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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/* signaltester, catch & print signals
* This is used for testing out sb2-monitor.
*
* Copyright (c) 2008 Nokia Corporation. All rights reserved.
* Author: Lauri T. Aarnio
* Licensed under LGPL version 2.1, see top level LICENSE file for details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define _GNU_SOURCE /* to get strsignal(), a non-standard extension */
#include <string.h>
static int signals_received = 0;
static void signal_handler(int sig, siginfo_t *info, void *ptr)
{
(void)ptr; /* unused param */
signals_received++;
fprintf(stderr, "\nGot signal %d (%s), received %d signals\n",
sig, strsignal(sig), signals_received);
switch (sig) {
case SIGILL: case SIGFPE: case SIGSEGV:
if ((info->si_code != SI_USER) &&
(info->si_code != SI_QUEUE)) {
/* the signal is a real, fatal, deadly
* that must not be ignored. */
fprintf(stderr, "Deadly signal\n");
exit(249);
}
/* else it is user-generated signal */
break;
case SIGTSTP:
/* Job control.. stop request from tty */
fprintf(stderr, "Stopping myself.\n");
raise(SIGSTOP);
return;
}
if (info->si_code == SI_QUEUE) {
fprintf(stderr, "SI_QUEUE int=%d ptr=0x%x\n",
info->si_value.sival_int,
(int)(info->si_value.sival_ptr));
} else if (info->si_code == SI_USER) {
fprintf(stderr, "SI_USER\n");
} else {
fprintf(stderr, "si_code is %d\n", info->si_code);
}
}
static void initialize_signal_handler(int sig)
{
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_sigaction = signal_handler;
act.sa_flags = SA_SIGINFO;
/* block all other signals while this signal is being processed */
sigfillset(&act.sa_mask);
sigaction(sig, &act, NULL);
}
/* Set up a signal handler for all signals that can be caught. */
static void catch_all_signals(void)
{
/* order here tries to follows the numerical order of signals
* on Linux (see signal(7)) and Mac OS X (see signal(2))
*/
initialize_signal_handler(SIGHUP); /* 1 */
initialize_signal_handler(SIGINT);
initialize_signal_handler(SIGQUIT);
initialize_signal_handler(SIGILL);
initialize_signal_handler(SIGTRAP); /* 5 */
initialize_signal_handler(SIGABRT);
#ifdef SIGIOT /* old name for SIGABRT */
initialize_signal_handler(SIGIOT);
#endif
#ifdef SIGEMT
initialize_signal_handler(SIGEMT);
#endif
initialize_signal_handler(SIGFPE);
/* SIGKILL, 9, cannot be caught or ignored */
initialize_signal_handler(SIGBUS);
initialize_signal_handler(SIGSEGV); /* 11 */
initialize_signal_handler(SIGSYS);
initialize_signal_handler(SIGPIPE);
initialize_signal_handler(SIGALRM);
initialize_signal_handler(SIGTERM); /* 15 */
initialize_signal_handler(SIGURG);
/* SIGSTOP, 17, cannot be caught or ignored */
initialize_signal_handler(SIGTSTP);
initialize_signal_handler(SIGCONT);
initialize_signal_handler(SIGCHLD); /* 20 */
initialize_signal_handler(SIGTTIN);
initialize_signal_handler(SIGTTOU);
initialize_signal_handler(SIGIO);
initialize_signal_handler(SIGXCPU);
initialize_signal_handler(SIGXFSZ); /* 25 */
initialize_signal_handler(SIGVTALRM);
initialize_signal_handler(SIGPROF);
initialize_signal_handler(SIGWINCH);
#ifdef SIGPWR
initialize_signal_handler(SIGPWR);
#endif
#ifdef SIGLOST
initialize_signal_handler(SIGLOST);
#endif
#ifdef SIGINFO
initialize_signal_handler(SIGINFO);
#endif
initialize_signal_handler(SIGUSR1);
initialize_signal_handler(SIGUSR2);
#ifdef SIGTHR
initialize_signal_handler(SIGTHR);
#endif
}
int main(int argc, char *argv[])
{
char *progname = argv[0];
int num_signals_to_receive = 10;
int opt;
while ((opt = getopt(argc, argv, "n:g")) != -1) {
switch (opt) {
case 'n': num_signals_to_receive = atoi(optarg); break;
case 'g': setpgrp(); break;
}
}
/* check parameters */
if (optind < argc) {
fprintf(stderr, "Wrong number of parameters");
exit(1);
}
fprintf(stderr, "\n%s: PID=%d PGID=%d: waiting for %d signals\n",
progname, (int)getpid(), (int)getpgrp(),
num_signals_to_receive);
catch_all_signals();
/* all initializations done, wait until the child has finished. */
while (signals_received < num_signals_to_receive) {
if (sleep(5)) fprintf(stderr, "S");
else fprintf(stderr, ".");
}
return(0);
}
|