/* * call-seq: * IO.pipe -> array * * Creates a pair of pipe endpoints (connected to each other) and * returns them as a two-element array of <code>IO</code> objects: * <code>[</code> <i>read_file</i>, <i>write_file</i> <code>]</code>. Not * available on all platforms. * * In the example below, the two processes close the ends of the pipe * that they are not using. This is not just a cosmetic nicety. The * read end of a pipe will not generate an end of file condition if * there are any writers with the pipe still open. In the case of the * parent process, the <code>rd.read</code> will never return if it * does not first issue a <code>wr.close</code>. * * rd, wr = IO.pipe * * if fork * wr.close * puts "Parent got: <#{rd.read}>" * rd.close * Process.wait * else * rd.close * puts "Sending message to parent" * wr.write "Hi Dad" * wr.close * end * * <em>produces:</em> * * Sending message to parent * Parent got: <Hi Dad> */ static VALUE rb_io_s_pipe(klass) VALUE klass; { #ifndef __human68k__ int pipes[2], state; VALUE r, w, args[3]; #ifdef _WIN32 if (_pipe(pipes, 1024, O_BINARY) == -1) #else if (pipe(pipes) == -1) #endif rb_sys_fail(0); args[0] = klass; args[1] = INT2NUM(pipes[0]); args[2] = INT2FIX(O_RDONLY); r = rb_protect(io_new_instance, (VALUE)args, &state); if (state) { close(pipes[0]); close(pipes[1]); rb_jump_tag(state); } args[1] = INT2NUM(pipes[1]); args[2] = INT2FIX(O_WRONLY); w = rb_protect(io_new_instance, (VALUE)args, &state); if (state) { close(pipes[1]); if (!NIL_P(r)) rb_io_close(r); rb_jump_tag(state); } rb_io_synchronized(RFILE(w)->fptr); return rb_assoc_new(r, w); #else rb_notimplement(); return Qnil; /* not reached */ #endif }