Bug 228728 - sh does not reap killed background processes until terminal activity, creating zombies
Summary: sh does not reap killed background processes until terminal activity, creatin...
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Many People
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-06-03 20:13 UTC by Mahmoud Al-Qudsi
Modified: 2018-06-06 01:05 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mahmoud Al-Qudsi 2018-06-03 20:13:24 UTC
The default `sh` shell does not reap backgrounded processes if sitting idle, and killed backgrounded processes are not reaped until a new command is executed or enter is pressed at the tty.

For example, 

```
$ cat
<CTRL-Z>
[1] + Suspended                     cat
$ 
```

Now in another terminal or in an SSH session:

```
$ killall -9 cat
```

The PID associated with cat is turned into a zombie as the shell does not reap the killed instance. The only way to trigger reaping would be to attach to the tty session where the process was initially backgrounded and hit <ENTER>:


```
$ cat
# resuming from first segment above 
$ <ENTER>
[1] Killed                          cat
$ 
```


Solution: `waitpid(2)` should be used to asynchronously detect the exit of backgrounded child processes.
Comment 1 Jilles Tjoelker freebsd_committer 2018-06-03 21:57:06 UTC
If this is to be fixed, waitpid() alone does not suffice, since it does not let you wait for either terminal input or a process termination. It is necessary to have a SIGCHLD signal handler (either directly or via pselect(2)).

Due to limitations in libedit's API, the signal handler could not do much more than reap the zombie and register this in the struct job. This does not help much except system administrators that insist on zombies being reaped quickly. Things like a proper 'set -b' (notify about job state at any time) would require some way to execute a handler function in a defined environment and to redraw the pending input.