Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvpipe.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Provides support for piping data to/from subprocesses.
00006  */ 
00007 #ifndef __WVPIPE_H
00008 #define __WVPIPE_H
00009 
00010 #include "wvfdstream.h"
00011 #include "wvsubproc.h"
00012 
00013 /**
00014  * Implementation of a WvPipe stream.  These allow you to create a new
00015  * process, attaching its stdin/stdout to a WvStream.
00016  * 
00017  * Unlike pipes created with the popen() system call, you can capture
00018  * both stdin and stdout for the given process.  This is because we
00019  * actually use the socketpair() call instead.  If you try this,
00020  * however, you must be very careful to always use the select() call
00021  * before reading from the stream.  (Think what would happen if both
00022  * ends of the pipe do a read() simultaneously!)
00023  * 
00024  * Note that we do not go as far as actually using a pty.  That means
00025  * programs which deliberately open /dev/tty will not be redirected.
00026  * 
00027  * When the WvPipe is destroyed, it makes sure that the child process
00028  * is killed.  Since it tries to do it politely (SIGTERM, wait up to
00029  * 2 seconds, SIGKILL) it can take up to 2 seconds to destroy a
00030  * WvPipe.
00031  */
00032 class WvPipe : public WvFDStream
00033 {
00034     WvSubProc proc;
00035 protected:
00036     void setup(const char *program, const char * const *argv,
00037                bool writable, bool readable, bool catch_stderr,
00038                int stdin_fd, int stdout_fd, int stderr_fd);
00039 public:
00040     /**
00041      * default pipe constructor; if you just want to use a pipe, use this.
00042      * For each of stdin, stdout, and stderr of the child process, it can
00043      * do one of three things:
00044      *    - leave it alone (ie. the same as for the parent process)
00045      *    - redirect it through the WvPipe (eg. if writable==true)
00046      *    - redirect it to any open file descriptor (std*_fd are only
00047      *       used if the corresponding bool is false, however)
00048      */
00049     WvPipe(const char *program, const char * const *argv,
00050            bool writable, bool readable, bool catch_stderr,
00051            int stdin_fd = 0, int stdout_fd = 1, int stderr_fd = 2);
00052     
00053     /**
00054      * This constructor does much the same thing as the previous one,
00055      * except that std*_str are WvStreams instead.  The target process
00056      * accesses the 'fd' member of the stream (NOT using
00057      * the WvStream read() and write() functions).
00058      *
00059      * Again, we only redirect to the given WvStreams if the corresponding
00060      * bool is false; otherwise, we redirect to the pipe.
00061      *
00062      * It is okay for the same WvStream to occur more than once.  Also,
00063      * you must naturally make sure that the stream doesn't disappear
00064      * before WvPipe does!
00065      */
00066     WvPipe(const char *program, const char * const *argv,
00067            bool writable, bool readable, bool catch_stderr,
00068            WvFDStream *stdin_str, WvFDStream *stdout_str = NULL,
00069            WvFDStream *stderr_str = NULL);
00070     
00071     /**
00072      * This constructor is the same again, except that it uses the features
00073      * of the WvFDStream class to get all its fds from one place.
00074      */
00075     WvPipe(const char *program, const char **argv,
00076            bool writable, bool readable, bool catch_stderr,
00077            WvFDStream *stdio_str);
00078 
00079     /** kill the child process and close the stream. */
00080     virtual ~WvPipe();
00081 
00082     /**
00083      * send the child a signal
00084      * (signal names are defined in signal.h)
00085      */
00086     void kill(int signum);
00087     
00088     /** wait for child to die.  Returns exit_status() */
00089     int finish(bool wait_children = true);
00090     
00091     /** returns true if child is dead. */
00092     bool child_exited();
00093 
00094     /** returns true if child is dead because of a signal. */
00095     bool child_killed() const;
00096     
00097     /**
00098      * returns the exit status:
00099      *   if child_killed()==true, the signal that killed the child.
00100      *   if child_killed()==false, the return code of the program.
00101      */
00102     int exit_status();
00103 
00104     // returns pid
00105     int getpid() const { return proc.pid; };
00106 
00107     // callback to ignore everything.  see comment in wvpipe.cc.
00108     static void ignore_read(WvStream& s, void *userdata);
00109 };
00110 
00111 #endif // __WVPIPE_H

Generated on Sat Feb 21 21:05:31 2004 for WvStreams by doxygen 1.3.5