gebs_cmd_run_collect() for collecting command output, Add examples/commands.c
This commit is contained in:
26
example/commands.c
Normal file
26
example/commands.c
Normal 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
5
gebs.c
@ -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
71
gebs.h
@ -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
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user