Loading...
Searching...
No Matches
Pipe.cpp
Go to the documentation of this file.
// -*- c++ -*-
//------------------------------------------------------------------------------
// $Id: Pipe.cpp,v 1.5 2006/07/20 02:30:54 vlg Exp $
//------------------------------------------------------------------------------
// Pipe.cpp
//------------------------------------------------------------------------------
// Copyright (c) 1997-2002,2005 by Vladislav Grinchenko
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
//
// Pipe class is based on ./unixsysdevel-734/homework3/src/bin/pipe/pipe.c
// code I wrote for UNIX system development class of JohnsHopking
// part time engineering school in November 1997.
// The class implementation is a rip off of Stevens' popen ()/ pclose()
// function, p. 438.
//
//------------------------------------------------------------------------------
#include <errno.h>
#include <sys/types.h> // kill (2)
#include <signal.h> // kill (2)
#include <unistd.h> // pipe (2)
#include "assa/Pipe.h"
#include "assa/Fork.h"
using namespace ASSA;
Pipe::
Pipe ()
: m_fp (NULL),
m_child_pid (0)
{
trace_with_mask("Pipe::Pipe", PIPE);
/* no-op */
}
Pipe::
~Pipe ()
{
trace_with_mask("Pipe::~Pipe", PIPE);
close ();
}
FILE*
Pipe::
open (const string& cmd_, const string& type_)
{
trace_with_mask("Pipe::open", PIPE);
#if !defined(WIN32) // not yet implemented
if (type_ != "r" && type_ != "w") {
EL((ASSAERR,"Wrong type \"%s\"\n", type_.c_str ()));
errno = EINVAL;
return NULL;
}
int fd [2];
if (pipe (fd) < 0) {
EL((ASSAERR,"failed: pipe(2)\n"));
return NULL;
}
Fork f (Fork::KILL_ON_EXIT, Fork::IGNORE_STATUS);
if (f.isChild ()) {
if (type_ == "r") {
::close (fd [0]);
if (fd [1] != STDOUT_FILENO) {
dup2 (fd [1], STDOUT_FILENO);
::close (fd [1]);
}
}
else { // 'w'
::close (fd [1]);
if (fd [0] != STDIN_FILENO) {
dup2 (fd [0], STDIN_FILENO);
::close (fd [0]);
}
}
DL((PIPE,"Executing cmd: \"%s\"\n", cmd_.c_str ()));
execl ("/bin/sh", "sh", "-c", cmd_.c_str (), (char* ) 0);
EL((ASSAERR,"failed: execl(2)\n"));
_exit (127);
}
/* parent */
if (type_ == "r") {
::close (fd [1]);
if ((m_fp = fdopen (fd [0], type_.c_str ())) == NULL) {
EL((ASSAERR,"failed: fdopen ()\n"));
return NULL;
}
}
else { // 'w'
::close (fd [0]);
if ((m_fp = fdopen (fd [1], type_.c_str ())) == NULL) {
EL((ASSAERR,"failed: fdopen ()\n"));
return NULL;
}
}
m_child_pid = f.getChildPID ();
DL((PIPE,"m_child_pid = %d\n",m_child_pid));
return m_fp;
#else
DL((ASSAERR|PIPE,"Not implemented for win32!\n"));
return NULL;
#endif
}
int
Pipe::
kill ()
{
trace_with_mask("Pipe::kill", PIPE);
#if !defined(WIN32)
if (m_child_pid == 0) return -1;
int ret = ::kill (m_child_pid, SIGTERM);
close ();
return ret;
#else
DL((ASSAERR|PIPE,"Not implemented for win32!\n"));
return -1;
#endif
}
int
Pipe::
close ()
{
trace_with_mask("Pipe::close", PIPE);
int ret = 0;
if (m_child_pid == 0) {
ret = EOF;
}
if (m_fp) {
ret = fclose (m_fp);
}
m_fp = NULL;
m_child_pid = 0;
return ret == EOF ? -1 : 0;
}
Fork.h
A simple wrapper around fork() library function call.
EL
#define EL(X)
A macro for writing error message to the Logger.
Definition Logger.h:285
DL
#define DL(X)
A macro for writing debug message to the Logger.
Definition Logger.h:273
trace_with_mask
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition Logger.h:437
Pipe.h
A wrapper around UNIX popen()/pclose() standard library calls.
ASSA::Fork
Fork class is a simple wrapper around C library function fork().
Definition Fork.h:86
ASSA::Fork::KILL_ON_EXIT
@ KILL_ON_EXIT
Kill all childer on exit.
Definition Fork.h:92
ASSA::Fork::isChild
bool isChild() const
Test whether we are in child section of the code.
Definition Fork.h:136
ASSA::Fork::IGNORE_STATUS
@ IGNORE_STATUS
Don't wait for child to complete.
Definition Fork.h:100
ASSA::Fork::getChildPID
pid_t getChildPID() const
Retrieve child process id.
Definition Fork.h:142
ASSA::Pipe::m_child_pid
pid_t m_child_pid
Supbrocess' PID.
Definition Pipe.h:98
ASSA::Pipe::fd
int fd() const
Get pipe's file descriptor.
Definition Pipe.h:105
ASSA::Pipe::Pipe
Pipe()
A no-op constructor.
Definition Pipe.cpp:34
ASSA::Pipe::open
FILE * open(const string &cmd_, const string &type_)
Starts a subshell and feed it the string cmd_ to be executed.
Definition Pipe.cpp:51
ASSA::Pipe::m_fp
FILE * m_fp
A standard I/O stream descriptor.
Definition Pipe.h:93
ASSA::Pipe::kill
int kill()
Kill subprocess with SIGTERM.
Definition Pipe.cpp:118
ASSA::Pipe::~Pipe
~Pipe()
Destructor calls close () first in an attempt to close opened pipe.
Definition Pipe.cpp:43
ASSA::Pipe::close
int close()
Close the pipe.
Definition Pipe.cpp:136
ASSA
Definition Acceptor.h:40
ASSA::PIPE
@ PIPE
Class Pipe messages.
Definition LogMask.h:49
ASSA::ASSAERR
@ ASSAERR
ASSA and system errors.
Definition LogMask.h:34