# HG changeset patch # User jwe # Date 830406567 0 # Node ID 679d7262a525a95c971d315b58bdb083f397f764 # Parent 7eeaad95315cd4fb86f0e735f1bcdaad70a76fd3 [project @ 1996-04-25 04:29:27 by jwe] diff -r 7eeaad95315c -r 679d7262a525 src/toplev.cc --- a/src/toplev.cc Thu Apr 25 03:20:56 1996 +0000 +++ b/src/toplev.cc Thu Apr 25 04:29:27 1996 +0000 @@ -613,71 +613,132 @@ delete (iprocstream *) p; } +static Octave_object +do_system (const string& cmd_str, bool return_output) +{ + Octave_object retval; + + iprocstream *cmd = new iprocstream (cmd_str.c_str ()); + + add_unwind_protect (cleanup_iprocstream, cmd); + + int status = 127; + + if (cmd && *cmd) + { + ostrstream output_buf; + + char ch; + while (cmd->get (ch)) + output_buf.put (ch); + + output_buf << ends; + + status = cmd->close (); + + // The value in status is as returned by waitpid. If the + // process exited normally, extract the actual exit status of + // the command. Otherwise, return 127 as a failure code. + + if ((status & 0xff) == 0) + status = (status & 0xff00) >> 8; + + if (return_output) + { + char *msg = output_buf.str (); + + retval(1) = (double) status; + retval(0) = msg; + + delete [] msg; + } + else + maybe_page_output (output_buf); + } + else + error ("unable to start subprocess for `%s'", cmd_str.c_str ()); + + run_unwind_protect (); + + return retval; +} + DEFUN (system, args, nargout, - "system (string [, return_output]): execute shell commands") + "system (STRING [, RETURN_OUTPUT] [, TYPE])\n\ +\n\ +Execute the shell command specified by STRING.\n\ +\n\ +If TYPE is \"async\", the process is started in the background and the\n\ +pid of the child proces is returned immediately. Otherwise, the\n\ +process is started, and Octave waits until it exits. If TYPE argument\n\ +is omitted, a value of \"sync\" is assumed.\n\ +\n\ +If NARGIN == 2 (the actual value of RETURN_OUTPUT is irrelevant) and\n\ +the subprocess is started synchronously, or if system() is called with\n\ +NARGIN == 1 and NARGOUT > 0, the output from the command is returned.\n\ +Otherwise, if the subprocess is executed synchronously, it's output is\n\ +sent to Octave's standard output (possibly being passed through the\n\ +pager).") { Octave_object retval; int nargin = args.length (); - if (nargin < 1 || nargin > 2) + if (nargin > 0 && nargin < 4) { - print_usage ("system"); - return retval; - } + bool return_output = (nargout > 0 || nargin > 1); + + string cmd_str = args(0).string_value (); + + enum exec_type { sync, async }; + + exec_type type = sync; + + if (! error_state) + { + if (nargin > 2) + { + string type_str = args(2).string_value (); - tree_constant tc_command = args(0); - - string tmp = tc_command.string_value (); + if (! error_state) + { + if (type_str == "sync") + type = sync; + else if (type_str == "async") + type = async; + else + error ("system: third arg must be \"sync\" or \"async\""); + } + else + error ("system: third argument must be a string"); + } + } + else + error ("system: expecting string as first argument"); - if (error_state) - { - error ("system: expecting string as first argument"); + if (! error_state) + { + if (type == async) + { + pid_t pid = fork (); + + if (pid < 0) + error ("system: fork failed -- can't create child process"); + else if (pid == 0) + { + system (cmd_str.c_str ()); + exit (0); + retval(0) = 0.0; + } + else + retval(0) = (double) pid; + } + else + retval = do_system (cmd_str, return_output); + } } else - { - iprocstream *cmd = new iprocstream (tmp.c_str ()); - - add_unwind_protect (cleanup_iprocstream, cmd); - - int status = 127; - - if (cmd && *cmd) - { - ostrstream output_buf; - - char ch; - while (cmd->get (ch)) - output_buf.put (ch); - - output_buf << ends; - - status = cmd->close (); - - // The value in status is as returned by waitpid. If the - // process exited normally, extract the actual exit status of - // the command. Otherwise, return 127 as a failure code. - - if ((status & 0xff) == 0) - status = (status & 0xff00) >> 8; - - if (nargout > 0 || nargin > 1) - { - char *msg = output_buf.str (); - - retval(1) = (double) status; - retval(0) = msg; - - delete [] msg; - } - else - maybe_page_output (output_buf); - } - else - error ("unable to start subprocess for `%s'", tmp.c_str ()); - - run_unwind_protect (); - } + print_usage ("system"); return retval; }