File: SignalHandler.cpp

package info (click to toggle)
abyss 2.3.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,284 kB
  • sloc: cpp: 78,182; ansic: 6,512; makefile: 2,252; perl: 672; sh: 509; haskell: 412; python: 4
file content (62 lines) | stat: -rw-r--r-- 1,403 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
 * Signal handling code, particularly SIGCHLD.
 */

#include "SignalHandler.h"
#include <cassert>
#include <cerrno>
#include <cstdio> // for perror
#include <cstdlib>
#include <iostream>
#include <signal.h>
#include <sys/wait.h>

using namespace std;

/** Print the specified exit status. */
static void printStatus(pid_t pid, int status)
{
	if (WIFEXITED(status))
		cerr << "PID " << pid << " exited with status "
			<< WEXITSTATUS(status) << endl;
	else if (WIFSIGNALED(status))
		cerr << "PID " << pid << " killed by signal "
			<< WTERMSIG(status) << endl;
	else
		cerr << "PID " << pid << " exited with code "
			<< status << endl;
}

/** SIGCHLD handler. Reap child processes and report an error if any
 * fail. */
static void sigchldHandler(int sig)
{
	assert(sig == SIGCHLD);
	(void)sig;

	pid_t pid;
	int status;
	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
		// Writing to cerr in a signal handler is not allowed, but
		// we're about to exit and an error message would be really
		// helpful.
		if (status != 0) {
			printStatus(pid, status);
			exit(EXIT_FAILURE);
		}
	}
	if (pid == -1 && errno != ECHILD) {
		perror("waitpid");
		exit(EXIT_FAILURE);
	}
}

/** Install a handler for SIGCHLD. */
void signalInit()
{
	struct sigaction action;
	action.sa_handler = sigchldHandler;
	sigemptyset(&action.sa_mask);
	action.sa_flags = SA_RESTART;
	sigaction(SIGCHLD, &action, NULL);
}