1. Help with pipe io

--fdj2RfSjLxBAspz7

I'm working on pipes for linux which are full duplex.
However, there is a bug,
as shown in demo1.exu - uncomment out the line which
opens "/bin/echo",
and you'll see that echo outputs a bunch of garbage
instead of "Hello World!"
Can anyone please explain why this happens and how to
fix it?

Thanks in advance.

-- 
"Is there peace in heaven, or is that merely an
illusion?" - Someone

"May peace find its way through the heavens to the
world of men and women
before the fires of the damned consume them." -
Someone

Linux User:190064
Linux Machine:84163



--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="cpipe.e"

include dll.e
include machine.e

constant STDLIB = open_dll("")
constant PIPE = define_c_func(STDLIB, "pipe",
{C_POINTER}, C_INT)
constant READ = define_c_func(STDLIB, "read", {C_INT,
C_POINTER, C_INT}, C_INT)
constant WRITE = define_c_func(STDLIB, "write",
{C_INT, C_POINTER, C_INT}, C_INT)
constant CLOSE = define_c_func(STDLIB, "close",
{C_INT}, C_INT)
constant DUP2 = define_c_func(STDLIB, "dup2", {C_INT,
C_INT}, C_INT)
constant KILL = define_c_func(STDLIB, "kill", {C_INT,
C_INT}, C_INT)
constant FORK = define_c_func(STDLIB, "fork", {},
C_INT)
constant EXECV = define_c_func(STDLIB, "execv",
{C_POINTER, C_POINTER}, C_INT)
constant SIGNAL = define_c_func(STDLIB, "signal",
{C_INT, C_POINTER}, C_POINTER)
constant ERRNO = define_c_var(STDLIB, "errno")

global constant os_stdin = 0
global constant os_stdout = 1
global constant os_stderr = 2
global constant os_sig_dfl = 0
global constant os_sig_ign = 1
global atom os_errno os_errno = 0
global object VOID VOID = {}

global function os_pipe()
    atom cmd, r, in, out
    cmd = allocate(8)
    r = c_func(PIPE,{cmd})
    if r = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    in = peek4u(cmd)
    out = peek4u(cmd+4)
    free(cmd)
    return {in, out}
end function

global function os_read(atom fd, integer bytes)
    atom buf, r
    sequence data
    buf = allocate(bytes)
    r = c_func(READ, {fd, buf, bytes})
    if r = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    if r = 0 then
	free(buf)
	return ""
    end if
    data = ""
    for i = 1 to r do
	data &= peek(buf+i-1)
    end for
    return data
end function

global function os_write(atom fd, sequence str)
    atom buf, r
    buf = allocate_string(str)
    r = c_func(WRITE, {fd, buf, length(str)})
    if r = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    return r
end function

global function os_close(atom fd)
    atom r
    r = c_func(CLOSE, {fd})
    if r = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    return 0
end function

global function os_dup2(atom oldfd, atom newfd)
    atom r
    r = c_func(DUP2, {oldfd, newfd})
    if r = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    return r
end function

global function os_kill(atom pid, atom signal)
    atom r
    r = c_func(KILL, {pid, signal})
    if r = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    return r
end function

global function os_fork()
    atom pid
    pid = c_func(FORK, {})
    if pid = -1 then
	os_errno = peek4u(ERRNO)
	return -1
    end if
    return pid
end function

global function os_execv(sequence s, sequence v)
    atom sbuf
    atom vbuf
    atom vbufstr
    atom r
    sbuf = allocate_string(s)
    vbuf = allocate((length(v)+1)*4)
    for i = 1 to length(v) do
	vbufstr = allocate_string(v[i])
	poke4(vbuf+((i-1)*4), vbufstr)
    end for
    poke4(vbuf+((length(v)+1)*4), 0)
    r = c_func(EXECV, {sbuf, vbuf}) -- execv() should
never return
    os_errno = peek4u(ERRNO)
    return r
end function

global function os_signal(integer signal, atom
handler)
    return c_func(SIGNAL, {signal, handler})
end function


--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pipeio.e"

include cpipe.e

procedure error()
    crash_message(sprintf("Errno = %d", os_errno))
    ? 1/0
end procedure

