gebs_cmd_run_collect() for collecting command output, Add examples/commands.c
This commit is contained in:
71
gebs.h
71
gebs.h
@ -236,6 +236,14 @@ int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd);
|
||||
gebs_cmd_run(&__cmd); \
|
||||
})
|
||||
|
||||
int gebs_cmd_run_sync_collect_alloc(Gebs_Allocator *alloc,
|
||||
Gebs_Cmd *cmd, Gebs_String_Builder *sb_out);
|
||||
|
||||
#define gebs_cmd_run_collect_alloc gebs_cmd_run_sync_collect_alloc
|
||||
|
||||
#define gebs_cmd_run_collect(cmd, out) \
|
||||
gebs_cmd_run_collect_alloc(&gebs_default_allocator, (cmd), (out))
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// The build system
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -330,6 +338,69 @@ int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd)
|
||||
#endif
|
||||
}
|
||||
|
||||
int gebs_cmd_run_sync_collect_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd, Gebs_String_Builder *sb_out)
|
||||
{
|
||||
Gebs_String_Builder sb = {0};
|
||||
gebs_nsl_join_alloc(alloc, cmd, &sb, " ");
|
||||
GEBS_LOGI("cmd `%s`\n", sb.items);
|
||||
|
||||
#if GEBS_PLATFORM == GEBS_PLATFORM_POSIX
|
||||
// Clone the list
|
||||
Gebs_Cmd new_cmd = {0};
|
||||
defer { gebs_cmd_free_alloc(alloc, &new_cmd); }
|
||||
for (size_t i = 0; i < cmd->count; i++) {
|
||||
gebs_cmd_append_alloc(alloc, &new_cmd, cmd->items[i]);
|
||||
}
|
||||
gebs_cmd_append_alloc((alloc), &new_cmd, NULL);
|
||||
|
||||
int pipe_ends[2];
|
||||
pipe(pipe_ends);
|
||||
|
||||
pid_t pid = vfork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
close(pipe_ends[0]);
|
||||
close(pipe_ends[1]);
|
||||
GEBS_LOGE("Could not vfork\n");
|
||||
return -1;
|
||||
case 0:
|
||||
close(pipe_ends[0]);
|
||||
dup2(pipe_ends[1], 1);
|
||||
close(pipe_ends[1]);
|
||||
|
||||
execvp(new_cmd.items[0], (char * const *)new_cmd.items);
|
||||
exit(EXIT_FAILURE);
|
||||
default: {
|
||||
close(pipe_ends[1]);
|
||||
char c;
|
||||
while (read(pipe_ends[0], &c, 1) > 0) {
|
||||
gebs_sb_append_char_alloc(alloc, sb_out, c);
|
||||
}
|
||||
gebs_sb_finish_alloc(alloc, sb_out);
|
||||
|
||||
int wstatus;
|
||||
do {
|
||||
if (waitpid(pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (WIFEXITED(wstatus)) {
|
||||
return WEXITSTATUS(wstatus);
|
||||
} else if (WIFSIGNALED(wstatus)) {
|
||||
GEBS_LOGI("%d killed by %d\n", pid, WTERMSIG(wstatus));
|
||||
return -1;
|
||||
} else if (WIFSTOPPED(wstatus)) {
|
||||
GEBS_LOGI("%d stopped by %d\n", pid, WSTOPSIG(wstatus));
|
||||
return -1;
|
||||
}
|
||||
} while(!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
|
||||
}
|
||||
}
|
||||
#else
|
||||
# error "gebs_cmd_run_sync_alloc unknown command"
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Allocators
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user