xtc_osproc(3)
---xtc_osproc(3)
OS-process spawn, control socket, and lifecycle
| XTC_OSPROC(3) | Library Functions Manual | XTC_OSPROC(3) |
NAME
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
SYNOPSIS
#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);
DESCRIPTION
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.
xtc_osproc_spawn()
forks a child described by opts. Exactly one of
opts->argv (the child execvp(3)s
a program) or opts->fn (the child runs
fn(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
xtc_osproc_ctrl_fd()
(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.
xtc_osproc_signal()
sends sig to the child.
xtc_osproc_try_wait()
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.
xtc_osproc_wait()
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.
xtc_osproc_destroy()
closes the control socket, releases the handle, and best-effort reaps an
already-exited child; it does not kill a still-running child.
xtc_osproc_isolated_spawn()
spawns a worker running fn over a control socket, the
setup for the request/reply protocol. The parent then ships a framed request
with
xtc_osproc_call()
(which parks for the reply, capped at max_reply
bytes, up to timeout_ns),
while the child loops in
xtc_osproc_serve()
handling framed requests with its handler until the
control socket closes.
IMPLEMENTATION NOTES
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.
RETURN VALUES
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.
SEE ALSO
AUTHORS
The XTC Project.
| June 3, 2026 | Debian |