libassa 3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // $Id: Pipe.cpp,v 1.5 2006/07/20 02:30:54 vlg Exp $ 00004 //------------------------------------------------------------------------------ 00005 // Pipe.cpp 00006 //------------------------------------------------------------------------------ 00007 // Copyright (c) 1997-2002,2005 by Vladislav Grinchenko 00008 // 00009 // This library is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Library General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2 of the License, or (at your option) any later version. 00013 //------------------------------------------------------------------------------ 00014 // 00015 // Pipe class is based on ./unixsysdevel-734/homework3/src/bin/pipe/pipe.c 00016 // code I wrote for UNIX system development class of JohnsHopking 00017 // part time engineering school in November 1997. 00018 // The class implementation is a rip off of Stevens' popen ()/ pclose() 00019 // function, p. 438. 00020 // 00021 //------------------------------------------------------------------------------ 00022 00023 #include <errno.h> 00024 #include <sys/types.h> // kill (2) 00025 #include <signal.h> // kill (2) 00026 #include <unistd.h> // pipe (2) 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 /* no-op */ 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 { // 'w' 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 /* parent */ 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 { // 'w' 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