Eric Blake wrote: > | POSIX is not correct about the type of SIG_DFL and SIG_IGN: > | In <http://www.opengroup.org/susv3/basedefs/signal.h.html> it says > | "... constants, each of which expands to a distinct constant expression > of > | the type void (*)(int) ...: SIG_DFL SIG_IGN" > | but also > | "void (*)(int, siginfo_t *, void *) sa_sigaction > | Pointer to signal handler function or one of the macros SIG_IGN or > SIG_DFL." > | But sa_sigaction cannot be SIG_IGN or SIG_DFL because they are of different > | types! > > I think you misquoted that. In both 2001 (you gave the URL) and draft 5.1 > of 200x, the description of struct sigaction only mention SIG_IGN and > SIG_DFL in relation to sa_handler, while the test for sa_sigaction states > only "Pointer to a signal-catching function".
You're right here. I was looking at an older copy of the same URL. They now fixed it. So, SIG_IGN and SIG_DFL can *only* be used in sa_handler. > | What if someone actually installs a handler with SA_SIGINFO and SIG_IGN? > > In theory, they can't, since SIG_IGN is typed differently than > sa_sigaction, but sa_sigaction is the only field that can be used when > SA_SIGINFO is set. There is no statement which fields of the struct a programmer may use or not. (Actually when a programmer copies a 'struct sigaction' he copies all fields.) The paragraph that applies is (from the sigaction description): "If the SA_SIGINFO flag (see below) is cleared in the sa_flags field of the sigaction structure, the sa_handler field identifies the action to be associated with the specified signal. If the SA_SIGINFO flag is set in the sa_flags field, the sa_sigaction field specifies a signal-catching function." So yes, SIG_IGN with SA_SIGINFO is not allowed by POSIX. In theory. Because in practice, on Linux, the program -------------------------------------------------------------- #include <signal.h> #include <stdio.h> int main () { struct sigaction s; s.sa_handler = SIG_IGN; s.sa_flags = SA_SIGINFO; int ret = sigaction (SIGINT, &s, NULL); printf ("ret = %d\n", ret); for (;;) ; } --------------------------------------------------------------- prints "ret = 0" and then is not interruptible by Ctrl-C. So, Linux has ignored the SA_SIGINFO flag here. And this is why in fatal-signal.c I test for SIG_IGN *regardless* of the SA_SIGINFO flag. > gcc's abort() is acceptable if the user attempted to invoke the function > via the wrong type, but NOT on just casting it. Yes. gcc's abort() comes in situations like this where a known external function is casted and then immediately called: extern double sin (double x); long double x = ((long double (*) (long double)) sin) (0L); > Does anyone know of a system where sa_handler and sa_sigaction do not > overlap, or where the kernel sets a signal handler to SIG_DFL or SIG_IGN > but accidentally sets the SA_SIGINFO flag in the return parameter of > sigaction? The include files of all systems that I have access to contain sa_handler and sa_sigaction as elements of the same union, i.e. they overlap. Only Interix 3.5 has a struct sigaction that lacks the 'sa_sigaction' member. But don't waste your time on that system, it's not worth porting to. Bruno 2008-06-18 Bruno Haible <[EMAIL PROTECTED]> * lib/fatal-signal.c (init_fatal_signals): Add comment. Reported by Eric Blake. *** lib/fatal-signal.c.orig 2008-06-19 03:33:07.000000000 +0200 --- lib/fatal-signal.c 2008-06-19 03:32:28.000000000 +0200 *************** *** 96,101 **** --- 96,105 ---- struct sigaction action; if (sigaction (fatal_signals[i], NULL, &action) >= 0 + /* POSIX says that SIG_IGN can only occur when action.sa_flags + does not contain SA_SIGINFO. But in Linux 2.4, for example, + SA_SIGINFO can actually be set and is ignored when sa_handler + is SIG_IGN. So don't bother testing for SA_SIGINFO. */ && action.sa_handler == SIG_IGN) fatal_signals[i] = -1; }