Supported OS-owned lifetime for one-shot macOS work after its controller exits

I’m designing a macOS utility that needs to run a bounded, one-shot diagnostic and collect its result.

The lifetime problem is:

  1. A controller asks for the diagnostic to start.
  2. The diagnostic may begin successfully.
  3. The controller can then fail immediately — potentially before it has retained the child’s PID or established output collection.
  4. The diagnostic may close stdin/stdout/stderr while continuing to run.
  5. The diagnostic must not become an unmanaged orphan if the controller disappears.

A focused test case uses Foundation.Process:

  • Controller launches Child.
  • Controller immediately exits with _exit(42), without waiting for Child or retaining its process identifier.
  • Child calls setsid(), closes stdin/stdout/stderr, stays alive for up to 120 seconds, then exits.

What I’m trying to establish is the supported macOS lifecycle boundary, rather than inventing a cleanup scheme around PIDs.

Is there a supported per-user launchd or other OS-managed mechanism where the OS assumes responsibility for the job before the diagnostic process can start, such that the requesting controller may subsequently fail without leaving an unmanaged process?

Specifically:

  • At what point does the OS own the lifetime relative to registration and process creation?
  • What supported mechanism bounds or terminates the job if the requesting controller disappears?
  • Is there a supported hard execution-time limit, rather than an idle-time concept?
  • How are descendants or process groups contained, and does calling setsid() conflict with that containment?
  • What completion or failure information remains available to a later controller after the original requester has died?
  • Are there important per-user, privilege, sandboxing, signing, or macOS-version limitations?

I’m not reporting an Apple bug and I’m not asking for a custom recovery implementation. I’m trying to identify the documented supported lifetime mechanism and its guarantees and limitations before choosing an architecture.

Environment:

  • macOS 26.6.2
  • Apple silicon
  • Foundation.Process is used by the focused reproducer

Apple Developer Technical Support suggested I start a new thread for this specific question in Processes & Concurrency.

Thanks for bringing this to the forums.

I read through your post a couple of times and I’m still not sure I understand your issue. Most folks in your situation simply spawn the child process (via fork/exec*, posix_spawn, NSTask, Process, or Subprocess). Then one of two things happens:

  • If the child terminates first, the parent reaps it.
  • If the parent terminates first, the child gets reparented but that’s fine because eventually the child will terminate.

It sounds like you’re concerned about the parent terminating and then the child getting stuck, resulting in no one being around to clean up. Is that right? Or have I misunderstood something?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Supported OS-owned lifetime for one-shot macOS work after its controller exits
 
 
Q