Files
CST-agent/include/os_compat.h
T

130 lines
4.9 KiB
C

#ifndef CST_OS_COMPAT_H
#define CST_OS_COMPAT_H
#include <stddef.h>
#include <time.h>
#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 → <exe_dir>/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);
/* Same, with child_hook(ud) run in the child just before exec (Unix only;
* ignored on Windows). A non-zero return aborts the child with exit 126. */
typedef int (*os_child_hook_fn)(void *ud);
int os_run_capture_ex(const char *cwd, const char *const argv[],
size_t max_out, os_run_result_t *r,
os_child_hook_fn child_hook, void *ud);
int os_run_shell_ex(const char *cwd, const char *cmd, size_t max_out,
os_run_result_t *r, os_child_hook_fn child_hook,
void *ud);
/* 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);
volatile int *os_get_cancel_flag(void);
void os_set_run_timeout(int seconds); /* this thread; 0 = default */
int os_get_run_timeout(void);
/* Long-lived child with pipes on stdin/stdout (MCP servers). stderr goes
* to stderr_path (NULL = discarded). env_add: "KEY=VALUE" entries added to
* the inherited environment (NULL-terminated, may be NULL). */
typedef struct {
#ifdef _WIN32
void *proc, *in_w, *out_r;
#else
int pid, in_fd, out_fd;
#endif
} os_proc_t;
int os_proc_spawn(const char *cwd, const char *const argv[],
const char *const env_add[], const char *stderr_path,
os_proc_t *p);
int os_proc_write(os_proc_t *p, const char *data, size_t n); /* 0 / -1 */
/* Bytes read, 0 at EOF, -1 on error, -2 when nothing came within
* timeout_ms. */
long os_proc_read(os_proc_t *p, char *buf, size_t n, int timeout_ms);
void os_proc_close_stdin(os_proc_t *p);
/* Close the pipes, end the process (group) and reap it. */
void os_proc_kill(os_proc_t *p);
/* This thread's cancel flag (os_set_cancel_flag) is raised. */
int os_cancel_requested(void);
/* Run fn(args[i]) for every i on its own thread and wait for all of them
* (falls back to running inline when a thread cannot start). */
typedef void (*os_task_fn)(void *arg);
void os_run_parallel(os_task_fn fn, void *const args[], int n);
/* 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 */
/* --- libc gaps on Windows ------------------------------------------------
* MinGW-w64 provides neither strcasestr() (a GNU extension) nor
* setenv()/unsetenv() (POSIX): they are simply absent from its headers.
* src/tui.c uses all three. Implemented in os_compat.c for _WIN32 only,
* so the Unix builds keep using the libc versions. */
#if defined(_WIN32)
char *strcasestr(const char *haystack, const char *needle);
int setenv(const char *name, const char *value, int overwrite);
int unsetenv(const char *name);
#endif
#ifdef __cplusplus
}
#endif
#endif /* CST_OS_COMPAT_H */