/home/vlg/develop/libASSA/libassa/assa/Pipe.cpp

Go to the documentation of this file.
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 

Generated on Sun Aug 13 15:08:00 2006 for libassa by  doxygen 1.4.6