#ifndef CST_OS_COMPAT_H #define CST_OS_COMPAT_H #include #include #ifdef __cplusplus extern "C" { #endif #ifndef OS_PATH_MAX #define OS_PATH_MAX 4096 #endif /* --- path --- */ int os_path_is_abs(const char *p); /* Join with native separator; out always uses '/' on Unix and '\\' on Win for * the joiner, but os_path_norm_slashes converts to '/' for comparisons. */ int os_path_join(char *out, size_t out_sz, const char *a, const char *b); void os_path_norm_slashes(char *p); int os_realpath(const char *path, char *out, size_t out_sz); /* True if path is under root (after realpath/norm). Trailing slash rules apply. */ int os_path_under(const char *root, const char *path); /* --- dirs / config --- */ int os_mkdir(const char *path, int mode); int os_mkdir_p(const char *path, int mode); int os_config_dir(char *out, size_t out_sz); int os_temp_dir(char *out, size_t out_sz); /* Create unique temp file; writes path into out; returns fd or -1. Caller closes. */ int os_mkstemp(char *out, size_t out_sz, const char *prefix); /* Directory containing the running executable (for bundled busybox). * Call os_set_prog_path(argv[0]) early on Unix/Termux as fallback. */ void os_set_prog_path(const char *argv0); int os_exe_dir(char *out, size_t out_sz); /* Resolve shell interpreter path into out. * Order: CST_SHELL → /busybox[.exe] → /bin/sh (Unix). */ int os_resolve_shell(char *out, size_t out_sz); /* --- process --- */ typedef struct { char *out; size_t out_len; int exit_code; } os_run_result_t; void os_run_result_free(os_run_result_t *r); /* Run argv[0..] (NULL-terminated) with cwd; capture stdout+stderr. * max_out caps captured bytes (0 = default 512KiB). */ int os_run_capture(const char *cwd, const char *const argv[], size_t max_out, os_run_result_t *r); /* Convenience: shell -c cmd via os_resolve_shell. */ int os_run_shell_c(const char *cwd, const char *cmd, size_t max_out, os_run_result_t *r); /* Child processes get stdin=/dev/null, their own process group, and are * killed after the timeout (CST_SHELL_TIMEOUT seconds, default 120) or when * *flag becomes non-zero. Exit code 124 = timeout, 130 = cancelled. */ void os_set_cancel_flag(volatile int *flag); void os_set_run_timeout(int seconds); /* Monotonic milliseconds (arbitrary epoch). */ double os_now_ms(void); /* --- misc --- */ void os_localtime(const time_t *t, struct tm *out); int os_getpid(void); int os_chmod_private(const char *path); /* best-effort 0600; no-op/ok on Win */ #ifdef __cplusplus } #endif #endif /* CST_OS_COMPAT_H */