Implement cmd_run_XXX variants for running via a file descriptor

This commit is contained in:
kamkow1
2025-06-09 20:10:46 +02:00
parent 9582176638
commit 61e59e6550

126
gebs.h
View File

@ -330,10 +330,13 @@ typedef Gebs_NString_List Gebs_Cmd;
#define gebs_cmd_free gebs_list_free
#define gebs_cmd_run_alloc gebs_cmd_run_sync_alloc
#define gebs_cmd_fd_run_alloc gebs_cmd_run_sync_alloc
#define gebs_cmd_run(cmd) gebs_cmd_run_alloc(&gebs_default_allocator, (cmd))
#define gebs_cmd_fd_run(fd, cmd) gebs_cmd_fd_run_alloc(&gebs_default_allocator, fd, (cmd))
int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd);
int gebs_cmd_fd_run_sync_alloc(Gebs_Allocator *alloc, int fd, Gebs_Cmd *cmd);
#define GEBS_CMD(...) \
({ \
@ -349,11 +352,18 @@ int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd);
int gebs_cmd_run_sync_collect_alloc(Gebs_Allocator *alloc,
Gebs_Cmd *cmd, Gebs_String_Builder *sb_out);
int gebs_cmd_fd_run_sync_collect_alloc(Gebs_Allocator *alloc, int fd,
Gebs_Cmd *cmd, Gebs_String_Builder *sb_out);
#define gebs_cmd_run_collect_alloc gebs_cmd_run_sync_collect_alloc
#define gebs_cmd_fd_run_collect_alloc gebs_cmd_fd_run_sync_collect_alloc
#define gebs_cmd_run_collect(cmd, out) \
gebs_cmd_run_collect_alloc(&gebs_default_allocator, (cmd), (out))
#define gebs_cmd_fd_run_collect(fd, cmd, out) \
gebs_cmd_fd_run_collect_alloc(&gebs_default_allocator, (fd), (cmd), (out))
// ----------------------------------------------------------------------------
// The build system
// ----------------------------------------------------------------------------
@ -463,6 +473,53 @@ int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd)
}
}
int gebs_cmd_fd_run_sync_alloc(Gebs_Allocator *alloc, int fd, Gebs_Cmd *cmd)
{
Gebs_String_Builder sb = {0};
defer { gebs_sb_free_alloc(alloc, &sb); }
gebs_nsl_join_alloc(alloc, cmd, &sb, " ");
gebs_sb_finish_alloc(alloc, &sb);
GEBS_LOGI("cmd `%s`\n", sb.items);
// 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, nil);
pid_t pid = vfork();
switch (pid) {
case -1:
GEBS_LOGE("Could not vfork\n");
return -1;
case 0: {
const char *const envp[] = {NULL};
fexecve(fd, (char * const *)new_cmd.items, (char * const *)envp);
exit(EXIT_FAILURE);
} break;
default: {
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));
}
}
}
int gebs_cmd_run_sync_collect_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd, Gebs_String_Builder *sb_out)
{
Gebs_String_Builder sb = {0};
@ -524,6 +581,69 @@ int gebs_cmd_run_sync_collect_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd, Gebs_S
}
}
int gebs_cmd_fd_run_sync_collect_alloc(Gebs_Allocator *alloc, int fd, Gebs_Cmd *cmd, Gebs_String_Builder *sb_out)
{
Gebs_String_Builder sb = {0};
defer { gebs_sb_free_alloc(alloc, &sb); }
gebs_nsl_join_alloc(alloc, cmd, &sb, " ");
gebs_sb_finish_alloc(alloc, &sb);
GEBS_LOGI("cmd `%s`\n", sb.items);
// 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, nil);
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]);
const char *const envp[] = {NULL};
fexecve(fd, (char *const *)new_cmd.items, (char *const *)envp);
exit(EXIT_FAILURE);
} break;
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));
}
}
}
// ----------------------------------------------------------------------------
// Allocators
// ----------------------------------------------------------------------------
@ -832,6 +952,12 @@ void gebs_rebuild_self1_alloc(Gebs_Allocator *alloc, int argc, char ** argv,
#define cmd_run_sync_collect_alloc gebs_cmd_run_sync_collect_alloc
#define cmd_run_collect_alloc gebs_cmd_run_collect_alloc
#define cmd_run_collect gebs_cmd_run_collect
#define cmd_fd_run_sync_collect_alloc gebs_cmd_fd_run_sync_collect_alloc
#define cmd_fd_run_collect_alloc gebs_cmd_fd_run_collect_alloc
#define cmd_fd_run_collect gebs_cmd_fd_run_collect
#define cmd_fd_run_sync_alloc gebs_cmd_fd_run_sync_alloc
#define cmd_fd_run_alloc gebs_cmd_fd_run_alloc
#define cmd_fd_run gebs_cmd_fd_run
#define needs_rebuild gebs_needs_rebuild
#define needs_rebuild_many gebs_needs_rebuild_many