1. Help with pipe io
- Posted by jbrown1050 at yahoo.com Mar 28, 2002
- 380 views
--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--
2. Re: Help with pipe io
- Posted by Robert Craig <rds at RapidEuphoria.com> Mar 28, 2002
- 408 views
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
3. Re: Help with pipe io
- Posted by jbrown1050 at yahoo.com Mar 28, 2002
- 365 views
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.) --