Results 1 to 3 of 3
Hello everyone,
I was wondering if anyone knows of a way to get a process to stopping blocking on a read() or similar call. Here's my example:
Code:
#include <signal.h>
...
- 11-22-2007 #1
Interrupting a blocking read()
Hello everyone,
I was wondering if anyone knows of a way to get a process to stopping blocking on a read() or similar call. Here's my example:
What I'd like to do is once the alarm triggers and alarm_handler returns, getchar() proceeds and the program terminates normally. The reason I want to do this is because I'm writing a program that blocks a good deal of the time, and I'd like to respond to SIGALRM and clean up on SIGTERM. Any advice would be greatly appreciated.Code:#include <signal.h> #include <stdio.h> #include <unistd.h> void alarm_handler(int sig) { printf("Signal!\n"); } int main(void) { signal(SIGALRM, alarm_handler); alarm(5); getchar(); return 0; }
Thanks!Flies of a particular kind, i.e. time-flies, are fond of an arrow.
Registered Linux User #408794
- 11-22-2007 #2
You're doing fine so far. This program:
will respond to the TERM signal. You can do stuff in the signal handler to clean up and exit.Code:#include <signal.h> #include <stdio.h> #include <unistd.h> void alarm_handler(int sig) { printf("Signal!\n"); } void reldnah_mrala(int sig) { printf("langiS!\n"); } int main(void) { signal(SIGALRM, alarm_handler); signal(SIGTERM, reldnah_mrala); alarm(5); getchar(); return 0; }
But maybe you don't want to do all that cleanup in the signal handler, since there are many non-reentrant functions that you should avoid calling from there. Maybe you want to return to just after the getchar(). To do so, you have two alternatives.
- Use setjmp()/longjmp(), since longjmp() is safe to call from a signal handler.
- Use sigaction() instead of signal().
That second alternative is a bit cleaner. This example uses it:
Run it and send it the TERM signal, and you'll get a result of -1 and an error of EINTR (which is 4).Code:#include <errno.h> #include <signal.h> #include <stdio.h> #include <unistd.h> void alarm_handler(int sig) { printf("Signal!\n"); } void reldnah_mrala(int sig) { printf("langiS!\n"); } int main(void) { int get_result; int the_error; struct sigaction new_action; new_action.sa_handler=reldnah_mrala; sigemptyset(&new_action.sa_mask); new_action.sa_flags=0; signal(SIGALRM, alarm_handler); sigaction(SIGTERM, &new_action, NULL); alarm(5); get_result=getchar(); if(get_result==-1) { the_error=errno; printf("errno is %d\n",the_error); } printf("%d\n",get_result); return 0; }
You can similarly alter the handling of the SIGALRM, but I didn't in this sample just so you could see the two interrupt handler specification calls together.
If you use sigaction(), you can vary at runtime whether the system call returns on interrupt by setting the new_action.sa_flags variable to SA_RESTART.
Hope this helps.
Edit:
I like to avoid signals whenever possible. Mariposa County has only one, and that's because of the rockslide.--
Bill
Old age and treachery will overcome youth and skill.
- 11-23-2007 #3
Much obliged. The sigaction hint was exactly what I needed. I guess I'll have to read up on that...
Flies of a particular kind, i.e. time-flies, are fond of an arrow.
Registered Linux User #408794


Reply With Quote