From e3ab29bb4d7174cae65de2275f19105eb3d93d91 Mon Sep 17 00:00:00 2001 From: Zuhaitz Méndez Fernández de Aránguiz Date: Sun, 25 Jan 2026 18:24:05 +0000 Subject: APE shall never kill APE --- ape/boot/boot.zc | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 ape/boot/boot.zc (limited to 'ape/boot/boot.zc') diff --git a/ape/boot/boot.zc b/ape/boot/boot.zc new file mode 100644 index 0000000..176f668 --- /dev/null +++ b/ape/boot/boot.zc @@ -0,0 +1,118 @@ +#define _COSMO_SOURCE +#include +#include +#include + +raw { + extern char **environ; +} + +fn normalize_wait(ws: int) -> int { + if ws == -1 { return -1 } + if WIFEXITED(ws) { return WEXITSTATUS(ws) } + if WIFSIGNALED(ws) { return 128 + WTERMSIG(ws) } + return -1; +} + +fn run_exec(argv: char**) -> int { + fflush(NULL); + let ws: int = systemvpe(argv[0], argv, environ); + return normalize_wait(ws); +} + +fn needs_quote(s: char*) -> bool { + for (let p = s; *p; ++p) { + if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '"' || *p == '\'' ) + return true; + } + return false; +} + +fn print_quoted(s: char*) { + if !needs_quote(s) { + print f"{s}"; + return; + } + + print f"'"; + for (let p = s; *p; ++p) { + if (*p == '\'') { + print f"'\"'\"'"; + } else { + print f"{*p:c}"; + } + } + print f"'"; +} + +fn log_cmd(argv: char**) { + print f"$ "; + let i = 0; + while argv[i] != NULL { + if i { print f" " } + print_quoted(argv[i]); + i++; + } + print f"\n"; +} + +fn main(argc: int, argv: string*) { + def delim = "::"; + + let newargc: int = cosmo_args("/zip/.args", &argv); + if newargc != -1 { argc = newargc } + + let i = 1; + while i < argc && strcmp(argv[i], delim) { i++ } + + while i < argc { + if strcmp(argv[i], delim) { + f"Expected '{delim}' before each command, got: {argv[i]}"; + return 2; + } + i++; + + let start = i; + while i < argc && strcmp(argv[i], delim) { i++ } + let cmd_argc = i - start; + + if cmd_argc <= 0 { + f"Empty command after '{delim}'"; + return 2; + } + + let rc = 0; + + if !strcmp(argv[start], "system") { + if cmd_argc != 3 { + !"error: system expects 2 arguments, got {cmd_argc}"; + return -4; + } + + if strcmp(argv[start + 1], "-c") { + !"error: system got '{argv[start + 1]}' instead of -c"; + return -5; + } + + "$ {argv[start + 2]}"; + rc = normalize_wait(system(argv[start + 2])); + + if rc { return rc } + + continue; + } + + autofree let cmdv = (char**)malloc((cmd_argc + 1) * sizeof(char*)); + if !cmdv { return 1 } + for (let k = 0; k < cmd_argc; k++) { cmdv[k] = argv[start + k] } + cmdv[cmd_argc] = NULL; + + log_cmd(cmdv); + + rc = run_exec(cmdv); + + if rc { return rc } + } + + return 0; +} -- cgit v1.2.3