Re: [PATCH 2/3] daemon: use sigaction() to install child_handler()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 24, 2025 at 3:29 PM Carlo Marcelo Arenas Belón
<carenas@xxxxxxxxx> wrote:
> I didn'r address it because I didn't knew where to put it, but removing
> the signal handler isn't possible, because as soon as we do, EINTR is no
> longer "returned" by `poll()` on the systems that allowed that as an
> exception to SA_RESTART rules ...

Yes, the signal handling stuff in POSIX is messy for Hysterical Raisins.

If we go back to V6/V7 Unix we only had three options:

 * signal is default-handled, or
 * signal is ignored, or
 * signal is caught: receipt of signal calls user-supplied function.

and the disposition of the signal was always reset to default if
caught, so the user function had to call signal() again. Which was
sort of OK but had the obvious race flaw, if the signal is delivered
twice, before the user function could be re-armed, well, Too Bad.

4.1BSD and 2.9BSD Unix added the "reliable signal" mechanism through a
magic library (-ljobs), with several new system calls internally,
which morphed into the more-standard-ish 4.2BSD `sigvec` system call,
which in turn morphed into the POSIX `sigaction` call. But this still
retained the three basic options: default, ignore, or
catch-at-user-function. So you have to have a function, even if it
doesn't do anything.

Meanwhile System III programmers discovered the problem with
child-is-ready-to-be-reaped signals (SIGCLD in that variant) getting
lost because a SIGCLD handler could not re-catch the signal in time,
and "solved" it by a horrible hack that (they claimed) required no
user intervention. Given that a user program using SIGCLD already had
a handler -- let's call it `child_exited` -- that called
`signal(SIGCLD, child_exited)` somewhere within the handler, the hack
was to have the OS *re-generate* the signal if there was currently a
collectable zombie.

This of course depended strongly on the actual code in `child_exited`,
which *had to* call `wait` once *before* calling `signal` to re-arm
the signal. Otherwise you get infinite recursion. But in fact the
program(s?) that they cared about did call `signal` at the end, rather
than at the start, of their handler(s).

POSIX took `sigvec` and added flags, like `SA_RESTART` and
`SA_RESETHAND`, but otherwise maintained a lot of backwards
compatibility with both schemes by making a lot of behavior optional.
So now you have to over-specify things.

People keep trying to fix the klunky interface over time, but history
is just too messy...

Chris





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux