:: Re: [DNG] Good thing we don't use s…
Top Page
Delete this message
Reply to this message
Author: Rainer Weikusat
Date:  
To: dng
Subject: Re: [DNG] Good thing we don't use systemd
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.