Skip to main content

Module detached

Module detached 

Source
Expand description

Detached spawn of a long-lived background service (daemon, proxy, background Cockpit) so it survives the caller and holds nothing of it.

On Unix a child simply outlives its parent: stdin/stdout are null, stderr is null or a log file, and the service leads its own process group (process_group(0)). Without that it stays in the spawner’s group: a terminal’s Ctrl-C reaches it, and every later CLI call from the same group (a script, CI, an app that spawns both serve --daemon and serve --stop) counts it among its own protected processes, so serve --status called it not running and serve --stop could not verify it.

On Windows a child created through std::process::Command inherits two things a background service must not keep (#2176):

  • Every inheritable handle of the caller. std always passes bInheritHandles = TRUE, so a pipe a shell gave lean-ctx restart (for example cmd’s stdout pipe in cmd /c "lean-ctx restart | findstr .") stays open in the daemon and the reader never sees EOF. The spawn below uses CreateProcessW with PROC_THREAD_ATTRIBUTE_HANDLE_LIST: the child inherits exactly its three std handles (NUL, NUL, NUL or the log file) and nothing else.
  • The caller’s job object. PowerShell’s Start-Process -Wait and AI clients run their children in a job; a service left in it ends with the job or keeps -Wait waiting (GL #545, #2176). In order:
    1. not in a job → a plain detached spawn;
    2. the job allows breakaway → CREATE_BREAKAWAY_FROM_JOB;
    3. the job forbids it (PowerShell’s jobs do: LimitFlags = 0) → the service is created with this user’s Explorer of this session as its parent (PROC_THREAD_ATTRIBUTE_PARENT_PROCESS), the same way a program started from the Start menu runs. Explorer is accepted only when it is %SystemRoot%\explorer.exe, runs as this user in this session and is itself in no job. The service then gets Explorer’s token: an elevated caller starts an unelevated service, which is what the service needs (same user, same data dirs);
    4. no such Explorer (a service session, Server Core) → the service stays in the job, and one stderr line says so instead of a silent hang.

Structs§

DetachedChild
A started background service. Dropping it neither waits for nor ends the service.

Enums§

DetachedStderr
Where a detached service writes its stderr; stdin and stdout are always the null device.

Functions§

spawn_detached
Spawn cmd as a detached background service (see the module docs). Only the program, arguments, environment changes and working directory of cmd are used; its stdio settings are replaced.