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 (type_ != "r" && type_ != "w") {
00056 EL((ERROR,"Wrong type \"%s\"\n", type_.c_str ()));
00057 errno = EINVAL;
00058 return NULL;
00059 }
00060
00061 int fd [2];
00062 if (pipe (fd) < 0) {
00063 EL((ERROR,"failed: pipe(2)\n"));
00064 return NULL;
00065 }
00066 Fork f (Fork::KILL_ON_EXIT, Fork::IGNORE_STATUS);
00067
00068 if (f.isChild ()) {
00069 if (type_ == "r") {
00070 ::close (fd [0]);
00071 if (fd [1] != STDOUT_FILENO) {
00072 dup2 (fd [1], STDOUT_FILENO);
00073 ::close (fd [1]);
00074 }
00075 }
00076 else {
00077 ::close (fd [1]);
00078 if (fd [0] != STDIN_FILENO) {
00079 dup2 (fd [0], STDIN_FILENO);
00080 ::close (fd [0]);
00081 }
00082 }
00083
00084 DL((PIPE,"Executing cmd: \"%s\"\n", cmd_.c_str ()));
00085 execl ("/bin/sh", "sh", "-c", cmd_.c_str (), (char* ) 0);
00086 EL((ERROR,"failed: execl(2)\n"));
00087 _exit (127);
00088 }
00089
00090 if (type_ == "r") {
00091 ::close (fd [1]);
00092 if ((m_fp = fdopen (fd [0], type_.c_str ())) == NULL) {
00093 EL((ERROR,"failed: fdopen ()\n"));
00094 return NULL;
00095 }
00096 }
00097 else {
00098 ::close (fd [0]);
00099 if ((m_fp = fdopen (fd [1], type_.c_str ())) == NULL) {
00100 EL((ERROR,"failed: fdopen ()\n"));
00101 return NULL;
00102 }
00103 }
00104 m_child_pid = f.getChildPID ();
00105 DL((PIPE,"m_child_pid = %d\n",m_child_pid));
00106 return m_fp;
00107 }
00108
00109 int
00110 Pipe::
00111 kill ()
00112 {
00113 trace_with_mask("Pipe::kill", PIPE);
00114
00115 if (m_child_pid == 0) return -1;
00116
00117 int ret = ::kill (m_child_pid, SIGTERM);
00118 close ();
00119 return ret;
00120 }
00121
00122 int
00123 Pipe::
00124 close ()
00125 {
00126 trace_with_mask("Pipe::close", PIPE);
00127
00128 int ret = 0;
00129 if (m_child_pid == 0) {
00130 ret = EOF;
00131 }
00132
00133 if (m_fp) {
00134 ret = fclose (m_fp);
00135 }
00136 m_fp = NULL;
00137 m_child_pid = 0;
00138 return ret == EOF ? -1 : 0;
00139 }
00140
00141
00142