Signals and signal handlers in C 
Author Message
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 
 [ 15 post ] 

 Relevant Pages 

1. signal handler function

2. fclose(), signal handlers, and an opaque struct named FILE

3. REPOST with code: Signal handler + write = SIGBUS !?!

4. abort() and signal handler + while loop: havoc behavior

5. Default signal handlers

6. Signal handlers and global variables.

7. printing within a signal handler

8. signal handlers

9. Bind keypress to a signal handler?

10. longjmp() from signal handler (was: NDEBUG useless?)

11. Library functions in signal handlers

12. signal handler

 

 
Powered by phpBB® Forum Software