/*
 *  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);
}