From 61377c582e0f2675baa5f5e6e30a35d1a4164b33 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 1 May 2017 16:08:43 +0300 Subject: Add hxx extension for headers and lib prefix for library dir --- libbutl/process-run.txx | 226 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 libbutl/process-run.txx (limited to 'libbutl/process-run.txx') diff --git a/libbutl/process-run.txx b/libbutl/process-run.txx new file mode 100644 index 0000000..28c44cf --- /dev/null +++ b/libbutl/process-run.txx @@ -0,0 +1,226 @@ +// file : libbutl/process-run.txx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include +#include // move(), forward(), index_sequence + +namespace butl +{ + inline int process_stdin (int v) {assert (v >= 0); return v;} + inline int process_stdout (int v) {assert (v >= 0); return v;} + inline int process_stderr (int v) {assert (v >= 0); return v;} + + inline int + process_stdin (const auto_fd& v) {assert (v.get () >= 0); return v.get ();} + + inline int + process_stdout (const auto_fd& v) {assert (v.get () >= 0); return v.get ();} + + inline int + process_stderr (const auto_fd& v) {assert (v.get () >= 0); return v.get ();} + + LIBBUTL_EXPORT process + process_start (const dir_path& cwd, + const process_path& pp, + const char* cmd[], + int in, + int out, + int err); + + template + inline const char* + process_args_as_wrapper (V& v, const T& x, std::string& storage) + { + process_args_as (v, x, storage); + return nullptr; + } + + template + process + process_start (std::index_sequence, + const C& cmdc, + I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const process_path& pp, + A&&... args) + { + // Map stdin/stdout/stderr arguments to their integer values, as expected + // by the process constructor. + // + int in_i (process_stdin (std::forward (in))); + int out_i (process_stdout (std::forward (out))); + int err_i (process_stderr (std::forward (err))); + + // Construct the command line array. + // + const std::size_t args_size (sizeof... (args)); + + small_vector cmd; + cmd.push_back (pp.recall_string ()); + + std::string storage[args_size != 0 ? args_size : 1]; + + const char* dummy[] = { + nullptr, process_args_as_wrapper (cmd, args, storage[index])... }; + + cmd.push_back (dummy[0]); // NULL (and get rid of unused warning). + + cmdc (cmd.data (), cmd.size ()); + + // @@ Do we need to make sure certain fd's are closed before calling + // wait()? Is this only the case with pipes? Needs thinking. + + return process_start (cwd, pp, cmd.data (), in_i, out_i, err_i); + } + + template + inline process + process_start (const C& cmdc, + I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const process_path& pp, + A&&... args) + { + return process_start (std::index_sequence_for (), + cmdc, + std::forward (in), + std::forward (out), + std::forward (err), + cwd, + pp, + std::forward (args)...); + } + + template + inline process + process_start (I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const P& p, + A&&... args) + { + return process_start ([] (const char* [], std::size_t) {}, + std::forward (in), + std::forward (out), + std::forward (err), + cwd, + process::path_search (p, true), + std::forward (args)...); + } + + template + inline process + process_start (const C& cmdc, + I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const P& p, + A&&... args) + { + return process_start (cmdc, + std::forward (in), + std::forward (out), + std::forward (err), + cwd, + process::path_search (p, true), + std::forward (args)...); + } + + template + inline process_exit + process_run (const C& cmdc, + I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const process_path& pp, + A&&... args) + { + process pr ( + process_start (cmdc, + std::forward (in), + std::forward (out), + std::forward (err), + cwd, + pp, + std::forward (args)...)); + + pr.wait (); + return *pr.exit; + } + + template + inline process_exit + process_run (I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const P& p, + A&&... args) + { + return process_run ([] (const char* [], std::size_t) {}, + std::forward (in), + std::forward (out), + std::forward (err), + cwd, + process::path_search (p, true), + std::forward (args)...); + } + + template + inline process_exit + process_run (const C& cmdc, + I&& in, + O&& out, + E&& err, + const dir_path& cwd, + const P& p, + A&&... args) + { + return process_run (cmdc, + std::forward (in), + std::forward (out), + std::forward (err), + cwd, + process::path_search (p, true), + std::forward (args)...); + } +} -- cgit v1.1