gebs_cmd_run_collect() for collecting command output, Add examples/commands.c

This commit is contained in:
kamkow1
2025-05-25 22:01:26 +02:00
parent 11e3ee039a
commit aad54edf84
3 changed files with 102 additions and 0 deletions

26
example/commands.c Normal file
View File

@ -0,0 +1,26 @@
#include <stdio.h>
#define GEBS_IMPLEMENTATION
#include "../gebs.h"
int main(int argc, char ** argv)
{
gebs_rebuild_self(argc, argv, "cc", "-o", "commands", __FILE__);
int code = GEBS_CMD("ls", "-la");
GEBS_LOGI("Exited with %d\n", code);
Gebs_Cmd cmd = {0};
defer { gebs_list_free(&cmd); }
gebs_cmd_append(&cmd, "ls");
gebs_cmd_append(&cmd, "-la");
Gebs_String_Builder out_sb = {0};
defer { gebs_sb_free(&out_sb); }
code = gebs_cmd_run_collect(&cmd, &out_sb);
printf("CAPTURED\n%sCAPTURED\n", out_sb.items);
GEBS_LOGI("Exited with %d\n", code);
return 0;
}

5
gebs.c
View File

@ -17,6 +17,11 @@ int main(int argc, char ** argv)
if (GEBS_CMD("gcc", "-ggdb", "-o", "build/arena", "example/arena.c") != 0) if (GEBS_CMD("gcc", "-ggdb", "-o", "build/arena", "example/arena.c") != 0)
return 1; return 1;
} }
if (gebs_needs_rebuild_many("build/commands", "example/commands.c", "gebs.h")) {
if (GEBS_CMD("gcc", "-ggdb", "-o", "build/commands", "example/commands.c") != 0) {
return 1;
}
}
return 0; return 0;
} }

71
gebs.h
View File

@ -236,6 +236,14 @@ int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd);
gebs_cmd_run(&__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 // The build system
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -330,6 +338,69 @@ int gebs_cmd_run_sync_alloc(Gebs_Allocator *alloc, Gebs_Cmd *cmd)
#endif #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 // Allocators
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------