/* * call-seq: * IO.popen(cmd_string, mode="r" ) => io * IO.popen(cmd_string, mode="r" ) {|io| block } => obj * * Runs the specified command string as a subprocess; the subprocess's * standard input and output will be connected to the returned * <code>IO</code> object. If <i>cmd_string</i> starts with a * ``<code>-</code>'', then a new instance of Ruby is started as the * subprocess. The default mode for the new file object is ``r'', but * <i>mode</i> may be set to any of the modes listed in the description * for class IO. * * If a block is given, Ruby will run the command as a child connected * to Ruby with a pipe. Ruby's end of the pipe will be passed as a * parameter to the block. * At the end of block, Ruby close the pipe and sets <code>$?</code>. * In this case <code>IO::popen</code> returns * the value of the block. * * If a block is given with a <i>cmd_string</i> of ``<code>-</code>'', * the block will be run in two separate processes: once in the parent, * and once in a child. The parent process will be passed the pipe * object as a parameter to the block, the child version of the block * will be passed <code>nil</code>, and the child's standard in and * standard out will be connected to the parent through the pipe. Not * available on all platforms. * * f = IO.popen("uname") * p f.readlines * puts "Parent is #{Process.pid}" * IO.popen ("date") { |f| puts f.gets } * IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f}"} * p $? * * <em>produces:</em> * * ["Linux\n"] * Parent is 26166 * Wed Apr 9 08:53:52 CDT 2003 * 26169 is here, f is * 26166 is here, f is #<IO:0x401b3d44> * #<Process::Status: pid=26166,exited(0)> */ static VALUE rb_io_s_popen(argc, argv, klass) int argc; VALUE *argv; VALUE klass; { char *mode; VALUE pname, pmode, port; if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) { mode = "r"; } else if (FIXNUM_P(pmode)) { mode = rb_io_modenum_mode(FIX2INT(pmode)); } else { mode = rb_io_flags_mode(rb_io_mode_flags(StringValueCStr(pmode))); } SafeStringValue(pname); port = pipe_open(pname, 0, mode); if (NIL_P(port)) { /* child */ if (rb_block_given_p()) { rb_yield(Qnil); fflush(stdout); fflush(stderr); _exit(0); } return Qnil; } RBASIC(port)->klass = klass; if (rb_block_given_p()) { return rb_ensure(rb_yield, port, io_close, port); } return port; }