00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <errno.h>
00024 #include <sys/types.h>
00025 #include <signal.h>
00026 #include <unistd.h>
00027
00028 #include "assa/Pipe.h"
00029 #include "assa/Fork.h"
00030
00031 using namespace ASSA;
00032
00033 Pipe::
00034 Pipe ()
00035 : m_fp (NULL),
00036 m_child_pid (0)
00037 {
00038 trace_with_mask("Pipe::Pipe", PIPE);
00039
00040 }
00041
00042 Pipe::
00043 ~Pipe ()
00044 {
00045 trace_with_mask("Pipe::~Pipe", PIPE);
00046 close ();
00047 }
00048
00049 FILE*
00050 Pipe::
00051 open (const string& cmd_, const string& type_)
00052 {
00053 trace_with_mask("Pipe::open", PIPE);
00054
00055 #if !defined(WIN32) // not yet implemented
00056
00057 if (type_ != "r" && type_ != "w") {
00058 EL((ASSAERR,"Wrong type \"%s\"\n", type_.c_str ()));
00059 errno = EINVAL;
00060 return NULL;
00061 }
00062
00063 int fd [2];
00064 if (pipe (fd) < 0) {
00065 EL((ASSAERR,"failed: pipe(2)\n"));
00066 return NULL;
00067 }
00068 Fork f (Fork::KILL_ON_EXIT, Fork::IGNORE_STATUS);
00069
00070 if (f.isChild ()) {
00071 if (type_ == "r") {
00072 ::close (fd [0]);
00073 if (fd [1] != STDOUT_FILENO) {
00074 dup2 (fd [1], STDOUT_FILENO);
00075 ::close (fd [1]);
00076 }
00077 }
00078 else {
00079 ::close (fd [1]);
00080 if (fd [0] != STDIN_FILENO) {
00081 dup2 (fd [0], STDIN_FILENO);
00082 ::close (fd [0]);
00083 }
00084 }
00085
00086 DL((PIPE,"Executing cmd: \"%s\"\n", cmd_.c_str ()));
00087 execl ("/bin/sh", "sh", "-c", cmd_.c_str (), (char* ) 0);
00088 EL((ASSAERR,"failed: execl(2)\n"));
00089 _exit (127);
00090 }
00091
00092 if (type_ == "r") {
00093 ::close (fd [1]);
00094 if ((m_fp = fdopen (fd [0], type_.c_str ())) == NULL) {
00095 EL((ASSAERR,"failed: fdopen ()\n"));
00096 return NULL;
00097 }
00098 }
00099 else {
00100 ::close (fd [0]);
00101 if ((m_fp = fdopen (fd [1], type_.c_str ())) == NULL) {
00102 EL((ASSAERR,"failed: fdopen ()\n"));
00103 return NULL;
00104 }
00105 }
00106 m_child_pid = f.getChildPID ();
00107 DL((PIPE,"m_child_pid = %d\n",m_child_pid));
00108 return m_fp;
00109
00110 #else
00111 DL((ASSAERR|PIPE,"Not implemented for win32!\n"));
00112 return NULL;
00113 #endif
00114 }
00115
00116 int
00117 Pipe::
00118 kill ()
00119 {
00120 trace_with_mask("Pipe::kill", PIPE);
00121
00122 #if !defined(WIN32)
00123 if (m_child_pid == 0) return -1;
00124
00125 int ret = ::kill (m_child_pid, SIGTERM);
00126 close ();
00127 return ret;
00128 #else
00129 DL((ASSAERR|PIPE,"Not implemented for win32!\n"));
00130 return -1;
00131 #endif
00132 }
00133
00134 int
00135 Pipe::
00136 close ()
00137 {
00138 trace_with_mask("Pipe::close", PIPE);
00139
00140 int ret = 0;
00141 if (m_child_pid == 0) {
00142 ret = EOF;
00143 }
00144
00145 if (m_fp) {
00146 ret = fclose (m_fp);
00147 }
00148 m_fp = NULL;
00149 m_child_pid = 0;
00150 return ret == EOF ? -1 : 0;
00151 }
00152
00153
00154