1#include <inttypes.h>
2#include <signal.h>
3#include <stdio.h>
4#include <string.h>
5#include <unistd.h>
6
7#define ADD_SIGNAL(signal)	{ signal, #signal }
8
9const struct {
10	int			signal;
11	const char*	name;
12} kSignals[] = {
13	ADD_SIGNAL(SIGHUP),
14	ADD_SIGNAL(SIGINT),
15	ADD_SIGNAL(SIGQUIT),
16	ADD_SIGNAL(SIGILL),
17	ADD_SIGNAL(SIGCHLD),
18	ADD_SIGNAL(SIGABRT),
19	ADD_SIGNAL(SIGPIPE),
20	ADD_SIGNAL(SIGFPE),
21	ADD_SIGNAL(SIGKILL),
22	ADD_SIGNAL(SIGSTOP),
23	ADD_SIGNAL(SIGSEGV),
24	ADD_SIGNAL(SIGCONT),
25	ADD_SIGNAL(SIGTSTP),
26	ADD_SIGNAL(SIGALRM),
27	ADD_SIGNAL(SIGTERM),
28	ADD_SIGNAL(SIGTTIN),
29	ADD_SIGNAL(SIGTTOU),
30	ADD_SIGNAL(SIGUSR1),
31	ADD_SIGNAL(SIGUSR2),
32	ADD_SIGNAL(SIGWINCH),
33	ADD_SIGNAL(SIGKILLTHR),
34	ADD_SIGNAL(SIGTRAP),
35	{-1, NULL}
36};
37
38#define ADD_SA_FLAG(flag)	{ flag, #flag }
39
40
41const struct {
42	int			flag;
43	const char*	name;
44} kSigActionFlags[] = {
45	ADD_SA_FLAG(SA_NOCLDSTOP),
46#ifdef SA_NOCLDWAIT
47		ADD_SA_FLAG(SA_NOCLDWAIT),
48#endif
49#ifdef SA_RESETHAND
50	ADD_SA_FLAG(SA_RESETHAND),
51#endif
52#ifdef SA_NODEFER
53	ADD_SA_FLAG(SA_NODEFER),
54#endif
55#ifdef SA_RESTART
56	ADD_SA_FLAG(SA_RESTART),
57#endif
58#ifdef SA_ONSTACK
59	ADD_SA_FLAG(SA_ONSTACK),
60#endif
61#ifdef SA_SIGINFO
62	ADD_SA_FLAG(SA_SIGINFO),
63#endif
64	{0, NULL}
65};
66
67
68int
69main(int argc, const char* const* argv)
70{
71	// print pid, process group
72	printf("process id:       %d\n", (int)getpid());
73	printf("parent id:        %d\n", (int)getppid());
74	printf("process group:    %d\n", (int)getpgrp());
75	printf("fg process group: %d\n", (int)tcgetpgrp(STDOUT_FILENO));
76
77	// print signal mask
78	sigset_t signalMask;
79	sigprocmask(SIG_BLOCK, NULL, &signalMask);
80	printf("blocked signals:  ");
81	bool printedFirst = false;
82	for (int i = 0; kSignals[i].name; i++) {
83		if (sigismember(&signalMask, kSignals[i].signal)) {
84			if (printedFirst) {
85				printf(", ");
86			} else
87				printedFirst = true;
88			printf("%s", kSignals[i].name);
89		}
90	}
91	printf("\n");
92
93	// print signal handlers
94	printf("signal handlers:\n");
95	for (int i = 0; kSignals[i].name; i++) {
96		struct sigaction action;
97		sigaction(kSignals[i].signal, NULL, &action);
98
99		// signal name
100		int signalNameSpacing = 10 - (int)strlen(kSignals[i].name);
101		if (signalNameSpacing < 0)
102			signalNameSpacing = 0;
103		printf("  %s:%*s ", kSignals[i].name, signalNameSpacing, "");
104
105		// signal handler
106		if (action.sa_handler == SIG_DFL)
107			printf("SIG_DFL");
108		else if (action.sa_handler == SIG_IGN)
109			printf("SIG_IGN");
110		else if (action.sa_handler == SIG_ERR)
111			printf("SIG_ERR");
112		else
113			printf("%p", action.sa_handler);
114
115		printf(" (");
116
117		// flags
118		printedFirst = false;
119		for (int i = 0; kSigActionFlags[i].name; i++) {
120			if (action.sa_flags & kSigActionFlags[i].flag) {
121				if (printedFirst) {
122					printf(", ");
123				} else
124					printedFirst = true;
125				printf("%s", kSigActionFlags[i].name);
126			}
127		}
128		printf(")\n");
129	}
130
131
132	return 0;
133}
134