You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9c5c71c
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/api.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1183,7 +1183,7 @@ This is useful when the subprocess spawns its own processes, such as when using
1183
1183
1184
1184
On Unix, this spawns the subprocess in its own [process group](https://en.wikipedia.org/wiki/Process_group). On Windows, this uses [`taskkill`](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill).
1185
1185
1186
-
This is best-effort: descendant processes that create their own process group or session are not terminated.
1186
+
This is best-effort: descendant processes that create their own process group or session are not terminated. Also, descendants are not terminated once Execa is done with the subprocess, or on Windows once the subprocess exited, since its PID might then belong to an unrelated process.
Copy file name to clipboardExpand all lines: docs/termination.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -209,7 +209,7 @@ await subprocess;
209
209
210
210
On Unix, this spawns the subprocess in its own [process group](https://en.wikipedia.org/wiki/Process_group), then sends the signal to that group. On Windows, this uses [`taskkill`](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill), which terminates the process tree tracked by the OS.
211
211
212
-
This is best-effort. On Unix, descendant processes that create their own process group or session (for example, daemons calling [`setsid()`](https://man7.org/linux/man-pages/man2/setsid.2.html)) escape termination. On Unix, because the subprocess runs in its own process group, it is also detached from the terminal, so pressing `CTRL-C` no longer forwards [`SIGINT`](#sigint) to it.
212
+
This is best-effort. On Unix, descendant processes that create their own process group or session (for example, daemons calling [`setsid()`](https://man7.org/linux/man-pages/man2/setsid.2.html)) escape termination. On Unix, because the subprocess runs in its own process group, it is also detached from the terminal, so pressing `CTRL-C` no longer forwards [`SIGINT`](#sigint) to it. Finally, the OS can re-assign the subprocess' PID to an unrelated process once it exited. So, descendants are not signaled anymore once Execa is done with the subprocess, i.e. once its promise has settled. On Windows, this applies as soon as the subprocess exited, which also prevents the [`forceKillAfterDelay`](#forceful-termination) escalation from terminating its descendants.
213
213
214
214
This option cannot be used with [synchronous methods](execution.md#synchronous-execution).
Unlike `subprocess.kill()`, signaling a process group or a process tree uses the PID directly, without going through the subprocess' handle. The OS can re-assign that PID once the tree is gone, and signaling it then would terminate an unrelated process, and on Windows its own descendants too.
36
+
On Unix, a PID stays reserved as long as it is the process group ID of a running process, so it can only be re-assigned once every descendant exited too. While Execa is still waiting on the subprocess, the signal is still useful, e.g. for the `forceKillAfterDelay` escalation, which happens after the subprocess exited but while a descendant might still be running. Once Execa is done with the subprocess, no internal logic sends signals anymore, so only `subprocess.kill()` can. Like `ChildProcess.kill()`, it then becomes a noop returning `false`. This narrows the window during which a re-assigned PID could be signaled, without removing it, e.g. when Execa is still waiting on a slow transform after the whole process group exited.
37
+
On Windows, there are no process groups: a PID is only reserved while a handle to the process is open, which Node.js closes once the subprocess exits. `taskkill /T` also cannot find the descendants of a process which exited. So the process tree is never signaled once the subprocess exited.
test.serial('killDescendants does not signal the process group once Execa is done with the subprocess',testAbandonedProcessGroup,()=>execa('fail.js',{killDescendants: true}));
135
+
136
+
test.serial('killDescendants does not signal the process group once Execa is done with a terminated subprocess',testAbandonedProcessGroup,()=>{
Copy file name to clipboardExpand all lines: types/arguments/options.d.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -340,7 +340,7 @@ export type CommonOptions<
340
340
341
341
On Unix, this spawns the subprocess in its own [process group](https://en.wikipedia.org/wiki/Process_group). On Windows, this uses [`taskkill`](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill).
342
342
343
-
This is best-effort: descendant processes that create their own process group or session are not terminated.
343
+
This is best-effort: descendant processes that create their own process group or session are not terminated. Also, descendants are not terminated once Execa is done with the subprocess, or on Windows once the subprocess exited, since its PID might then belong to an unrelated process.
0 commit comments