Wire up the error sink for os exec
This commit is contained in:
parent
003e2777de
commit
a15e98212d
@ -697,6 +697,7 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
Dqn_Scratch scratch = Dqn_Scratch_Get(nullptr);
|
Dqn_Scratch scratch = Dqn_Scratch_Get(nullptr);
|
||||||
|
Dqn_Str8 cmd_rendered = Dqn_Slice_Str8Render(scratch.arena, cmd_line, DQN_STR8(" "));
|
||||||
int stdout_pipe[Dqn_OSPipeType__Count] = {};
|
int stdout_pipe[Dqn_OSPipeType__Count] = {};
|
||||||
int stderr_pipe[Dqn_OSPipeType__Count] = {};
|
int stderr_pipe[Dqn_OSPipeType__Count] = {};
|
||||||
|
|
||||||
@ -704,6 +705,12 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
if (Dqn_Bit_IsSet(exec_flags, Dqn_OSExecFlag_SaveStdout)) {
|
if (Dqn_Bit_IsSet(exec_flags, Dqn_OSExecFlag_SaveStdout)) {
|
||||||
if (pipe(stdout_pipe) == -1) {
|
if (pipe(stdout_pipe) == -1) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to create stdout pipe to redirect the output of the command '%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
DQN_ASSERT(stdout_pipe[Dqn_OSPipeType__Read] != 0);
|
DQN_ASSERT(stdout_pipe[Dqn_OSPipeType__Read] != 0);
|
||||||
@ -725,14 +732,19 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
stderr_pipe[Dqn_OSPipeType__Write] = stdout_pipe[Dqn_OSPipeType__Write];
|
stderr_pipe[Dqn_OSPipeType__Write] = stdout_pipe[Dqn_OSPipeType__Write];
|
||||||
} else if (pipe(stderr_pipe) == -1) {
|
} else if (pipe(stderr_pipe) == -1) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to create stderr pipe to redirect the output of the command '%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
DQN_ASSERT(stderr_pipe[Dqn_OSPipeType__Read] != 0);
|
DQN_ASSERT(stderr_pipe[Dqn_OSPipeType__Read] != 0);
|
||||||
DQN_ASSERT(stderr_pipe[Dqn_OSPipeType__Write] != 0);
|
DQN_ASSERT(stderr_pipe[Dqn_OSPipeType__Write] != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_DEFER
|
DQN_DEFER {
|
||||||
{
|
|
||||||
if (result.os_error_code == 0 && result.exit_code == 0)
|
if (result.os_error_code == 0 && result.exit_code == 0)
|
||||||
return;
|
return;
|
||||||
close(stderr_pipe[Dqn_OSPipeType__Read]);
|
close(stderr_pipe[Dqn_OSPipeType__Read]);
|
||||||
@ -742,6 +754,12 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
pid_t child_pid = fork();
|
pid_t child_pid = fork();
|
||||||
if (child_pid < 0) {
|
if (child_pid < 0) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to fork process to execute the command '%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,12 +767,24 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
if (Dqn_Bit_IsSet(exec_flags, Dqn_OSExecFlag_SaveStdout) &&
|
if (Dqn_Bit_IsSet(exec_flags, Dqn_OSExecFlag_SaveStdout) &&
|
||||||
(dup2(stdout_pipe[Dqn_OSPipeType__Write], STDOUT_FILENO) == -1)) {
|
(dup2(stdout_pipe[Dqn_OSPipeType__Write], STDOUT_FILENO) == -1)) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to redirect stdout 'write' pipe for output of command '%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Dqn_Bit_IsSet(exec_flags, Dqn_OSExecFlag_SaveStderr) &&
|
if (Dqn_Bit_IsSet(exec_flags, Dqn_OSExecFlag_SaveStderr) &&
|
||||||
(dup2(stderr_pipe[Dqn_OSPipeType__Write], STDERR_FILENO) == -1)) {
|
(dup2(stderr_pipe[Dqn_OSPipeType__Write], STDERR_FILENO) == -1)) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to redirect stderr 'read' pipe for output of command '%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -763,19 +793,22 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
Dqn_Arena_NewArray(scratch.arena, char *, cmd_line.size + 1 /*null*/, Dqn_ZeroMem_Yes);
|
Dqn_Arena_NewArray(scratch.arena, char *, cmd_line.size + 1 /*null*/, Dqn_ZeroMem_Yes);
|
||||||
if (!argv) {
|
if (!argv) {
|
||||||
result.exit_code = -1;
|
result.exit_code = -1;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to create argument values from command line '%.*s': Out of memory",
|
||||||
|
DQN_STR_FMT(cmd_rendered));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Dqn_usize arg_index = 0; arg_index < cmd_line.size; arg_index++) {
|
for (Dqn_usize arg_index = 0; arg_index < cmd_line.size; arg_index++) {
|
||||||
Dqn_Str8 arg = cmd_line.data[arg_index];
|
Dqn_Str8 arg = cmd_line.data[arg_index];
|
||||||
argv[arg_index] = Dqn_Str8_Copy(scratch.arena, arg)
|
argv[arg_index] = Dqn_Str8_Copy(scratch.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated
|
||||||
.data; // NOTE: Copy string to guarantee it is null-terminated
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Change the working directory if there is one
|
// NOTE: Change the working directory if there is one
|
||||||
char *prev_working_dir = nullptr;
|
char *prev_working_dir = nullptr;
|
||||||
DQN_DEFER
|
DQN_DEFER {
|
||||||
{
|
|
||||||
if (!prev_working_dir)
|
if (!prev_working_dir)
|
||||||
return;
|
return;
|
||||||
if (result.os_error_code == 0) {
|
if (result.os_error_code == 0) {
|
||||||
@ -789,6 +822,12 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
prev_working_dir = get_current_dir_name();
|
prev_working_dir = get_current_dir_name();
|
||||||
if (chdir(working_dir.data) == -1) {
|
if (chdir(working_dir.data) == -1) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to create argument values from command line '%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -797,6 +836,12 @@ DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Slice<Dqn_Str8> cmd_line,
|
|||||||
// binary to execute is guaranteed to be null-terminated.
|
// binary to execute is guaranteed to be null-terminated.
|
||||||
if (execvp(argv[0], argv) < 0) {
|
if (execvp(argv[0], argv) < 0) {
|
||||||
result.os_error_code = errno;
|
result.os_error_code = errno;
|
||||||
|
Dqn_ErrorSink_MakeF(
|
||||||
|
error,
|
||||||
|
result.os_error_code,
|
||||||
|
"Failed to execute command'%.*s': %s",
|
||||||
|
DQN_STR_FMT(cmd_rendered),
|
||||||
|
strerror(result.os_error_code));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user