Author |
Message |
Kenneth #1 / 15
|
Signals and signal handlers in C
Hi there, I'm having some difficulties with signal handlers in C. I've read several man pages and text books on this and they all seem to be saying the same sort of thing. The signal handler that is passed as a function pointer to the signal(...) function is almost always in every case I've seen so far, a void return and void or int parameter function. My program is supposed to take a configuration file and re-read it when a signal is received. So that means the function that reads the config file will need a bunch of variables to be passed to it, so that it can change their values based on the config file. My problem is: I don't know if it's possible to create a signal handler and to pass that to signal(...) such that it has parameters other than simply void or int. Thanks Kenneth
|
Sat, 02 Apr 2005 12:16:26 GMT |
|
|
Angela d.S #2 / 15
|
Signals and signal handlers in C
"Kenneth S" wrote Quote: > I'm having some difficulties with signal handlers in C. I've read > several man pages and text books on this and they all seem to be > saying the same sort of thing. > The signal handler that is passed as a function pointer to the > signal(...) function is almost always in every case I've seen so far, > a void return and void or int parameter function. > My program is supposed to take a configuration file and re-read it > when a signal is received. So that means the function that reads the > config file will need a bunch of variables to be passed to it, so that > it can change their values based on the config file. > My problem is: I don't know if it's possible to create a signal > handler and to pass that to signal(...) such that it has parameters > other than simply void or int.
A signal handler must be declared with type void(int) or alternatively void(*)(int). Note that there is not much you can do within a signal handler itself portably; you can merely set a flag. Rereading a configuration file within the signal handler itself (like it seems you wanted to do) is a bad idea and might lead to surprising and inconsistent results.
|
Sat, 02 Apr 2005 13:30:43 GMT |
|
|
Jeff Davi #3 / 15
|
Signals and signal handlers in C
Quote:
> "Kenneth S" wrote >> I'm having some difficulties with signal handlers in C. I've read >> several man pages and text books on this and they all seem to be >> saying the same sort of thing. >> The signal handler that is passed as a function pointer to the >> signal(...) function is almost always in every case I've seen so far, >> a void return and void or int parameter function. >> My program is supposed to take a configuration file and re-read it >> when a signal is received. So that means the function that reads the >> config file will need a bunch of variables to be passed to it, so that >> it can change their values based on the config file. >> My problem is: I don't know if it's possible to create a signal >> handler and to pass that to signal(...) such that it has parameters >> other than simply void or int. > A signal handler must be declared with type void(int) or alternatively > void(*)(int). Note that there is not much you can do within a signal > handler itself portably; you can merely set a flag. Rereading a > configuration file within the signal handler itself (like it seems you > wanted to do) is a bad idea and might lead to surprising and inconsistent > results.
What kind of unexpected behavior might he expect (ignore the logical error in that sentence :) I would have previously thought it a normal thing to do to reread a config file when a signal's received. I don't really know what goes on I guess when a program receives a signal I suppose. Regards, Jeff
|
Sat, 02 Apr 2005 13:49:50 GMT |
|
|
Angela d.S #4 / 15
|
Signals and signal handlers in C
"Jeff Davis" wrote Quote: > What kind of unexpected behavior might he expect (ignore the logical error > in that sentence :) I would have previously thought it a normal thing to > do to reread a config file when a signal's received. I don't really know > what goes on I guess when a program receives a signal I suppose.
The functions in the standard library are not guaranteed to be reentrant and may modify objects with static storage duration, so in general a signal handler cannot call standard library functions (without unexpected results). Rereading a configuration file involves calling standard library functions, hence... --- AdS
|
Sat, 02 Apr 2005 14:26:37 GMT |
|
|
those who know me have no need of my nam #5 / 15
|
Signals and signal handlers in C
in comp.lang.c i read: Quote: >My program is supposed to take a configuration file and re-read it >when a signal is received. >My problem is: I don't know if it's possible to create a signal >handler and to pass that to signal(...) such that it has parameters >other than simply void or int.
nope. a signal handler has only one form in iso c: void(*func)(int). it may be that your implementation or platform provides other forms, but it is extremely unlikely. it is even more unlikely (i.e., virtually nil) that arbitrary data can be passed to the function as parameters. almost the only thing that can be done safely from a signal handler is to manipulate volatile sig_atomic_t data, e.g., #include <stdio.h> #include <stdlib.h> #include <signal.h> static void handle_signal(void); static void handler(int); static volatile sig_atomic_t signalled = 0; int main(void) { /* ... initialization ... */ /* establish signal handling */ if (SIG_ERR == signal(SIGINT,handler)) { fprintf(stderr, "failed to establish signal handler\n"); /* probably you should display errno and/or use strerror/perror */ /* whether to exit or continue, hmm..., i'll croak */ return EXIT_FAILURE; } while(1) { /* ... do stuff ... */ handle_signal(); /* ... more stuff ... */ handle_signal(); /* ... more stuff ... */ handle_signal(); /* ... more stuff ... */ } /* relinquish signal handling */ if (SIG_ERR == signal(signal,SIG_DFL)) { fprintf(stderr, "failed to relinquish signal handler\n"); /* probably you should display errno and/or use strerror/perror */ /* whether to exit or continue, hmm..., i'll continue */ } /* ... clean-up ... */ return EXIT_SUCCESS; } static void handle_signal(void) { if (0 != signalled) { /* ... read config and whatever else ... */ /* re-establish signal handling */ signalled = 0; (void) signal(SIGINT,handler); } } static void handler(int signal) { (void) signal(signal,SIG_DFL); /* restore default behavior so that a subsequent signal will do the default thing, e.g., terminate the program */ signalled = 1; /* set flag (for main loop) */ } note: when a signal is handled it is implementation defined whether the signal is reset to SIG_DFL or retains the explicit setting provided by the program. if you need the signal to be handled reliably you will need to use implementation or platform provided tools, i.e., i've only described the iso c semantics for signal handling, your implementation or platform may provide something else and will certainly fill-in the blanks that iso c requires (and is almost certainly what you will need to use), but all of that is off-topic for this group. -- bringing you boring signatures for 17 years
|
Sat, 02 Apr 2005 16:38:23 GMT |
|
|
Dave Near #6 / 15
|
Signals and signal handlers in C
On Tue, 15 Oct 2002 05:49:50 GMT, Jeff Davis said: Quote:
>> Note that there is not much you can do within a signal >> handler itself portably; you can merely set a flag. Rereading a >> configuration file within the signal handler itself (like it seems you >> wanted to do) is a bad idea and might lead to surprising and inconsistent >> results. > What kind of unexpected behavior might he expect
Consider what happens if the program receives the signal while the file is being read, and the signal handler tries to open the file for reading again. Cheers, Dave. -- David Neary, E-Mail: bolsh at gimp dot org CV: http://www.redbrick.dcu.ie/~bolsh/CV/CV.html
|
Sat, 02 Apr 2005 22:06:17 GMT |
|
|
Dan P #7 / 15
|
Signals and signal handlers in C
Quote: >"Kenneth S" wrote >> I'm having some difficulties with signal handlers in C. I've read >> several man pages and text books on this and they all seem to be >> saying the same sort of thing. >> The signal handler that is passed as a function pointer to the >> signal(...) function is almost always in every case I've seen so far, >> a void return and void or int parameter function. >> My program is supposed to take a configuration file and re-read it >> when a signal is received. So that means the function that reads the >> config file will need a bunch of variables to be passed to it, so that >> it can change their values based on the config file. >> My problem is: I don't know if it's possible to create a signal >> handler and to pass that to signal(...) such that it has parameters >> other than simply void or int. >A signal handler must be declared with type void(int) or alternatively >void(*)(int).
A signal handler is a function returning void and taking one int argument and nothing else. Dan -- Dan Pop DESY Zeuthen, RZ group
|
Sun, 03 Apr 2005 20:59:12 GMT |
|
|
Dan P #8 / 15
|
Signals and signal handlers in C
Quote: >I'm having some difficulties with signal handlers in C. I've read >several man pages and text books on this and they all seem to be >saying the same sort of thing. >The signal handler that is passed as a function pointer to the >signal(...) function is almost always in every case I've seen so far, >a void return and void or int parameter function. >My program is supposed to take a configuration file and re-read it >when a signal is received. So that means the function that reads the >config file will need a bunch of variables to be passed to it, so that >it can change their values based on the config file. >My problem is: I don't know if it's possible to create a signal >handler and to pass that to signal(...) such that it has parameters >other than simply void or int.
You've got it wrong. All the signal handler has to do is to set a flag variable, defined as volatile sig_atomic_t. In the main loop of your program you periodically check to see if the flag was set. If this is the case, you reread the configuration file (and reset the flag). Don't forget to reenable the signal handler, either before leaving the signal handler or after detecting that the flag was set. Dan -- Dan Pop DESY Zeuthen, RZ group
|
Sun, 03 Apr 2005 20:56:58 GMT |
|
|
Dan P #9 / 15
|
Signals and signal handlers in C
Quote: >in comp.lang.c i read: >>My program is supposed to take a configuration file and re-read it >>when a signal is received. >>My problem is: I don't know if it's possible to create a signal >>handler and to pass that to signal(...) such that it has parameters >>other than simply void or int. >nope. a signal handler has only one form in iso c: void(*func)(int). it
Nope, a signal handler is a function, NOT a pointer to a function. Dan -- Dan Pop DESY Zeuthen, RZ group
|
Sun, 03 Apr 2005 21:01:20 GMT |
|
|
Angela d.S #10 / 15
|
Signals and signal handlers in C
"Dan Pop" wrote
writes: Quote: > >A signal handler must be declared with type void(int) or alternatively > >void(*)(int). > A signal handler is a function returning void and taking one int argument > and nothing else.
What prevents one from declaring a signal handler as a pointer to a function returning void and taking one int argument? --- aDs
|
Mon, 04 Apr 2005 01:41:36 GMT |
|
|
those who know me have no need of my nam #11 / 15
|
Signals and signal handlers in C
in comp.lang.c i read: Quote:
>>a signal handler has only one form in iso c: void(*func)(int). >Nope, a signal handler is a function, NOT a pointer to a function.
argh. yeah, copied the prototype for the argument to signal() and forgot to remove the *. thanks for catching it. -- bringing you boring signatures for 17 years
|
Mon, 04 Apr 2005 01:57:10 GMT |
|
|
Dave Near #12 / 15
|
Signals and signal handlers in C
On Wed, 16 Oct 2002 19:41:36 +0200, Angela d.S. said: Quote: > What prevents one from declaring a signal handler as a pointer to a function > returning void and taking one int argument?
The point is that the pointer has to point at something. Dereferencing a pointer-to-function with nothing behind it is undefined behaviour. Therefore, the actual signal handler is a function, whereas the parameter passed to signal is a pointer to that function. Cheers, Dave. -- David Neary, E-Mail: bolsh at gimp dot org CV: http://www.redbrick.dcu.ie/~bolsh/CV/CV.html
|
Mon, 04 Apr 2005 04:23:33 GMT |
|
|
Angela d.S #13 / 15
|
Signals and signal handlers in C
"Dave Neary" wrote Quote: > On Wed, 16 Oct 2002 19:41:36 +0200, Angela d.S. said: > > What prevents one from declaring a signal handler as a pointer to a function > > returning void and taking one int argument? > The point is that the pointer has to point at something. > Dereferencing a pointer-to-function with nothing behind it is > undefined behaviour.
Well, duh. Quote: > Therefore, the actual signal handler is a function, whereas the > parameter passed to signal is a pointer to that function.
Sorry, I'm still missing the point; your post does not actually address the question. One can declare a signal handler as a pointer to a function returning void and taking one int argument, e.g. #include <signal.h> extern void f(int a); static void (*signal_handler)(int a) = f; int main(void) { signal(SIGINT, signal_handler); return 0; Quote: }
Now what is wrong with that statement?
|
Mon, 04 Apr 2005 05:16:28 GMT |
|
|
Dan P #14 / 15
|
Signals and signal handlers in C
Quote: >"Dave Neary" wrote >> On Wed, 16 Oct 2002 19:41:36 +0200, Angela d.S. said: >> > What prevents one from declaring a signal handler as a pointer to a function >> > returning void and taking one int argument? >> The point is that the pointer has to point at something. >> Dereferencing a pointer-to-function with nothing behind it is >> undefined behaviour. >Well, duh. >> Therefore, the actual signal handler is a function, whereas the >> parameter passed to signal is a pointer to that function. >Sorry, I'm still missing the point; your post does not actually address the >question. One can declare a signal handler as a pointer to a function returning >void and taking one int argument, e.g. >#include <signal.h> >extern void f(int a); >static void (*signal_handler)(int a) = f; >int main(void) >{ > signal(SIGINT, signal_handler); > return 0; >} >Now what is wrong with that statement?
The point you're missing is that, in your example, the signal handler is the function f and not the pointer signal_handler. Otherwise, func shall point to a function to be called when that signal occurs. An invocation of such a function because of a signal, or ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (recursively) of any further functions called by that invocation (other than functions in the standard library), is called a signal handler. ^^^^^^^^^^^^^^^^^^^^^^^^^^ Dan -- Dan Pop DESY Zeuthen, RZ group
|
Mon, 04 Apr 2005 17:19:54 GMT |
|
|
Gordon Burdi #15 / 15
|
Signals and signal handlers in C
Quote: >> A signal handler must be declared with type void(int) or alternatively >> void(*)(int). Note that there is not much you can do within a signal >> handler itself portably; you can merely set a flag. Rereading a >> configuration file within the signal handler itself (like it seems you >> wanted to do) is a bad idea and might lead to surprising and inconsistent >> results. >What kind of unexpected behavior might he expect (ignore the logical error >in that sentence :) I would have previously thought it a normal thing to >do to reread a config file when a signal's received. I don't really know >what goes on I guess when a program receives a signal I suppose.
Two likely problem areas are with any operation that uses (or might use) malloc(), and file operations on the same file as the top-level program is using. Both of these will have problems if the program gets a signal while in the middle of changing global data (in the case of malloc()) or file-related data (in the case of file operations) which might be global or might be related to the FILE structure for the file in question. A common implementation of malloc() involves a linked list of free storage. If the signal handler and the top-level program both modify the linked list at the same time, one of them may end up following links to nowhere and smegfaulting. Or you might end up allocating the same piece of memory twice. File operations may use malloc(), and they also deal with buffers which might result in duplicated or missed output if both a signal handler and top-level program try to access the same file at the same time. It might seem that something as harmless as: #include <stdlib.h> void keyboardsignalhandler(int sig) { printf("Caught signal %d, giving up\n", sig); exit(EXIT_FAILURE); Quote: }
wouldn't cause core dumps on UNIX, but I have seen it happen (rarely). Gordon L. Burditt
|
Fri, 22 Apr 2005 13:58:18 GMT |
|
|