Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku <643-408-1753@kylheku.com> Newsgroups: comp.unix.shell Subject: Re: (bash) How (really!) does the "current job" get determined? Date: Tue, 8 Oct 2024 17:37:20 -0000 (UTC) Organization: A noiseless patient Spider Lines: 69 Message-ID: <20241008101759.180@kylheku.com> References: <20241003170607.397@kylheku.com> <20241004070133.515@kylheku.com> Injection-Date: Tue, 08 Oct 2024 19:37:20 +0200 (CEST) Injection-Info: dont-email.me; posting-host="803b188bb69054d691f903fac8e36e85"; logging-data="2386758"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+sFCKrE4eAVebgmQvfp2gFm7dUNsIxtDk=" User-Agent: slrn/pre1.0.4-9 (Linux) Cancel-Lock: sha1:byPe0mD2kEantTRau4uZfhtyQuo= Bytes: 4376 On 2024-10-04, Christian Weisgerber wrote: > What happens if the background job has already terminated on its > own accord before we reach the kill(1)? Not much, because with job > control, the shell knows that no such job exists. In Unix, when a child process terminates, it does not go away. The parent process has to call one of the wait functions like waitpid in order to "reap" that process. It can be notified of children in this state asynchronously via the SIGCHLD signal. The problem of PIDs suddenly disappearing and being recycled behind the parent process' back does not exist in the operating system. We can imagine a shell which does nothing when a child coprocess launched with & terminates spontaneously, so that the script /must/ use the wait command. In that shell, the process ID of that child will remain reliably available until that wait. Only if the shell reaps terminated coprocesses behind the script's back, so to speak, do you have the reuse problem. What does POSIX say? Something between those two alternatives: When an element of an asynchronous list (the portion of the list ended by an , such as command1, above) is started by the shell, the process ID of the last command in the asynchronous list element shall become known in the current shell execution environment; see Shell Execution Environment. This process ID shall remain known until: The command terminates and the application waits for the process ID. Another asynchronous list is invoked before "$!" (corresponding to the previous asynchronous list) is expanded in the current execution environment. The implementation need not retain more than the {CHILD_MAX} most recent entries in its list of known process IDs in the current shell execution environment. It's seems as if what POSIX is saying is that scripts which fire off asynchronous jobs one after another receive automatic clean up. A script which does not refer to the $! variable from one ampersand job, before firing off more ampersand jobs, will not clog the system with uncollected zombie processes. But a script which does reference $! after launching an ampersand job (before launching another one) will not have that process cleaned up behind its back: it takes on the responsibility for doing the wait which recycles the PID. Anyway, that's what I'd like to believe that the quoted passage means. > If you do this > with "kill $!", you signal that PID, which no longer refers to the > intended process and may in fact have been reused for a different > process. At the system call level, that's not what kill means. It means to pass a certain signal (fatal or not, catchable or not) to the process. Even if the signal is uncatchable and fatal, kill deos not mean "make the target process disappear, so that its PID may be reused". The waitpid system call will do that (in the situation when the process is a zombie, and so subsequently the returned status indicates that it exited, and with what exit code or on what signal). -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca