00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
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 #if !(defined(__MINGW__) || defined(__MINGW32__))
00019 #  include <sys/wait.h>
00020 #endif
00021 
00022 #define STDIN 0
00023 #define STDOUT 1
00024 #define STDERR 2
00025 #define IN 0
00026 #define OUT 1
00027 #define TERMCHAR '\1'
00028 
00029 extern char **environ;
00030 
00032 
00033 namespace mmx {
00034 
00035 
00036 
00037 
00038 
00039 class pipe_port_rep: public posix_port_rep {
00040   string cmd;
00041   string role;
00042   nat    pid;
00043 
00044 public:
00045   syntactic expression () const {
00046     return syn ("pipe_port", syntactic (cmd), syntactic (role));
00047   }
00048 
00049 public:
00050   inline pipe_port_rep (nat kind, nat fd, nat pid2,
00051                         const string& cmd2, const string& role2):
00052     posix_port_rep (kind, fd),
00053     cmd (cmd2), role (role2), pid (pid2) {}
00054   inline ~pipe_port_rep () {
00055     close (this->fd); }
00056 };
00057 
00058 port
00059 pipe_port (nat kind, nat fd, nat pid, const string& cmd, const string& role) {
00060   return (port_rep*) new pipe_port_rep (kind, fd, pid, cmd, role);
00061 }
00062 
00063 
00064 
00065 
00066 
00067 port
00068 pipe_port (const string& cmd) {
00069 #if defined(__MINGW__) || defined(__MINGW32__)
00070   mmerr << "pipe_port not implemented" << lf;
00071   exit (-1);
00072 #else
00073   int pp_in [2];  
00074   int pp_out[2];  
00075   int pp_err[2];  
00076 
00077   int e1 = pipe (pp_in ); (void) e1;
00078   int e2 = pipe (pp_out); (void) e2;
00079   int e3 = pipe (pp_err); (void) e3;
00080   int pid= fork ();
00081 
00082   if (pid==0) { 
00083     setsid();
00084     close (pp_in  [OUT]);
00085     close (pp_out [IN ]);
00086     close (pp_err [IN ]);
00087     dup2  (pp_in  [IN ], STDIN );
00088     close (pp_in  [IN ]);
00089     dup2  (pp_out [OUT], STDOUT);
00090     close (pp_out [OUT]);
00091     dup2  (pp_err [OUT], STDERR);
00092     close (pp_err [OUT]);
00093 
00094     system (cmd);
00095     exit (127);
00096     
00097   }
00098 
00099   else { 
00100     int in = pp_in  [OUT];
00101     close (pp_in [IN]);
00102     int out= pp_out [IN ];
00103     close (pp_out [OUT]);
00104     int err= pp_err [IN ];
00105     close (pp_err [OUT]);
00106 
00107     port pin = pipe_port (1, in , pid, cmd, "in" );
00108     port pout= pipe_port (2, out, pid, cmd, "out");
00109     port perr= pipe_port (2, err, pid, cmd, "err");
00110     return composite_port (vec<port> (pin, pout, perr),
00111                            vec<string> ("in", "out", "err"));
00112   }
00113 #endif
00114 }
00115 
00116 }