In the following program, if I uncomment _XOPEN_SOURCE line, my program terminates when I hit C-c, same program doesn’t terminate If I don’t comment that line. Anyone knows in what ways does _XOPEN_SOURCE affect signal handling? I am on linux with gcc (4.6.3) and glibc (2.15).
/* #define _XOPEN_SOURCE 700 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
typedef void (*sighandler_t)(int);
void handle_signal(int signo)
{
printf("\n[MY_SHELL] ");
fflush(stdout);
}
int main()
{
int c;
signal(SIGINT, SIG_IGN);
signal(SIGINT, handle_signal);
printf("[MY_SHELL] ");
while ((c = getchar()) != EOF) {
if (c == '\n')
printf("[MY_SHELL] ");
}
printf("\n");
return 0;
}
The problem is that the
signal()function can have two different forms of behaviour when installing a signal handling function:SIG_DFL– and system calls that are interrupted by the signal are not restarted; orOn Linux with glibc, you get the BSD semantics if
_BSD_SOURCEis defined, and the System V semantics if it is not. The_BSD_SOURCEmacro is defined by default, but this default definition is suppressed if you define_XOPEN_SOURCE(or a few other macros too, like_POSIX_SOURCEand_SVID_SOURCE).Under System V semantics, if the
read()system call underlyinggetchar()is interrupted bySIGINTthengetchar()will returnEOFwitherrnoset toEINTR(this will cause your program to exit normally). In addition, after the firstSIGINTthe disposition of this signal is reset to the default, and the default action forSIGINTis to terminate the process (so even if your program survived the firstSIGINT, the second would cause it to exit abnormally).The solution is not to use
signal()at all for installing signal-handling functions; instead, you should usesigaction(), which is portable – it gives the same semantics everywhere. Withsa_flagsset toSA_RESTART,sigaction()it will give the BSD semantics, which is what you want.