CMS 3D CMS Logo

lat::SubProcess Class Reference

A subprocess. More...

#include <Iguana/Utilities/classlib/iobase/SubProcess.h>

List of all members.

Public Types

enum  Flags {
  Read = 1, Write = 2, First = 4, Last = 8,
  One = First | Last, Synchronous = 16, Search = 32, NoCloseInput = 64,
  NoCloseOutput = 128
}

Public Member Functions

virtual void detach (void)
virtual bool done (void)
virtual IOChannelinput (void) const
virtual IOChanneloutput (void) const
virtual pid_t pid (void) const
virtual Pipepipe (void) const
virtual pid_t run (const char **argz, unsigned flags, IOChannel *input, IOChannel *output=0)
virtual pid_t run (const char **argz, unsigned flags, SubProcess *input, IOChannel *output=0)
virtual pid_t run (const char **argz, unsigned flags, Pipe *pipe, IOChannel *other=0)
virtual pid_t run (const char **argz, unsigned flags=One)
 SubProcess (const char **argz, unsigned flags, IOChannel *input, IOChannel *output=0)
 SubProcess (const char **argz, unsigned flags, SubProcess *input, IOChannel *output=0)
 SubProcess (const char **argz, unsigned flags, Pipe *pipe, IOChannel *other=0)
 SubProcess (const char **argz, unsigned flags=One)
 SubProcess (void)
virtual void terminate (void)
virtual int wait (void)
virtual ~SubProcess (void)

Static Public Member Functions

static bool exitBySignal (int waitcode)
static bool exitNormal (int waitcode)
static int exitSignal (int waitcode)
static int exitStatus (int waitcode)

Private Member Functions

pid_t dorun (const char **argz, unsigned flags, IOChannel *input, IOChannel *output, IOChannel *cleanup)
SubProcessoperator= (const SubProcess &x)
 SubProcess (const SubProcess &x)
void sysdetach (void)
pid_t sysrun (const char **argz, unsigned flags, IOChannel *input, IOChannel *output, IOChannel *cleanup)

Private Attributes

IOChannelm_input
IOChannelm_output
Pipem_pipe
int m_status
pid_t m_sub


Detailed Description

A subprocess.

This class provides a convenient interface for running commands in subprocesses with possibly redirected input and output. One can run either simple subcommands, or entire subprocess pipelines. The entire pipeline (henceforth "subprocess chain") can have its input or output redirected to or from a pipe, or any IOChannel (e.g. a temporary file).

The command to run is specified as an argz vector: a list of C strings with a null pointer to terminate the list, identical to the program's argv list. The first element of argz is the name of the command to execute, the subsequent elements are the arguments to it. All the information in argz is always passed without modification or interpretation to the child process. By default the command name specifies the pathname of the file to be executed. Using Search changes this so that if the command does not include a path separator (slash (/) on unixen), the method duplicates the actions of shell in searching for an executable file in the directories listed in the $PATH shell environment variable.

Argz provides a way to build argz lists dynamically. It also provides utilties for converting between argz lists and strings to parse. One can force shell to parse of arguments by executing the platform equivalent of argz = { "/bin/sh", "-c", command }. This is not portable and more importantly, ridden with all kinds of security risks if the contents of "command" are not strictly controlled to be only safe characters.

By default the subprocesses execute concurrently with the parent process. Use wait() to suspend the parent until the child exits and to find out its exit status. If the Synchronous is used when creating the subprocess, a wait() is executed immediately before the method returns.

To construct a subprocess chain, construct multiple SubProcess objects and chain them together. The First and Last flags must be used by the client to indicate which portion of the chain is being constructed. In addition, the Read flag may be used when constructing the last child to indicate that this will be the end of the chain and the parent expects to read from it. The Write flag may be used at the beginning of the chain to indicate that the parent expects to write to the chain (the caller must provide the Pipe for this). If there are more than one process in the chain, intermediate pipes are automatically created; when the next subprocess is created, it attaches itself to the other end of the pipe.

The different flags combinations overlap. The purpose is to help clients express their needs in the most convenient terms. To avoid confusion in more complicated subprocess chain constructions it is simplest to think about each SubProcess as an individual redirection candidate. All subprocesses can have their input or output redirected from or to a pipe; for the first process in the chain input redirection from a pipe implies Write, for the last output redirection to a pipe implies Read, and for all but last output redirection means another subprocess will attach to the pipe. The implementation does not distinguish the pipe output redirections situations in any way, so different argument and call combinations can produce exactly the same result. The first and last processes may also have their input and output, respectively, redirected to a IOChannel, or inherit the parent's standard input or output. These are treated differently only in that the pipes are automatically closed in the parent once used in a child whereas bare IOChannel objects are not.

