add subprocess constructors that open as part of the construction

master
Daniel Kolesa 2017-05-11 19:36:17 +02:00
parent bf8e82b71f
commit cc18d2b736
2 changed files with 50 additions and 14 deletions

View File

@ -106,12 +106,10 @@ static void print_help(ostd::string_range arg0) {
}
static void exec_command(strvec const &args) {
ostd::subprocess p;
p.open_command(ostd::iter(args));
if (int ret; (ret = p.close())) {
auto app = ostd::appender<std::string>();
ostd::format(app, "command failed with code %d", ret);
throw std::runtime_error{app.get()};
if (int ret = ostd::subprocess{ostd::iter(args)}.close(); ret) {
throw std::runtime_error{ostd::format(
ostd::appender<std::string>(), "command failed with code %d", ret
).get()};
}
}

View File

@ -180,19 +180,57 @@ struct OSTD_EXPORT subprocess {
*/
file_stream err = file_stream{};
/** @brief Initializes a default subprocess.
*
* No streams will be set to redirect.
*/
subprocess() noexcept {}
/** @brief Initializes a subprocess with the given stream redirections.*/
/** @brief Initializes the structure with the given stream redirections. */
subprocess(
process_stream in_use, process_stream out_use, process_stream err_use
process_stream in_use = process_stream::DEFAULT,
process_stream out_use = process_stream::DEFAULT,
process_stream err_use = process_stream::DEFAULT
) noexcept:
use_in(in_use), use_out(out_use), use_err(err_use)
{}
/** @brief Initializes the structure and opens a subprocess.
*
* This is similar to calling either open_command() or open_path()
* after constructing the object depending on `use_path`. It may
* throw the same exceptions as the respective two methods.
*/
template<typename InputRange>
subprocess(
string_range cmd, InputRange &&args, bool use_path = true,
process_stream in_use = process_stream::DEFAULT,
process_stream out_use = process_stream::DEFAULT,
process_stream err_use = process_stream::DEFAULT,
std::enable_if_t<
is_input_range<InputRange>, bool
> = true
):
use_in(in_use), use_out(out_use), use_err(err_use)
{
open_full(cmd, std::forward<InputRange>(args), use_path);
}
/** @brief Initializes the structure and opens a subprocess.
*
* This is similar to calling either open_command() or open_path()
* after constructing the object depending on `use_path`. It may
* throw the same exceptions as the respective two methods.
*/
template<typename InputRange>
subprocess(
InputRange &&args, bool use_path = true,
process_stream in_use = process_stream::DEFAULT,
process_stream out_use = process_stream::DEFAULT,
process_stream err_use = process_stream::DEFAULT,
std::enable_if_t<
is_input_range<InputRange>, bool
> = true
):
use_in(in_use), use_out(out_use), use_err(err_use)
{
open_full(nullptr, std::forward<InputRange>(args), use_path);
}
/** @brief Moves the subprocess data. */
subprocess(subprocess &&i) noexcept:
use_in(i.use_in), use_out(i.use_out), use_err(i.use_err),