/*
* call-seq:
* open(path [, mode [, perm]] ) => io or nil
* open(path [, mode [, perm]] ) {|io| block } => obj
*
* Creates an <code>IO</code> object connected to the given stream,
* file, or subprocess.
*
* If <i>path</i> does not start with a pipe character
* (``<code>|</code>''), treat it as the name of a file to open using
* the specified mode (defaulting to ``<code>r</code>''). (See the table
* of valid modes on page 331.) If a file is being created, its initial
* permissions may be set using the integer third parameter.
*
* If a block is specified, it will be invoked with the
* <code>File</code> object as a parameter, and the file will be
* automatically closed when the block terminates. The call
* returns the value of the block.
*
* If <i>path</i> starts with a pipe character, a subprocess is
* created, connected to the caller by a pair of pipes. The returned
* <code>IO</code> object may be used to write to the standard input
* and read from the standard output of this subprocess. If the command
* following the ``<code>|</code>'' is a single minus sign, Ruby forks,
* and this subprocess is connected to the parent. In the subprocess,
* the <code>open</code> call returns <code>nil</code>. If the command
* is not ``<code>-</code>'', the subprocess runs the command. If a
* block is associated with an <code>open("|-")</code> call, that block
* will be run twice---once in the parent and once in the child. The
* block parameter will be an <code>IO</code> object in the parent and
* <code>nil</code> in the child. The parent's <code>IO</code> object
* will be connected to the child's <code>$stdin</code> and
* <code>$stdout</code>. The subprocess will be terminated at the end
* of the block.
*
* open("testfile") do |f|
* print f.gets
* end
*
* <em>produces:</em>
*
* This is line one
*
* Open a subprocess and read its output:
*
* cmd = open("|date")
* print cmd.gets
* cmd.close
*
* <em>produces:</em>
*
* Wed Apr 9 08:56:31 CDT 2003
*
* Open a subprocess running the same Ruby program:
*
* f = open("|-", "w+")
* if f == nil
* puts "in Child"
* exit
* else
* puts "Got: #{f.gets}"
* end
*
* <em>produces:</em>
*
* Got: in Child
*
* Open a subprocess using a block to receive the I/O object:
*
* open("|-") do |f|
* if f == nil
* puts "in Child"
* else
* puts "Got: #{f.gets}"
* end
* end
*
* <em>produces:</em>
*
* Got: in Child
*/
static VALUE
rb_f_open(argc, argv)
int argc;
VALUE *argv;
{
if (argc >= 1) {
char *str = StringValuePtr(argv[0]);
if (str[0] == '|') {
VALUE tmp = rb_str_new(str+1, RSTRING(argv[0])->len-1);
OBJ_INFECT(tmp, argv[0]);
argv[0] = tmp;
return rb_io_s_popen(argc, argv, rb_cIO);
}
}
return rb_io_s_open(argc, argv, rb_cFile);
}