basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : pipe_port.cpp 00004 * DESCRIPTION: Ports for pipes 00005 * COPYRIGHT : (C) 2010 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #include <basix/posix_port.hpp> 00014 #include <basix/system.hpp> 00015 #include <string.h> 00016 #include <unistd.h> 00017 #include <signal.h> 00018 #include <sys/wait.h> 00019 00020 #define STDIN 0 00021 #define STDOUT 1 00022 #define STDERR 2 00023 #define IN 0 00024 #define OUT 1 00025 #define TERMCHAR '\1' 00026 00027 extern char **environ; 00028 00030 00031 namespace mmx { 00032 00033 /****************************************************************************** 00034 * Pipe ports 00035 ******************************************************************************/ 00036 00037 class pipe_port_rep: public posix_port_rep { 00038 string cmd; 00039 string role; 00040 nat pid; 00041 00042 public: 00043 syntactic expression () const { 00044 return syn ("pipe_port", syntactic (cmd), syntactic (role)); 00045 } 00046 00047 public: 00048 inline pipe_port_rep (nat kind, nat fd, nat pid2, 00049 const string& cmd2, const string& role2): 00050 posix_port_rep (kind, fd), 00051 cmd (cmd2), role (role2), pid (pid2) {} 00052 inline ~pipe_port_rep () { 00053 close (this->fd); } 00054 }; 00055 00056 port 00057 pipe_port (nat kind, nat fd, nat pid, const string& cmd, const string& role) { 00058 return (port_rep*) new pipe_port_rep (kind, fd, pid, cmd, role); 00059 } 00060 00061 /****************************************************************************** 00062 * Starting a pipe port and public interface 00063 ******************************************************************************/ 00064 00065 port 00066 pipe_port (const string& cmd) { 00067 int pp_in [2]; // for data going to the child 00068 int pp_out[2]; // for data coming from the child 00069 int pp_err[2]; // for error messages coming from the child 00070 00071 int e1 = pipe (pp_in ); (void) e1; 00072 int e2 = pipe (pp_out); (void) e2; 00073 int e3 = pipe (pp_err); (void) e3; 00074 int pid= fork (); 00075 00076 if (pid==0) { // the child 00077 setsid(); 00078 close (pp_in [OUT]); 00079 close (pp_out [IN ]); 00080 close (pp_err [IN ]); 00081 dup2 (pp_in [IN ], STDIN ); 00082 close (pp_in [IN ]); 00083 dup2 (pp_out [OUT], STDOUT); 00084 close (pp_out [OUT]); 00085 dup2 (pp_err [OUT], STDERR); 00086 close (pp_err [OUT]); 00087 00088 system (cmd); 00089 exit (127); 00090 // exit (system (cmd) != 0); 00091 } 00092 00093 else { // the main process 00094 int in = pp_in [OUT]; 00095 close (pp_in [IN]); 00096 int out= pp_out [IN ]; 00097 close (pp_out [OUT]); 00098 int err= pp_err [IN ]; 00099 close (pp_err [OUT]); 00100 00101 port pin = pipe_port (1, in , pid, cmd, "in" ); 00102 port pout= pipe_port (2, out, pid, cmd, "out"); 00103 port perr= pipe_port (2, err, pid, cmd, "err"); 00104 return composite_port (vec<port> (pin, pout, perr), 00105 vec<string> ("in", "out", "err")); 00106 } 00107 } 00108 00109 } // namespace mmx