basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/pipe_port.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines