diff options
-rw-r--r-- | libbutl/process-run.cxx | 2 | ||||
-rw-r--r-- | libbutl/process-run.txx | 10 | ||||
-rw-r--r-- | libbutl/process.cxx | 1 | ||||
-rw-r--r-- | libbutl/process.hxx | 28 | ||||
-rw-r--r-- | libbutl/process.ixx | 36 |
5 files changed, 67 insertions, 10 deletions
diff --git a/libbutl/process-run.cxx b/libbutl/process-run.cxx index a5014f6..b044ea1 100644 --- a/libbutl/process-run.cxx +++ b/libbutl/process-run.cxx @@ -24,7 +24,7 @@ namespace butl try { return process (pp, cmd, - in, out, err, + move (in), move (out), move (err), cwd != nullptr ? cwd->string ().c_str () : nullptr, envvars); } diff --git a/libbutl/process-run.txx b/libbutl/process-run.txx index 8e6ca57..67426f0 100644 --- a/libbutl/process-run.txx +++ b/libbutl/process-run.txx @@ -87,21 +87,21 @@ namespace butl // valid file descriptor. // inline process::pipe - process_stdin (const process::pipe& v) + process_stdin (process::pipe v) { assert (v.in >= 0); return v; } inline process::pipe - process_stdout (const process::pipe& v) + process_stdout (process::pipe v) { assert (v.out >= 0); return v; } inline process::pipe - process_stderr (const process::pipe& v) + process_stderr (process::pipe v) { assert (v.out >= 0); return v; @@ -170,7 +170,9 @@ namespace butl return process_start (env.cwd, *env.path, cmd.data (), env.vars, - in_i, out_i, err_i); + std::move (in_i), + std::move (out_i), + std::move (err_i)); } template <typename C, diff --git a/libbutl/process.cxx b/libbutl/process.cxx index a19719f..aee4508 100644 --- a/libbutl/process.cxx +++ b/libbutl/process.cxx @@ -1794,7 +1794,6 @@ namespace butl using namespace chrono; - // Retry for about 1 hour. // system_clock::duration timeout (1h); diff --git a/libbutl/process.hxx b/libbutl/process.hxx index 47cc507..cf5bcd8 100644 --- a/libbutl/process.hxx +++ b/libbutl/process.hxx @@ -298,21 +298,41 @@ namespace butl const char* const* envvars = nullptr); // If the descriptors are pipes that you have created, then you should use - // this constructor instead to communicate this information. + // this constructor instead to communicate this information (the parent + // end may need to be "probed" on Windows). // // For generality, if the "other" end of the pipe is -1, then assume this // is not a pipe. // struct pipe { - int in = -1; - int out = -1; - pipe () = default; pipe (int i, int o): in (i), out (o) {} explicit pipe (const fdpipe& p): in (p.in.get ()), out (p.out.get ()) {} + + // Transfer ownership to one end of the pipe. + // + pipe (auto_fd i, int o): in (i.release ()), out (o), own_in (true) {} + pipe (int i, auto_fd o): in (i), out (o.release ()), own_out (true) {} + + // Moveable-only type. + // + pipe (pipe&&); + pipe& operator= (pipe&&); + + pipe (const pipe&) = delete; + pipe& operator= (const pipe&) = delete; + + ~pipe (); + + public: + int in = -1; + int out = -1; + + bool own_in = false; + bool own_out = false; }; process (const process_path&, const char* [], diff --git a/libbutl/process.ixx b/libbutl/process.ixx index 256454b..0f04127 100644 --- a/libbutl/process.ixx +++ b/libbutl/process.ixx @@ -124,6 +124,42 @@ namespace butl } #endif + // process::pipe + // + inline process::pipe:: + pipe (pipe&& p) + : in (p.in), out (p.out), own_in (p.own_in), own_out (p.own_out) + { + p.in = p.out = -1; + } + + inline process::pipe& process::pipe:: + operator= (pipe&& p) + { + if (this != &p) + { + int d (own_in ? in : own_out ? out : -1); + if (d != -1) + fdclose (d); + + in = p.in; + out = p.out; + own_in = p.own_in; + own_out = p.own_out; + + p.in = p.out = -1; + } + return *this; + } + + inline process::pipe:: + ~pipe () + { + int d (own_in ? in : own_out ? out : -1); + if (d != -1) + fdclose (d); + } + // process // #ifndef _WIN32 |