rename to subprocess_stream/error

master
Daniel Kolesa 2017-05-11 23:57:04 +02:00
parent 5fc674e4d3
commit 005485f6a6
3 changed files with 67 additions and 67 deletions

View File

@ -84,7 +84,7 @@ Sink &&split_args(Sink &&out, string_range str) {
}
/** @brief Thrown on errors in ostd::subprocess. */
struct process_error: std::runtime_error {
struct subprocess_error: std::runtime_error {
using std::runtime_error::runtime_error;
};
@ -97,7 +97,7 @@ struct process_error: std::runtime_error {
*
* Only use the `STDOUT` value for stderr stream.
*/
enum class process_stream {
enum class subprocess_stream {
DEFAULT = 0, ///< Do not perform any redirection.
PIPE, ///< Capture the stream as an ostd::file_stream.
STDOUT ///< Writes to stderr will be written to stdout.
@ -114,7 +114,7 @@ enum class process_stream {
struct OSTD_EXPORT subprocess {
/** @brief The standard input redirection mode.
*
* The value is one of ostd::process_stream. Set this before opening
* The value is one of ostd::subprocess_stream. Set this before opening
* the subprocess. If it's set to `PIPE`, you will be able to write
* into the standard input of the child process using the `in` member,
* which is a standard ostd::file_stream. Never set it to `STDOUT`
@ -124,11 +124,11 @@ struct OSTD_EXPORT subprocess {
* @see ostd::subprocess::in, ostd::subprocess::use_out,
* ostd::subprocess::use_err
*/
process_stream use_in = process_stream::DEFAULT;
subprocess_stream use_in = subprocess_stream::DEFAULT;
/** @brief The standard output redirection mode.
*
* The value is one of ostd::process_stream. Set this before opening
* The value is one of ostd::subprocess_stream. Set this before opening
* the subprocess. If it's set to `PIPE`, you will be able to read
* from the standard output of the child process using the `out` member,
* which is a standard ostd::file_stream. Setting this to `STDOUT` has
@ -137,11 +137,11 @@ struct OSTD_EXPORT subprocess {
* @see ostd::subprocess::out, ostd::subprocess::use_in,
* ostd::subprocess::use_err
*/
process_stream use_out = process_stream::DEFAULT;
subprocess_stream use_out = subprocess_stream::DEFAULT;
/** @brief The standard error redirection mode.
*
* The value is one of ostd::process_stream. Set this before opening
* The value is one of ostd::subprocess_stream. Set this before opening
* the subprocess. If it's set to `PIPE`, you will be able to read
* from the standard error of the child process using the `err` member,
* which is a standard ostd::file_stream. Setting this to `STDOUT`
@ -153,7 +153,7 @@ struct OSTD_EXPORT subprocess {
* @see ostd::subprocess::err, ostd::subprocess::use_in,
* ostd::subprocess::use_out
*/
process_stream use_err = process_stream::DEFAULT;
subprocess_stream use_err = subprocess_stream::DEFAULT;
/** @brief The standard input stream when redirected.
*
@ -184,9 +184,9 @@ struct OSTD_EXPORT subprocess {
/** @brief Initializes the structure with the given stream redirections. */
subprocess(
process_stream in_use = process_stream::DEFAULT,
process_stream out_use = process_stream::DEFAULT,
process_stream err_use = process_stream::DEFAULT
subprocess_stream in_use = subprocess_stream::DEFAULT,
subprocess_stream out_use = subprocess_stream::DEFAULT,
subprocess_stream err_use = subprocess_stream::DEFAULT
) noexcept:
use_in(in_use), use_out(out_use), use_err(err_use)
{}
@ -200,9 +200,9 @@ struct OSTD_EXPORT subprocess {
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,
subprocess_stream in_use = subprocess_stream::DEFAULT,
subprocess_stream out_use = subprocess_stream::DEFAULT,
subprocess_stream err_use = subprocess_stream::DEFAULT,
std::enable_if_t<
is_input_range<InputRange>, bool
> = true
@ -221,9 +221,9 @@ struct OSTD_EXPORT subprocess {
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,
subprocess_stream in_use = subprocess_stream::DEFAULT,
subprocess_stream out_use = subprocess_stream::DEFAULT,
subprocess_stream err_use = subprocess_stream::DEFAULT,
std::enable_if_t<
is_input_range<InputRange>, bool
> = true
@ -273,21 +273,21 @@ struct OSTD_EXPORT subprocess {
}
try {
close();
} catch (process_error const &) {}
} catch (subprocess_error const &) {}
reset();
}
/** @brief Waits for a currently running child process to be done.
*
* If there isn't any child process assigned to this, it will throw
* ostd::process_error. It will also throw the same exception if some
* other error has occured. It will not throw if the command has
* ostd::subprocess_error. It will also throw the same exception if
* some other error has occured. It will not throw if the command has
* executed but exited with a non-zero code. This code will be
* returned instead.
*
* @returns The child process return code on success.
*
* @throws ostd::process_error on failure of any kind.
* @throws ostd::subprocess_error on failure of any kind.
*
* @see open_path(), open_command()
*/
@ -302,13 +302,13 @@ struct OSTD_EXPORT subprocess {
*
* If `path` is empty, the first element of `args` is used.
*
* If this fails, ostd::process_error will be thrown.
* If this fails, ostd::subprocess_error will be thrown.
*
* On success, a new subprocess will be created and this will return
* without waiting for it to finish. Use close() to wait and get the
* return code.
*
* @throws ostd::process_error on failure of any kind.
* @throws ostd::subprocess_error on failure of any kind.
*
* @see open_command(), close()
*/
@ -334,13 +334,13 @@ struct OSTD_EXPORT subprocess {
*
* If `cmd` is empty, the first element of `args` is used.
*
* If this fails, ostd::process_error will be thrown.
* If this fails, ostd::subprocess_error will be thrown.
*
* On success, a new subprocess will be created and this will return
* without waiting for it to finish. Use close() to wait and get the
* return code.
*
* @throws ostd::process_error on failure of any kind.
* @throws ostd::subprocess_error on failure of any kind.
*
* @see open_path(), close()
*/
@ -367,12 +367,12 @@ private:
argv.emplace_back(args.front());
}
if (argv.empty()) {
throw process_error{"no arguments given"};
throw subprocess_error{"no arguments given"};
}
if (cmd.empty()) {
cmd = argv[0];
if (cmd.empty()) {
throw process_error{"no command given"};
throw subprocess_error{"no command given"};
}
}
open_impl(std::string{cmd}, argv, use_path);

View File

@ -88,12 +88,12 @@ struct pipe {
}
}
void open(process_stream use) {
if (use != process_stream::PIPE) {
void open(subprocess_stream use) {
if (use != subprocess_stream::PIPE) {
return;
}
if (::pipe(fd) < 0) {
throw process_error{"could not open pipe"};
throw subprocess_error{"could not open pipe"};
}
}
@ -104,7 +104,7 @@ struct pipe {
void fdopen(file_stream &s, bool write) {
FILE *p = ::fdopen(fd[std::size_t(write)], write ? "w" : "r");
if (!p) {
throw process_error{"could not open redirected stream"};
throw subprocess_error{"could not open redirected stream"};
}
/* do not close twice, the stream will close it */
fd[std::size_t(write)] = -1;
@ -135,8 +135,8 @@ OSTD_EXPORT void subprocess::open_impl(
std::string const &cmd, std::vector<std::string> const &args,
bool use_path
) {
if (use_in == process_stream::STDOUT) {
throw process_error{"could not redirect stdin to stdout"};
if (use_in == subprocess_stream::STDOUT) {
throw subprocess_error{"could not redirect stdin to stdout"};
}
auto argp = std::make_unique<char *[]>(args.size() + 1);
@ -148,14 +148,14 @@ OSTD_EXPORT void subprocess::open_impl(
/* fd_errno used to detect if exec failed */
pipe fd_errno, fd_stdin, fd_stdout, fd_stderr;
fd_errno.open(process_stream::PIPE);
fd_errno.open(subprocess_stream::PIPE);
fd_stdin.open(use_in);
fd_stdout.open(use_out);
fd_stderr.open(use_err);
auto cpid = fork();
if (cpid == -1) {
throw process_error{"fork failed"};
throw subprocess_error{"fork failed"};
} else if (!cpid) {
/* child process */
fd_errno.close(false);
@ -165,24 +165,24 @@ OSTD_EXPORT void subprocess::open_impl(
std::exit(1);
}
/* prepare standard streams */
if (use_in == process_stream::PIPE) {
if (use_in == subprocess_stream::PIPE) {
fd_stdin.close(true);
if (!fd_stdin.dup2(STDIN_FILENO, fd_errno, false)) {
std::exit(1);
}
}
if (use_out == process_stream::PIPE) {
if (use_out == subprocess_stream::PIPE) {
fd_stdout.close(false);
if (!fd_stdout.dup2(STDOUT_FILENO, fd_errno, true)) {
std::exit(1);
}
}
if (use_err == process_stream::PIPE) {
if (use_err == subprocess_stream::PIPE) {
fd_stderr.close(false);
if (!fd_stderr.dup2(STDERR_FILENO, fd_errno, true)) {
std::exit(1);
}
} else if (use_err == process_stream::STDOUT) {
} else if (use_err == subprocess_stream::STDOUT) {
if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0) {
fd_errno.write_errno();
std::exit(1);
@ -199,15 +199,15 @@ OSTD_EXPORT void subprocess::open_impl(
} else {
/* parent process */
fd_errno.close(true);
if (use_in == process_stream::PIPE) {
if (use_in == subprocess_stream::PIPE) {
fd_stdin.close(false);
fd_stdin.fdopen(in, true);
}
if (use_out == process_stream::PIPE) {
if (use_out == subprocess_stream::PIPE) {
fd_stdout.close(true);
fd_stdout.fdopen(out, false);
}
if (use_err == process_stream::PIPE) {
if (use_err == subprocess_stream::PIPE) {
fd_stderr.close(true);
fd_stderr.fdopen(err, false);
}
@ -230,25 +230,25 @@ OSTD_EXPORT void subprocess::reset() {
OSTD_EXPORT int subprocess::close() {
if (!p_current) {
throw process_error{"no child process"};
throw subprocess_error{"no child process"};
}
data *pd = static_cast<data *>(p_current);
int retc = 0;
if (pid_t wp; (wp = waitpid(pd->pid, &retc, 0)) < 0) {
reset();
throw process_error{"child process wait failed"};
throw subprocess_error{"child process wait failed"};
}
if (retc) {
int eno;
auto r = read(pd->errno_fd, &eno, sizeof(int));
reset();
if (r < 0) {
throw process_error{"could not read from pipe"};
throw subprocess_error{"could not read from pipe"};
} else if (r == sizeof(int)) {
auto ec = std::system_category().default_error_condition(eno);
auto app = appender<std::string>();
format(app, "could not execute subprocess (%s)", ec.message());
throw process_error{std::move(app.get())};
throw subprocess_error{std::move(app.get())};
}
}
reset();

View File

@ -101,15 +101,15 @@ struct pipe {
}
}
void open(process_stream use, SECURITY_ATTRIBUTES &sa, bool read) {
if (use != process_stream::PIPE) {
void open(subprocess_stream use, SECURITY_ATTRIBUTES &sa, bool read) {
if (use != subprocess_stream::PIPE) {
return;
}
if (!CreatePipe(&p_r, &p_w, &sa, 0)) {
throw process_error{"could not open pipe"};
throw subprocess_error{"could not open pipe"};
}
if (!SetHandleInformation(read ? p_r : p_w, HANDLE_FLAG_INHERIT, 0)) {
throw process_error{"could not set pipe parameters"};
throw subprocess_error{"could not set pipe parameters"};
}
}
@ -119,7 +119,7 @@ struct pipe {
read ? _O_RDONLY : 0
);
if (fd < 0) {
throw process_error{"could not open redirected stream"};
throw subprocess_error{"could not open redirected stream"};
}
if (read) {
p_r = nullptr;
@ -129,7 +129,7 @@ struct pipe {
auto p = _fdopen(fd, read ? "r" : "w");
if (!p) {
_close(fd);
throw process_error{"could not open redirected stream"};
throw subprocess_error{"could not open redirected stream"};
}
s.open(p, [](FILE *f) {
std::fclose(f);
@ -283,8 +283,8 @@ static std::string concat_args(std::vector<std::string> const &args) {
OSTD_EXPORT void subprocess::open_impl(
std::string const &cmd, std::vector<std::string> const &args, bool use_path
) {
if (use_in == process_stream::STDOUT) {
throw process_error{"could not redirect stdin to stdout"};
if (use_in == subprocess_stream::STDOUT) {
throw subprocess_error{"could not redirect stdin to stdout"};
}
/* pipes */
@ -310,33 +310,33 @@ OSTD_EXPORT void subprocess::open_impl(
si.cb = sizeof(STARTUPINFOW);
if (use_in == process_stream::PIPE) {
if (use_in == subprocess_stream::PIPE) {
si.hStdInput = pipe_in.p_r;
pipe_in.fdopen(in, false);
} else {
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
if (si.hStdInput == INVALID_HANDLE_VALUE) {
throw process_error{"could not get standard input handle"};
throw subprocess_error{"could not get standard input handle"};
}
}
if (use_out == process_stream::PIPE) {
if (use_out == subprocess_stream::PIPE) {
si.hStdOutput = pipe_out.p_w;
pipe_out.fdopen(out, true);
} else {
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
if (si.hStdOutput == INVALID_HANDLE_VALUE) {
throw process_error{"could not get standard output handle"};
throw subprocess_error{"could not get standard output handle"};
}
}
if (use_err == process_stream::PIPE) {
if (use_err == subprocess_stream::PIPE) {
si.hStdError = pipe_err.p_w;
pipe_err.fdopen(err, true);
} else if (use_err == process_stream::STDOUT) {
} else if (use_err == subprocess_stream::STDOUT) {
si.hStdError = si.hStdOutput;
} else {
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
if (si.hStdError == INVALID_HANDLE_VALUE) {
throw process_error{"could not get standard error handle"};
throw subprocess_error{"could not get standard error handle"};
}
}
si.dwFlags |= STARTF_USESTDHANDLES;
@ -348,7 +348,7 @@ OSTD_EXPORT void subprocess::open_impl(
if (!MultiByteToWideChar(
CP_UTF8, 0, cmd.data(), cmd.size() + 1, wcmd.get(), cmd.size() + 1
)) {
throw process_error{"unicode conversion failed"};
throw subprocess_error{"unicode conversion failed"};
}
if (!use_path) {
cmdpath = wcmd.get();
@ -364,7 +364,7 @@ OSTD_EXPORT void subprocess::open_impl(
if (!MultiByteToWideChar(
CP_UTF8, 0, astr.data(), astr.size() + 1, cmdline.get(), astr.size() + 1
)) {
throw process_error{"unicode conversion failed"};
throw subprocess_error{"unicode conversion failed"};
}
/* owned by CreateProcess, do not close explicitly */
@ -390,7 +390,7 @@ OSTD_EXPORT void subprocess::open_impl(
};
if (!success) {
throw process_error{"could not execute subprocess"};
throw subprocess_error{"could not execute subprocess"};
}
}
@ -400,7 +400,7 @@ OSTD_EXPORT void subprocess::reset() {
OSTD_EXPORT int subprocess::close() {
if (!p_current) {
throw process_error{"no child process"};
throw subprocess_error{"no child process"};
}
data *pd = static_cast<data *>(p_current);
@ -409,7 +409,7 @@ OSTD_EXPORT int subprocess::close() {
CloseHandle(pd->process);
CloseHandle(pd->thread);
reset();
throw process_error{"child process wait failed"};
throw subprocess_error{"child process wait failed"};
}
DWORD ec = 0;
@ -417,7 +417,7 @@ OSTD_EXPORT int subprocess::close() {
CloseHandle(pd->process);
CloseHandle(pd->thread);
reset();
throw process_error{"could not retrieve exit code"};
throw subprocess_error{"could not retrieve exit code"};
}
CloseHandle(pd->process);