I am having trouble trying to handle a signal…
I have a multithreaded application, which receives a signal that interrupts system calls in a library that I am using. After some research, I found that if a signal is not handled, it gets sent to a random thread in the application. I have confirmed from the library I am using that they are not using any signals in their application. Neither am I. Here is my main driver class:
void sig_handler(int signum)
{
cout << "Signal Handle: " << signum << endl;
signal(signum, SIG_IGN);
}
class Driver
{
public:
Driver();
void LaunchLog();
void logonListen();
};
Driver::Driver()
{
pthread_t logThread;
pthread_create(&logThread, NULL, LaunchLogThread, (void*) this);
pthread_detach(logThread);
pthread_t listenThread;
pthread_create(&listenThread, NULL, LaunchListenThread, (void*)this);
pthread_detach(listenThread);
bool running = true;
while(running)
{
//Simple loop to resemble a menu for the console
}
}
void Driver::logonListen()
{
char buffer[256];
int logonPort = BASEPORT;
int sockfd;
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen;
//initialize socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd < 0){
perror("Error opening socket");
exit(1);
}
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(logonPort);
//bind socket to our address
if(bind(sockfd,(struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
{
perror("Error on bind");
exit(1);
}
clilen = sizeof(struct sockaddr_in);
int n;
int nextUser = 2;
char reply[32];
while(1)
{
//Wait for incoming connection on a socket
}
}
void Driver::LaunchLog()
{
Logger::Instance()->WriteToFile();
}
void* LaunchListenThread(void* ptr)
{
Driver* driver = (Driver*) ptr;
driver->logonListen();
}
int main()
{
signal (SIGHUP, sig_handler);
signal (SIGINT, sig_handler);
signal (SIGQUIT, sig_handler);
signal (SIGILL, sig_handler);
signal (SIGTRAP, sig_handler);
signal (SIGFPE, sig_handler);
signal (SIGKILL, sig_handler);
signal (SIGUSR1, sig_handler);
signal (SIGSEGV, sig_handler);
signal (SIGUSR2, sig_handler);
signal (SIGPIPE, sig_handler);
signal (SIGALRM, sig_handler);
signal (SIGTERM, sig_handler);
signal (SIGCHLD, sig_handler);
signal (SIGCONT, sig_handler);
signal (SIGSTOP, sig_handler);
signal (SIGTSTP, sig_handler);
signal (SIGTTIN, sig_handler);
signal (SIGTTOU, sig_handler);
signal (SIGABRT, sig_handler);
Driver driver;
return 0;
}
I am unable to handle the signals. Interrupted System Calls keep creeping up, and my signal handler never gets used. Even when I press CTRL+C in the console, the program ends with interruption rather than SIGINT being handled. Am I installing the handler incorrectly?
Is there a way to handle all signals and to ignore them if they arise?
Thanks
You want to use sigaction(2) with the SA_RESTART flag to ignore the signals and insure that system calls get restarted instead of interrupted:
Note that you might not want to ignore things like SIGINT as you then won’t be able to stop you program with ctrl-C. Likewise, ignoring SIGSEGV may cause your program to hang if it contains a bug, rather than exiting.
edit
Your description that neither you nor the library is using any signals doesn’t quite ring true — the signals are coming from SOMEWHERE, and it may just be a case that you don’t realize something you are doing is using signals under the hood. If you’re using any alarms or itimers anywhere, those involve signals. If your sig_handler is truly not being called, that implies that someone else (your library?) is installing a signal handler to replace it.
If you still can’t figure out where the signals are coming from, you can run under a debugger, and enable the debugger’s signal debugging ability (if needed). That should at least tell you which signals are occurring, and where they are occurring.
In general, with any system call, you should ALWAYS check for errors, and if you see the error EINTR unexpectedly, you should probably just loop and redo the system call.