Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When a signal occurs, the normal flow of control of a program is interrupted. If a signal occurs that is being trapped by a signal handler, that handler is invoked. When it is finished, execution continues at the point at which the signal occurred. This arrangement could cause problems if the signal handler invokes a library function that was being executed at the time of the signal. Since library functions are not guaranteed to be reentrant, they should not be called from a signal handler that returns.

Implementation Details

The And according to the OpenBSD signal() man page

...

identifies functions that are either reentrant or not interruptible by

...

signals and are

...

asynchronous-signal safe.

...

Applications may therefore invoke

...

them, without restriction, from signal-catching functions

...

Base Interfaces:

_exit(), access(), alarm(), cfgetispeed(), cfgetospeed(), cfsetispeed(),
cfsetospeed(), chdir(), chmod(), chown(), close(), creat(), dup(),
dup2(), execle(), execve(), fcntl(), fork(), fpathconf(), fstat(),
fsync(), getegid(), geteuid(), getgid(), getgroups(), getpgrp(),
getpid(), getppid(), getuid(), kill(), link(), lseek(), mkdir(),
mkfifo(), open(), pathconf(), pause(), pipe(), raise(), read(), rename(),
rmdir(), setgid(), setpgid(), setsid(), setuid(), sigaction(),
sigaddset(), sigdelset(), sigemptyset(), sigfillset(), sigismember(),
signal(), sigpending(), sigprocmask(), sigsuspend(), sleep(), stat(),
sysconf(), tcdrain(), tcflow(), tcflush(), tcgetattr(), tcgetpgrp(),
tcsendbreak(), tcsetattr(), tcsetpgrp(), time(), times(), umask(),
uname(), unlink(), utime(), wait(), waitpid(), write().

.

Non-Compliant Code Example

This non-compliant code example invokes the longjmp function to transfer control from the signal handler int_handler() back into main(). Once control returns to main(), a potentially non-reentrant system call is made to strcpy().

Non-Compliant Coding Example

Using the longjmp function inside a signal handler is particularly dangerous, as it could call any part of your code.

Code Block
bgColor#FFcccc
#include <setjmp.h> 
#include <signal.h> 
 
static jmp_buf env; 
 
void int_handler() { 
  longjmp(env, 1); 
  return;
} 
 
int main(void) { 
  char *foo; 

  signal(SIGINT, int_handler); 
 
  if (setjmp(env) == 0) { 
    foo = malloc(15);
    strcpy(foo, "Nothing yet.");
  }
  else {
    strcpy(foo, "Signal caught.");
  }

  /* main loop which displays foo */

  return 0;
}

...

Code Block
bgColor#ccccff
#include <signal.h> 

int interrupted = 0;
 
void int_handler() { 
  interrupted = 1;
  return;
} 
 
int main(void) { 
  char *foo; 

  signal(SIGINT, int_handler); 
    
  foo = malloc(15);
  strcpy(foo, "Nothing yet.");
  
  /* main loop which displays foo */
  if (interrupted == 1) {
    strcpy(foo, "Signal caught.");
  }

  return 0;
}

...