aboutsummaryrefslogtreecommitdiff
path: root/butl/process
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-07-23 14:47:09 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-07-23 14:47:09 +0200
commite2d759fce9ff5e5886064ec693af54fe598773ff (patch)
tree2ecc81af9347fdf5b60182536dabdf24e9fd9546 /butl/process
parent9565dd32bbd68d2fada2fbe2ece4b778b43e6bb0 (diff)
Add support for process redirection to existing fd, piping
Diffstat (limited to 'butl/process')
-rw-r--r--butl/process44
1 files changed, 33 insertions, 11 deletions
diff --git a/butl/process b/butl/process
index 52aad41..cf18acd 100644
--- a/butl/process
+++ b/butl/process
@@ -28,18 +28,36 @@ namespace butl
struct process
{
- // Start another process using the specified command line. Connect the
- // newly created process' stdin to out_fd. Also if connect_* are true,
- // connect the created process' stdout and stderr to in_*fd. Throw
- // process_error if anything goes wrong.
+ // Start another process using the specified command line. The default
+ // values to the in, out and err arguments indicate that the child
+ // process should inherit the parent process stdin, stdout, and stderr,
+ // respectively. If -1 is passed instead, then the corresponding child
+ // process descriptor is connected (via a pipe) to out_fd for stdin,
+ // in_ofd for stdout, and in_efd for stderr (see data members below).
+ //
+ // Instead of passing -1 or the default value, you can also pass your
+ // own descriptors. Note, however, that in this case they are not
+ // closed by the parent. So you should do this yourself, if required.
+ // For example, to redirect the child process stdout to stderr, you
+ // can do:
+ //
+ // process p (..., 0, 2);
//
- // Note that some of the exceptions (e.g., if exec() failed) can be
- // thrown in the child version of us.
+ // Throw process_error if anything goes wrong. Note that some of the
+ // exceptions (e.g., if exec() failed) can be thrown in the child
+ // version of us.
//
- process (char const* args[],
- bool connect_stdin = false,
- bool connect_stderr = false,
- bool connect_stdout = false);
+ process (char const* args[], int in = 0, int out = 1, int err = 2);
+
+ // The "piping" constructor, for example:
+ //
+ // process lhs (..., 0, -1); // Redirect stdout to a pipe.
+ // process rhs (..., lhs); // Redirect stdin to lhs's pipe.
+ //
+ // rhs.wait (); // Wait for last first.
+ // lhs.wait ();
+ //
+ process (char const* args[], process& in, int out = 1, int err = 2);
// Wait for the process to terminate. Return true if the process
// terminated normally and with the zero exit status. Throw
@@ -50,6 +68,9 @@ namespace butl
~process () {if (id != 0) wait ();}
+ process (const process&) = delete;
+ process& operator= (const process&) = delete;
+
#ifndef _WIN32
typedef pid_t id_type;
#else
@@ -57,9 +78,10 @@ namespace butl
#endif
id_type id;
+
int out_fd; // Write to this fd to send to the new process' stdin.
- int in_efd; // Read from this fd to receive from the new process' stderr.
int in_ofd; // Read from this fd to receive from the new process' stdout.
+ int in_efd; // Read from this fd to receive from the new process' stderr.
};
}