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