Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Fixed the includes to match the library functions used.

...

Code Block
bgColor#FFcccc
langc
#include <signal.h>
#include <stdlib.h>
#include <string<stdio.h>

typedef void (*pfv)(int);

void handler(int signum) {
  pfv old_handler = signal(signum, SIG_DFL);
  if (old_handler == SIG_ERR) {
    perror("SIGINT handler"); /* undefined behavior */
    /* Handle error condition */
  }
}

int main(void) {
  pfv old_handler = signal(SIGINT, handler);
  if (old_handler == SIG_ERR) {
    perror("SIGINT handler");
    /* Handle error condition */
  }

  /* Main code loop */

  return 0EXIT_SUCCESS;
}

The call to perror() from handler() also violates SIG30-C. Call only asynchronous-safe functions within signal handlers.

...

Code Block
bgColor#ccccff
langc
#include <signal.h>
#include <stdlib.h>
#include <string<stdio.h>

typedef void (*pfv)(int);

void handler(int signum) {
  pfv old_handler = signal(signum, SIG_DFL);
  if (old_handler == SIG_ERR) {
    abort();
  }
}

int main(void) {
  pfv old_handler = signal(SIGINT, handler);
  if (old_handler == SIG_ERR) {
    perror("SIGINT handler");
    /* Handle error condition */
  }

  /* Main code loop */

  return 0EXIT_SUCCESS;
}

Noncompliant Code Example (POSIX)

...

Code Block
bgColor#FFcccc
langc
#include <stddef.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

void reaper(int signum) {
  errno = 0;
  for (;;) {
    int rc = waitpid(-1, NULL, WNOHANG);
    if ( (0 == rc) || (-1 == rc && EINTR != errno) )
      break;
  }
  if (ECHILD != errno) {
    /* Handle error */
  }
}

int main(void) {
  struct sigaction act;
  act.sa_handler = reaper;
  act.sa_flags = 0;
  if (sigemptyset(&act.sa_mask) != 0) {
    /* Handle error */
  }
  if (sigaction(SIGCHLD, &act, NULL) != 0) {
    /* Handle error */
  }

  /* ... */

  return 0EXIT_SUCCESS;
}

Compliant Solution (POSIX)

...

Code Block
bgColor#ccccff
langc
#include <stddef<signal.h>
#include <signal<stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

void reaper(int signum) {
  int save_errno = errno;
  errno = 0;
  for (;;) {
    int rc = waitpid(-1, NULL, WNOHANG);
    if ( (0 == rc) || (-1 == rc && EINTR != errno) )
      break;
  }
  if (ECHILD != errno) {
    /* Handle error */
  }
  errno = save_errno;
}

int main(void) {
  struct sigaction act;
  act.sa_handler = reaper;
  act.sa_flags = 0;
  if (sigemptyset(&act.sa_mask) != 0) {
    /* Handle error */
  }
  if (sigaction(SIGCHLD, &act, NULL) != 0) {
    /* Handle error */
  }

  /* ... */

  return 0EXIT_SUCCESS;
}

Risk Assessment

Referencing indeterminate values can result in undefined behavior.

...