Attempting to simultanously both write to and read from a process causes deadlocks and therefore flags is not allowed to contain both Read and Write. Instead, if you read from the chain, redirect its input from a temporary file, or if you write to it, redirect its output to one; see TempFile::file() for a way to create temporary files. The deadlocks arise because pipes can buffer only a limited amount of data: once the buffer is full the caller will block until someone reads data off the other end. Indiscrete use of pipes to simultaneously read and write results in a deadlock where writes in both processes are blocked waiting on the other to read -- which neither is able to as they are blocked in their own write. It does not matter how many pipes are used, nor in fact whether subprocesses are involved: as long as the communication channel has limited buffering capacity and it blocks the writer when the buffer becomes full, the processes will deadlock sooner or later. The only workaround is to use non-blocking pipes and to explicitly buffer data at each end.

(FIXME: envz? close descriptors, clean up safe env?)

Definition at line 106 of file SubProcess.h.


Member Enumeration Documentation

enum lat::SubProcess::Flags

Enumerator:
Read 
Write 
First 
Last 
One 
Synchronous 
Search 
NoCloseInput 
NoCloseOutput 

Definition at line 116 of file SubProcess.h.

00116                {
00117         Read            = 1,            //< Make a read subprocess chain
00118         Write           = 2,            //< Make a write subprocess chain
00119         First           = 4,            //< First subprocess in a chain
00120         Last            = 8,            //< Last subprocess in a chain
00121         One             = First | Last, //< Single-subprocess chain
00122         Synchronous     = 16,           //< Run synchronously
00123         Search          = 32,           //< Search path for command
00124         NoCloseInput    = 64,           //< Don't close input pipe in parent
00125         NoCloseOutput   = 128           //< Don't close output pipe in parent
00126         // CleanEnv     = 256           //< Clean up safe environment
00127         // CloseFds     = 512           //< Close all "other" file descriptors
00128     };


Constructor & Destructor Documentation

lat::SubProcess::SubProcess ( void   ) 

lat::SubProcess::SubProcess ( const char **  argz,
unsigned  flags = One 
)

lat::SubProcess::SubProcess ( const char **  argz,
unsigned  flags,
Pipe pipe,
IOChannel other = 0 
)

lat::SubProcess::SubProcess ( const char **  argz,
unsigned  flags,
SubProcess input,
IOChannel output = 0 
)

lat::SubProcess::SubProcess ( const char **  argz,
unsigned  flags,
IOChannel input,
IOChannel output = 0 
)

virtual lat::SubProcess::~SubProcess ( void   )  [virtual]

lat::SubProcess::SubProcess ( const SubProcess x  )  [private]


Member Function Documentation

virtual void lat::SubProcess::detach ( void   )  [virtual]

virtual bool lat::SubProcess::done ( void   )  [virtual]

pid_t lat::SubProcess::dorun ( const char **  argz,
unsigned  flags,
IOChannel input,
IOChannel output,
IOChannel cleanup 
) [private]

static bool lat::SubProcess::exitBySignal ( int  waitcode  )  [static]

static bool lat::SubProcess::exitNormal ( int  waitcode  )  [static]

static int lat::SubProcess::exitSignal ( int  waitcode  )  [static]

static int lat::SubProcess::exitStatus ( int  waitcode  )  [static]

virtual IOChannel* lat::SubProcess::input ( void   )  const [virtual]

SubProcess& lat::SubProcess::operator= ( const SubProcess x  )  [private]

virtual IOChannel* lat::SubProcess::output ( void   )  const [virtual]

virtual pid_t lat::SubProcess::pid ( void   )  const [virtual]

virtual Pipe* lat::SubProcess::pipe ( void   )  const [virtual]

virtual pid_t lat::SubProcess::run ( const char **  argz,
unsigned  flags,
IOChannel input,
IOChannel output = 0 
) [virtual]

virtual pid_t lat::SubProcess::run ( const char **  argz,
unsigned  flags,
SubProcess input,
IOChannel output = 0 
) [virtual]

virtual pid_t lat::SubProcess::run ( const char **  argz,
unsigned  flags,
Pipe pipe,
IOChannel other = 0 
) [virtual]

virtual pid_t lat::SubProcess::run ( const char **  argz,
unsigned  flags = One 
) [virtual]

Referenced by IgServerPool::createProcess().

void lat::SubProcess::sysdetach ( void   )  [private]

pid_t lat::SubProcess::sysrun ( const char **  argz,
unsigned  flags,
IOChannel input,
IOChannel output,
IOChannel cleanup 
) [private]

virtual void lat::SubProcess::terminate ( void   )  [virtual]

virtual int lat::SubProcess::wait ( void   )  [virtual]


Member Data Documentation

IOChannel* lat::SubProcess::m_input [private]

Definition at line 173 of file SubProcess.h.

IOChannel* lat::SubProcess::m_output [private]

Definition at line 174 of file SubProcess.h.

Pipe* lat::SubProcess::m_pipe [private]

Definition at line 175 of file SubProcess.h.

int lat::SubProcess::m_status [private]

Definition at line 172 of file SubProcess.h.

pid_t lat::SubProcess::m_sub [private]

Definition at line 180 of file SubProcess.h.


The documentation for this class was generated from the following file:
Generated on Tue Jun 9 18:48:36 2009 for CMSSW by  doxygen 1.5.4