Re: Pipe Input/Output
- Posted by jimcbrown (admin) Apr 05, 2014
- 1954 views
I'm looking at http://openeuphoria.org/docs/std_pipeio.html. Does this library mean I can start processes and communicate with them?
Yes, that's the whole point of the library. It's a platform-independent way of launching and communicating with processes.
It isn't very clear what this library can do, and there have been tickets open on this library since 2010. I want to use this library, but how does it work?
Take a look at pipes.ex/pipe_sub.ex in demos for an example.
Basically, you create a pipe with pipeio:create(), then you launch the process with pipeio:exec("command line here", thepipeyoumade).
Then, you write to the new process's standard input and read from its standard output. (This can be a little confusing, but the constants are defined from the child process's point of view. So since the child process has to read from its stadard input and write to its standard output, someone else has to write data into the child process's standard input and presumably is also reading the data written into the child process's standard output.)
So,
childsSTDIN = thepipeyoumade[STDIN] integer b = pipeio:write(childsSTDIN, "some data") childsSTDOUT = thepipeyoumade[STDOUT] integer n = pipeio:read(childsSTDOUT, number_of_bytes_to_read)
When you are done, clean up by doing pipeio:kill(thepipeyoumade) (maybe this should have been better named close_process() or cleanup() or something, but kill matches the API call name that is used internally).
From the process side (if it's an Euphoria process), simply read your data as normal from stdin (gets(0) or getc(0), etc) and write your data to stdout (puts(1, "data", etc) and you're done.
One annoying thing about pipeio is that if data isn't ready, it makes you wait instead of just saying "0 bytes read" or something. On *nix, here's how to fix that.
include std/pipeio.e object thepipeyoumade = pipeio:create() thepipeyoumade = pipeio:exec("command line here", thepipeyoumade) include std/dll.e object STDLIB = dll:open_dll({ "libc.so", "libc.dylib", "" }) object FNCTL = dll:define_c_func(STDLIB, "fnctl", {dll:C_INT, dll:C_INT, dll:C_INT}, dll:C_INT) object O_NONBLOCK = 2048, O_ASYNC = 8192, F_SETFL = 4 c_func(FNCTL, {thepipeyoumade[STDIN], F_SETFL, or_bits(O_NONBLOCK, O_ASYNC)}) c_func(FNCTL, {thepipeyoumade[STDOUT], F_SETFL, or_bits(O_NONBLOCK, O_ASYNC)}) c_func(FNCTL, {thepipeyoumade[STDERR], F_SETFL, or_bits(O_NONBLOCK, O_ASYNC)}) childsSTDIN = thepipeyoumade[STDIN] integer b = pipeio:write(childsSTDIN, "some data") childsSTDOUT = thepipeyoumade[STDOUT] integer n = pipeio:read(childsSTDOUT, number_of_bytes_to_read) pipeio:kill(thepipeyoumade)