2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * Provides support for piping data to/from subprocesses.
10 #include "wvfdstream.h"
11 #include "wvsubproc.h"
14 * Implementation of a WvPipe stream. These allow you to create a new
15 * process, attaching its stdin/stdout to a WvStream.
17 * Unlike pipes created with the popen() system call, you can capture
18 * both stdin and stdout for the given process. This is because we
19 * actually use the socketpair() call instead. If you try this,
20 * however, you must be very careful to always use the select() call
21 * before reading from the stream. (Think what would happen if both
22 * ends of the pipe do a read() simultaneously!)
24 * Note that we do not go as far as actually using a pty. That means
25 * programs which deliberately open /dev/tty will not be redirected.
27 * When the WvPipe is destroyed, it makes sure that the child process
28 * is killed. Since it tries to do it politely (SIGTERM, wait up to
29 * 2 seconds, SIGKILL) it can take up to 2 seconds to destroy a
32 class WvPipe
: public WvFDStream
36 void setup(const char *program
, const char * const *argv
,
37 bool writable
, bool readable
, bool catch_stderr
,
38 int stdin_fd
, int stdout_fd
, int stderr_fd
,
42 * default pipe constructor; if you just want to use a pipe, use this.
43 * For each of stdin, stdout, and stderr of the child process, it can
44 * do one of three things:
45 * - leave it alone (ie. the same as for the parent process)
46 * - redirect it through the WvPipe (eg. if writable==true)
47 * - redirect it to any open file descriptor (std*_fd are only
48 * used if the corresponding bool is false, however)
49 * Note that you need either writable or readable set to true if you
50 * want the pipe to close automatically (for instance, when it's
51 * appened to the globallist). Use the ignore_read() callback if
52 * you really don't care about its output.
54 WvPipe(const char *program
, const char * const *argv
,
55 bool writable
, bool readable
, bool catch_stderr
,
56 int stdin_fd
= 0, int stdout_fd
= 1, int stderr_fd
= 2,
57 WvStringList
*env
= NULL
);
60 * This constructor does much the same thing as the previous one,
61 * except that std*_str are WvStreams instead. The target process
62 * accesses the 'fd' member of the stream (NOT using
63 * the WvStream read() and write() functions).
65 * Again, we only redirect to the given WvStreams if the corresponding
66 * bool is false; otherwise, we redirect to the pipe.
68 * It is okay for the same WvStream to occur more than once. Also,
69 * you must naturally make sure that the stream doesn't disappear
72 WvPipe(const char *program
, const char * const *argv
,
73 bool writable
, bool readable
, bool catch_stderr
,
74 WvFDStream
*stdin_str
, WvFDStream
*stdout_str
= NULL
,
75 WvFDStream
*stderr_str
= NULL
, WvStringList
*env
= NULL
);
78 * This constructor is the same again, except that it uses the features
79 * of the WvFDStream class to get all its fds from one place.
81 WvPipe(const char *program
, const char **argv
,
82 bool writable
, bool readable
, bool catch_stderr
,
83 WvFDStream
*stdio_str
, WvStringList
*env
= NULL
);
85 /** kill the child process and close the stream. */
89 * send the child a signal
90 * (signal names are defined in signal.h)
92 void kill(int signum
);
94 /** wait for child to die. Returns exit_status() */
95 int finish(bool wait_children
= true);
97 /** returns true if child is dead. */
100 /** returns true if child is dead because of a signal. */
101 bool child_killed() const;
104 * returns the exit status:
105 * if child_killed()==true, the signal that killed the child.
106 * if child_killed()==false, the return code of the program.
111 int getpid() const { return proc
.pid
; };
113 // callback to ignore everything. see comment in wvpipe.cc.
114 static void ignore_read(WvStream
&s
);
117 const char *wstype() const { return "WvPipe"; }