Mercurial > hg > octave-nkf
diff liboctave/oct-syscalls.cc @ 6321:363a2f8c9e97
[project @ 2007-02-16 20:26:23 by dbateman]
author | dbateman |
---|---|
date | Fri, 16 Feb 2007 20:27:46 +0000 |
parents | 8d285942fc3c |
children | 7e958a1532c6 |
line wrap: on
line diff
--- a/liboctave/oct-syscalls.cc +++ b/liboctave/oct-syscalls.cc @@ -47,6 +47,7 @@ #include <signal.h> #include "lo-utils.h" +#include "lo-sysdep.h" #include "oct-syscalls.h" #include "str-vec.h" @@ -356,6 +357,100 @@ return status; } +pid_t +octave_syscalls::popen2 (const std::string& cmd, const string_vector& args, + bool sync_mode, int *fildes) +{ + std::string msg; + bool interactive = false; + return popen2 (cmd, args, sync_mode, fildes, msg, interactive); +} + +pid_t +octave_syscalls::popen2 (const std::string& cmd, const string_vector& args, + bool sync_mode, int *fildes, std::string& msg) +{ + bool interactive = false; + return popen2 (cmd, args, sync_mode, fildes, msg, interactive); +} + +pid_t +octave_syscalls::popen2 (const std::string& cmd, const string_vector& args, + bool sync_mode, int *fildes, std::string& msg, bool &interactive) +{ +#if defined (__WIN32__) && ! defined (__CYGWIN__) + return ::octave_popen2 (cmd, args, sync_mode, fildes, msg); +#else + pid_t pid; + int child_stdin[2], child_stdout[2]; + + if (pipe (child_stdin, msg) == 0) + { + if (pipe (child_stdout, msg) == 0) + { + pid = fork (msg); + if (pid < 0) + msg = "popen2: process creation failed -- " + msg; + else if (pid == 0) + { + std::string child_msg; + + interactive = false; + + // Child process + ::close (child_stdin[1]); + ::close (child_stdout[0]); + + if (dup2 (child_stdin[0], STDIN_FILENO) >= 0) + { + ::close (child_stdin[0]); + if (dup2 (child_stdout[1], STDOUT_FILENO) >= 0) + { + ::close (child_stdout[1]); + if (execvp (cmd, args, child_msg) < 0) + child_msg = "popen2 (child): unable to start process -- " + child_msg; + } + else + child_msg = "popen2 (child): file handle duplication failed -- " + child_msg; + } + else + child_msg = "popen2 (child): file handle duplication failed -- " + child_msg; + + (*current_liboctave_error_handler)(child_msg.c_str()); + + exit(0); + } + else + { + // Parent process + ::close (child_stdin[0]); + ::close (child_stdout[1]); +#if defined (F_SETFL) && defined (O_NONBLOCK) + if (! sync_mode && fcntl (child_stdout[0], F_SETFL, O_NONBLOCK, msg) < 0) + msg = "popen2: error setting file mode -- " + msg; + else +#endif + { + fildes[0] = child_stdin [1]; + fildes[1] = child_stdout [0]; + return pid; + } + } + ::close (child_stdout[0]); + ::close (child_stdout[1]); + } + else + msg = "popen2: pipe creation failed -- " + msg; + ::close (child_stdin[0]); + ::close (child_stdin[1]); + } + else + msg = "popen2: pipe creation failed -- " + msg; + + return -1; +#endif +} + /* ;;; Local Variables: *** ;;; mode: C++ ***