xtc_osproc(3)

---

xtc_osproc(3)

OS-process spawn, control socket, and lifecycle

XTC_OSPROC(3) Library Functions Manual XTC_OSPROC(3)

xtc_osproc_spawn, xtc_osproc_isolated_spawn, xtc_osproc_pid, xtc_osproc_ctrl_fd, xtc_osproc_signal, xtc_osproc_call, xtc_osproc_serve, xtc_osproc_try_wait, xtc_osproc_wait, xtc_osproc_destroy — OS-process spawn, control socket, and lifecycle

#include <xtc.h>
#include <xtc_osproc.h>

int
xtc_osproc_spawn(const xtc_osproc_opts_t *opts, xtc_osproc_t **out);

int
xtc_osproc_isolated_spawn(const char *name, int (*fn)(int ctrl_fd, void *arg), void *arg, xtc_osproc_t **out);

long
xtc_osproc_pid(const xtc_osproc_t *p);

int
xtc_osproc_ctrl_fd(const xtc_osproc_t *p);

int
xtc_osproc_signal(const xtc_osproc_t *p, int sig);

int
xtc_osproc_call(xtc_osproc_t *p, const void *req, size_t req_len, void **reply, size_t *reply_len, size_t max_reply, int64_t timeout_ns);

int
xtc_osproc_serve(int ctrl_fd, xtc_osproc_handler_fn handler, void *arg);

int
xtc_osproc_try_wait(xtc_osproc_t *p, int *status);

int
xtc_osproc_wait(xtc_osproc_t *p, int *status, int64_t timeout_ns);

void
xtc_osproc_destroy(xtc_osproc_t *p);

These functions run work in a separate operating-system process -- the “default-to-fork” tier -- as opposed to xtc_proc(3), which spawns an in-process fiber. Use this tier for un-cooperative or untrusted work that must not run in a loop thread, and for one-process-per-connection isolation.

() forks a child described by opts. Exactly one of opts->argv (the child execvp(3)s a program) or opts->fn (the child runs (ctrl_fd, arg) and _exit(2)s with its return value) must be set. When opts->ctrl_socket is non-zero an AF_UNIX SOCK_STREAM socketpair is created; the parent end is returned by () (it is O_NONBLOCK and O_CLOEXEC, pollable with xtc_proc(3) or wrappable with xtc_net(3)), and the child end is delivered to a forked callback as its ctrl_fd argument or, for an exec'd program, in the environment variable XTC_CTRL_FD.

() sends sig to the child. () reaps the child without blocking, returning XTC_OK and the raw waitpid(2) status if it has exited or XTC_E_AGAIN if it is still running. () parks the calling fiber until the child exits (or timeout_ns elapses; a negative value waits forever), then reaps it; it never blocks the loop thread. () closes the control socket, releases the handle, and best-effort reaps an already-exited child; it does not kill a still-running child.

() spawns a worker running fn over a control socket, the setup for the request/reply protocol. The parent then ships a framed request with () (which parks for the reply, capped at max_reply bytes, up to timeout_ns), while the child loops in () handling framed requests with its handler until the control socket closes.

On Linux (>= 5.3) a pidfd(2) backs xtc_osproc_wait() so the caller parks on a readable descriptor with no process-wide SIGCHLD handler; elsewhere xtc_osproc_wait() falls back to a cooperative waitpid(2) WNOHANG poll that yields between probes. The library never installs a SIGCHLD handler, so it does not collide with an embedder's signal handling.

An xtc executor is multi-threaded; fork(2) duplicates only the calling thread. The exec path is therefore safe: the parent resolves the program path (the PATH search execvp(3) would do) and formats XTC_CTRL_FD before forking, and the child only closes descriptors and calls execve(2). Releases before 1.50 called setenv(3) and execvp(3) in the child, which could deadlock it if another parent thread held the C library's environment lock at the moment of the fork. A fn (fork-only) callback runs in a half-initialised child and must restrict itself to async-signal-safe work until it re-initialises its own runtime.

xtc_osproc_spawn() returns XTC_OK on success, or XTC_E_INVAL, XTC_E_NOMEM, or XTC_E_INTERNAL. The wait functions return XTC_OK (exited), XTC_E_AGAIN (running or timed out), or a negative error. On a platform without fork(2) (Windows) every function returns XTC_E_NOSYS.

xtc_proc(3), xtc_net(3), xtc_sync(3)

The XTC Project.

June 3, 2026 Debian

View the mdoc source