global function popen(sequence command, sequence args)
    atom pid
    sequence ipipe, opipe, epipe
    ipipe = {os_pipe()}
    opipe = {os_pipe()}
    epipe = {os_pipe()}
    if atom(ipipe[1]) then
	error()
    end if
    if atom(opipe[1]) then
	error()
    end if
    if atom(epipe[1]) then
	error()
    end if
    ipipe = ipipe[1]
    opipe = opipe[1]
    epipe = epipe[1]
    pid = os_fork()
    if pid = 0 then
	VOID = os_signal(15, os_sig_dfl) --15 = sigterm
	if os_dup2(ipipe[1], os_stdin) = -1 then
	    error()
	end if
	if os_dup2(opipe[2], os_stdout) = -1 then
	    error()
	end if
	if os_dup2(epipe[2], os_stderr) = -1 then
	    error()
	end if
	if os_execv(command, args) then
	    error()
	end if
    elsif pid = -1 then
	error()
    end if
    return {pid, ipipe[2], opipe[1], epipe[1]}
end function


--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="demo1.exu"

with trace
include pipeio.e

sequence data
--data = popen("/opt/euphoria/bin/exu",
{"subprocess1.exu"})
     -- eu programs dont work w/ pipes, so use echo to
test instead
--data = popen("/bin/echo", {"Hello World!"})
    -- interesting bug, some strange garbage is
printed instead of the message.
data = popen("/bin/arch", {})
    -- this seems to work fine
integer pid, pin, pout, perr
pid = data[1]
pin = data[2]
pout = data[3]
perr = data[4]
object c
c = os_read(pout, 256)
if atom(c) then
    printf(1, "Failed on read with error %x",
os_errno)
    abort(1)
end if
puts(1, c)
VOID = os_kill(pid, 15)
--pclose(pipe)


--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="demo2.exu"

with trace
include pipeio.e

sequence data
--data = popen("/opt/euphoria/bin/exu",
{"subprocess2.exu"})
     -- eu programs dont work w/ pipes, so use cat to
test instead
data = popen("/bin/cat", {})
integer pid, pin, pout, perr
pid = data[1]
pin = data[2]
pout = data[3]
perr = data[4]
object c
c = os_write(pin, "Hello, World!\n")
if c = -1 then
    printf(1, "Failed on write with error %x",
os_errno)
    abort(1)
end if
c = os_read(pout, 256)
if atom(c) then
    printf(1, "Failed on read with error %x",
os_errno)
    abort(1)
end if
puts(1, c)
VOID = os_kill(pid, 15)
--pclose(pipe)


--fdj2RfSjLxBAspz7--

new topic     » topic index » view message » categorize

2. Re: Help with pipe io

jbrown writes:
> you'll see that echo outputs a bunch of garbage
> instead of "Hello World!"

I'm not sure what your specific problem is,
but on Linux, ncurses has a bug that causes
stderr and stdout to be mixed together.
If stdout from your Euphoria Linux program is redirected
to a file, and your program also tries to print something
to the screen, you may find the screen output plus
a bunch of ncurses control characters mixed into the file.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

3. Re: Help with pipe io

On  0, Robert Craig <rds at RapidEuphoria.com> wrote:
> 
> jbrown writes:
> > you'll see that echo outputs a bunch of garbage
> > instead of "Hello World!"
> 
> I'm not sure what your specific problem is,
> but on Linux, ncurses has a bug that causes
> stderr and stdout to be mixed together.
> If stdout from your Euphoria Linux program is
redirected
> to a file, and your program also tries to print
something
> to the screen, you may find the screen output plus
> a bunch of ncurses control characters mixed into the
file.
> 
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    http://www.RapidEuphoria.com
> 

Thanks, but thats not my exact problem. I get garbage
when i call and redirect
any program which uses arguments. I think its a
problem with the way I'm
setting up the array.

BTW, What I'm trying to do is redirect stdin, stdout,
and stderr of a program
to pipes for interprocess communication, just in case
someone else has figured
this out already. (I know about filelib.e and
pipelib.e by the way, and
Jeffrey Fielding has done a very good job with them,
but I want full duplex,
not half-duplex, pipe io.)

--

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu