From Bugzilla Helper: User-Agent: Mozilla/4.78 [en] (X11; U; Linux 2.4.3-12 i586) Description of problem: If you try to set up a signal handler for the real-time signals (SIGRTMIN+x), sigaction will fail with error code "Invalid argument" if the program was linked with librt. If you don't link with librt, the call succeeds (but you can't call any POSIX.4 timer functions, or the program won't even link). Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: 1. Create the following file: cat > sigaction_error.c << EOF #include <signal.h> #include <stdio.h> void catch_signal (int signum) { return; } int main () { struct sigaction handler; int status; handler.sa_handler = catch_signal; sigemptyset (&handler.sa_mask); handler.sa_flags = SA_RESTART; status = sigaction (SIGRTMIN, &handler, NULL); if (status) perror ("sigaction(SIGRTMIN)"); else puts ("SIGRTMIN signal handler successfully installed."); return status; } EOF 2. Compile as follows: gcc -g -lrt -o sigaction_error sigaction_error.c 3. Run. Actual Results: sigaction(SIGRTMIN): Invalid argument Expected Results: 2b. Compile as follows: gcc -g -o sigaction_error sigaction_error.c 3. Run. SIGRTMIN signal handler successfully installed. Additional info: I thought the error might have occurred because I was installing a regular one-argument signal handler instead of the newer three-argument version, even though the POSIX standard does not impose such a restriction. However, adding the flag SA_SIGINFO does not alter the results.
The thing is that -lpthread (which -lrt uses because kernel lacks native aio support) uses SIGRTMIN..SIGRTMIN+2 for thread bookkeeping, so you obviously cannot use already used signals. I don't think any standard requires full range of SIGRTMIN..SIGRTMAX to be available for the application's use.
I disagree. The very rationale for the existence of SIGRTMIN through SIGRTMAX was to have a larger set of signals for application use. I don't have the 1993 (94?) version of the POSIX.4 standard, but I do have two other standards for reference: In the Single Unix Specification Version 2 ("UNIX98"), under <signal.h>: "This header also declares the macros SIGRTMIN and SIGRTMAX, which evaluate to integral expressions and, if the Realtime Signals Extension option is supported, specify a range of signal numbers that are reserved for application use and for which the realtime signal behaviour specified in this specification is supported. The signal numbers in this range do not overlap any of the signals specified in the following table. "The range SIGRTMIN through SIGRTMAX inclusive includes at least RTSIG_MAX signal numbers." And in the April 2001 draft of POSIX (p1003.1-200x), again under <signal.h>: "This header shall also declare the macros SIGRTMIN and SIGRTMAX, which evaluate to integer expressions, and specify a range of signal numbers that are reserved for application use and for which the realtime signal behavior specified in this volume of IEEE Std 1003.1-200x is supported. The signal numbers in this range do not overlap any of the signals specified in the following table. "The range SIGRTMIN through SIGRTMAX inclusive shall include at least {RTSIG_MAX} signal numbers." If the system needs additional signals for its own purposes, fine; you can define a set of implementation-defined signals. But don't use the signals that are reserved for application use. Instead, you could simply adjust the values of SIGRTMIN and/or SIGRTMAX so that there is no conflict. As long as there are still at least 8 values from SIGRTMIN to SIGRTMAX, that will satisfy the standard. And remember that SIGRTMIN is evaluated at run-time, not compile-time, so its value can change according to the system's needs. Isn't that why you have it defined as a function call?
I'll talk with Ulrich what can be done about this. The issue is that as -lpthread is only DT_NEEDED of -lrt, not anything else, -lc comes earlier in search scope than -lpthread and thus __libc_current_sigrtmin is used from -lc, not -lpthread. One solution would be using GROUP ( /lib/librt.so.1 /lib/libpthread.so.0 ) as /usr/lib/librt.so, another having a copy of allocrtsig.c in linuxthreads which would make glibc examine some pthread weak symbol and adjust if pthread was found, another have a separate __libc_current_sigrtmin in -lrt which would transfer control to -lpthread's __libc_current_sigrtmin.
Actually, it is fixed in yet different way. librt.so.* has DT_FILTER libpthread.so.0 (in GNU DT_FILTER semantics), meaning libpthread.so.0 will come earlier than librt.so.1 in search path (which means earlier than libc.so.6 too).
As GLIBC DT_FILTER semantics is horribly broken, Ulrich decided a librt.so linker script is the way to go for now. It should be fixed in 2.2.4-19.