Ralph Ronnquist via Dng <dng@???> writes:
> On Sun, Apr 05, 2026 at 01:29:08PM +0100, Rainer Weikusat via Dng wrote:
>> Ralph Ronnquist via Dng <dng@???> writes:
>> > On Sun, Apr 05, 2026 at 12:25:51PM +0100, Rainer Weikusat via Dng wrote:
>> >> Didier Kryn <kryn@???> writes:
>> >> > Le 04/04/2026 à 18:49, Rainer Weikusat via Dng a écrit :
>> >> >> int main(void)
>> >> >> {
>> >> >> extern int wait(int *);
>> >> >> while (1) wait(0);
>> >> >> return 0;
>> >> >> }
>> >> >
>> >> > Well, this is for the second-stage init; but it must also respond
>> >> > to reboot requests and, maybe, monitor at least one getty.
>> >> >
>> >> > And it comes after a first stage which needs to start some daemon
>> >> > launcher. Otherwise it is pointless to reap processes since there
>> >> > arent any (~:
>> >>
>> >> That's what the shell-script was for. At worst, if a shell script cannot
>> >> yet be executed (seems very improbable), one would need to use two
>> >> executable binaries, one which launches the startup script and then
>> >> execs the other which waits for orphaned processes. There's really no
>> >> reason why init should do anything else, this can all be provided by
>> >> other processes/ programs. Poettering is a dolt. Or an early attempt at
>> >> creating an LLM which went really awry.
>> >>
>> >> I might eventually create something that's compatible SysV rc based on
>> >> this idea. On the outset, it looks like an interesting project.
>> >
>> > Well "zombie eating" can also be done in a shell script, so you
>> > wouldn't need much as /init script. Perhaps like so (reflecting a
>> > "normal" idea of use of sysvinit):
>> > ------------------------------
>> > #!/bin/sh
>> > eatzombie() { X=$?; }
>> > trap "eatzombie" CHILD
>> > /etc/init.d/rc S
>> > /etc/init/d/rc 2
>> > ------------------------------
>>
>> This won't work because there's no 1:1 correspondence between SIGCHLDs
>> generated for a process and child processes which exited. It also keeps
>> a shell running all the time which is a pretty complicated program.
>
> You are wrong. Did you test it?
>
> When the zombie process gets reparented to become an init's child,
> init gets a CHILD signal. The zombie process stays zombie until its
> return code is read.
Traditionally, the set of pending signal is bitmask, this means only one
signal of every kind can be pending at the same time. Judging from code
I read yesterday, Linux queues one non-realtime signal but this still
only makes two. Since the issue is timing dependent, some fiddling may
be necessaary to demonstrate the effect, but this program:
----
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
static unsigned signals, pids;
static void reap_children(int)
{
pid_t pid;
++signals;
do {
pid = waitpid(-1, NULL, WNOHANG);
if (pid > 0) ++pids;
} while (pid > 0);
}
static void terminate(int)
{
printf("reaped %u children, got %u signals\n", pids, signals);
exit(1);
}
int main(void)
{
struct sigaction sa;
sigset_t omask;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = reap_children;
sigaction(SIGCHLD, &sa, NULL);
sigaddset(&sa.sa_mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &sa.sa_mask, &omask);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
if (fork() == 0) _exit(0);
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = terminate;
sigaction(SIGALRM, &sa, NULL);
sigprocmask(SIG_SETMASK, &omask, NULL);
alarm(10);
while (1) pause();
return 0;
}
----
always prints that it reaped more children than it got SIGCHLD signals
for me.
>> init will only receive signals it installed handlers for.
> I guess you mean, that like any process, "init" will only handle
> signals that it has handlers for, and ignore those it has blocked.
> A process has no say in which signals it receives.
There's code in the kernel special-casing this for init.