aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/process-run.cxx2
-rw-r--r--libbutl/process-run.txx10
-rw-r--r--libbutl/process.cxx1
-rw-r--r--libbutl/process.hxx28
-rw-r--r--libbutl/process.ixx36
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