2026-01-17 18:21:08 +01:00
|
|
|
#include "command.h"
|
|
|
|
|
|
|
|
|
|
#include "memory.h"
|
|
|
|
|
#include "discovery.h"
|
|
|
|
|
#include "io.h"
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
|
|
|
|
|
// TODO: This file is UNSAFE. This file is purely here for MVP purposes, and to self-host this program itself.
|
|
|
|
|
|
2026-01-18 16:43:23 +01:00
|
|
|
Command command_create_f_to_o(CommandOptions* co)
|
2026-01-17 18:21:08 +01:00
|
|
|
{
|
2026-01-18 16:43:23 +01:00
|
|
|
assert(co != NULL);
|
|
|
|
|
|
|
|
|
|
size_t len_args = 6;
|
|
|
|
|
|
|
|
|
|
size_t flag_count = 0;
|
2026-01-17 18:21:08 +01:00
|
|
|
|
2026-01-18 16:43:23 +01:00
|
|
|
StringView* dep_flags_buf = NULL;
|
|
|
|
|
|
|
|
|
|
switch(co->bp)
|
|
|
|
|
{
|
|
|
|
|
case B_DEBUG:
|
|
|
|
|
len_args += co->c->debug_compiler_flags_c;
|
|
|
|
|
flag_count = co->c->debug_compiler_flags_c;
|
|
|
|
|
dep_flags_buf = co->c->debug_compiler_flags;
|
|
|
|
|
break;
|
|
|
|
|
case B_PROD:
|
|
|
|
|
len_args += co->c->prod_compiler_flags_c;
|
|
|
|
|
flag_count = co->c->prod_compiler_flags_c;
|
|
|
|
|
dep_flags_buf = co->c->prod_compiler_flags;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
DIE("No configuration was selected!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char** args_buf = (const char**)arena_alloc(co->a, sizeof(const char*) * len_args);
|
|
|
|
|
args_buf[0] = co->app.buf;
|
|
|
|
|
args_buf[1] = "-c";
|
|
|
|
|
args_buf[2] = co->files[0].buf;
|
|
|
|
|
args_buf[3] = "-o";
|
2026-01-17 18:21:08 +01:00
|
|
|
|
2026-01-18 16:43:23 +01:00
|
|
|
StringView o_ext = STR_LIT(co->sp, ".o");
|
|
|
|
|
StringView f_o = string_concat_ss(co->sp, &co->files[0], &o_ext);
|
|
|
|
|
args_buf[4] = f_o.buf;
|
|
|
|
|
args_buf[5] = "-MMD";
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < flag_count; i++)
|
2026-01-17 18:21:08 +01:00
|
|
|
{
|
2026-01-18 16:43:23 +01:00
|
|
|
args_buf[i + 5] = dep_flags_buf[i].buf;
|
2026-01-17 18:21:08 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-18 16:43:23 +01:00
|
|
|
args_buf[len_args] = NULL;
|
|
|
|
|
|
|
|
|
|
LOG_DEBUG("Command created, first 4 args: %s %s %s %s %s | total args: %d", args_buf[0], args_buf[1], args_buf[2], args_buf[3], args_buf[4], len_args);
|
|
|
|
|
|
|
|
|
|
return (Command){.a = co->a, .app = co->app, .args = args_buf};
|
2026-01-17 18:21:08 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-18 16:43:23 +01:00
|
|
|
// TODO: Add input sanitization to cmd->app and cmd->args
|
2026-01-17 18:21:08 +01:00
|
|
|
int command_run(Command* cmd)
|
|
|
|
|
{
|
|
|
|
|
assert(cmd != NULL);
|
|
|
|
|
if(cmd->args == NULL) DIE("No arguments were supplied to the command");
|
|
|
|
|
|
|
|
|
|
pid_t pid = fork();
|
|
|
|
|
|
|
|
|
|
if(pid == -1) DIE("fork failed, could not create child process.");
|
|
|
|
|
|
|
|
|
|
if(pid == 0)
|
|
|
|
|
{
|
|
|
|
|
if(execvp(cmd->app.buf, (char*const*)cmd->args) == -1)
|
|
|
|
|
DIE("Failed to launch command: %s.", cmd->app.buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int wstatus = 0;
|
|
|
|
|
if(waitpid(pid, &wstatus, 0) == -1) DIE("wait failed.");
|
|
|
|
|
LOG_DEBUG("Command calling app %s exited with status code %d on child process PID %d.", cmd->app.buf, wstatus, pid);
|
|
|
|
|
return wstatus;
|
|
|
|
|
}
|
|
|
|
|
|