Use signal to register the signal, which may not interrupt the blocked socket. Please refer to the following code:
/** * Try to reproduce this issue: * Set an alarm before connect() of blocking socket, connect() won't be * interrupted when this alarm is fired. * gcc -o signal signal.c */#include <signal.h>#include <unistd.h>#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/in.h>#include <errno.h>#include <stdarg.h>#include <string.h>#include <stdlib.h>voidsig_handler(int sig){ printf("in signal handler\n");}die(const char *fmt, ...){ char buf[1024] = {0}; va_list va; va_start(va, fmt); vsnprintf(buf, sizeof(buf), fmt, va); va_end(va); fprintf(stderr, "%s\n", buf); exit(1); /* stdlib.h */}intmain(int argc, char **argv){#ifdef USE_SIGACTION struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_handler; if(sigaction(SIGALRM, &sa, NULL) < 0) die("sigaction failed");#else if(SIG_ERR == signal(SIGALRM, sig_handler)) { die("signal failed\n"); }#endif int sock = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in to; memset(&to, 0, sizeof(to)); to.sin_family = AF_INET; if(!inet_aton("192.168.1.254", &to.sin_addr)) { die("convert failed"); } to.sin_port = htons(22322); alarm(2); if(connect(sock, (struct sockaddr*)&to, sizeof(to)) < 0 && errno == EINTR) { close(sock); die("connect() is interrupted"); } return 0;}
Indefinite macro use_sigaction, using signal to register the signal, connect () will never be interrupted.
However, using sigaction to register a signal can interrupt the connect function:
$gcc -o signal signal.c -DUSE_SIGACTION$./signal in signal handlerconnect() is interrupted
My environment:
$gcc --versiongcc (GCC) 4.4.2 20091027 (Red Hat 4.4.2-7)$uname -r2.6.31.5-127.fc12.i686.PAE
Conclusion: Use sigaction to register the signal whenever possible.
There is very little information on the Internet. Refer to the so post:
Http://stackoverflow.com/questions/3582226/recv-is-not-interrupted-by-a-signal-in-multithreaded-environment