| 291 | } |
| 292 | |
| 293 | static int spawn_ignoring_tree(const char *pid_path, int quiet_timeout_ms, int cancel_grace_ms, |
| 294 | cbm_subprocess_t **out) { |
| 295 | /* The direct child installs its trap before starting a nested shell. The two |
| 296 | * PIDs are written only after the nested process exists, eliminating the |
| 297 | * cancellation-before-trap race from the test. */ |
| 298 | const char *script = "trap '' TERM; " |
| 299 | "/bin/sh -c 'trap \"\" TERM; while :; do sleep 1; done' cbm-grandchild & " |
| 300 | "grandchild=$!; echo \"$$ $grandchild\" > \"$1\"; wait"; |
| 301 | const char *argv[] = {"/bin/sh", "-c", script, "cbm-parent", pid_path, NULL}; |
| 302 | cbm_proc_opts_t opts = {0}; |
| 303 | opts.bin = "/bin/sh"; |
| 304 | opts.argv = argv; |
| 305 | opts.quiet_timeout_ms = quiet_timeout_ms; |
| 306 | opts.cancel_grace_ms = cancel_grace_ms; |
| 307 | return cbm_subprocess_spawn(&opts, out); |
| 308 | } |
| 309 | |
| 310 | typedef struct { |
| 311 | cbm_subprocess_t *process; |
no test coverage detected