xref: /freebsd/usr.bin/procstat/procstat_sigs.c (revision 474b62b8)
1f4646706SKonstantin Belousov /*-
2f4646706SKonstantin Belousov  * Copyright (c) 2010 Konstantin Belousov
3474b62b8SAllan Jude  * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org>
4f4646706SKonstantin Belousov  * All rights reserved.
5f4646706SKonstantin Belousov  *
6f4646706SKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
7f4646706SKonstantin Belousov  * modification, are permitted provided that the following conditions
8f4646706SKonstantin Belousov  * are met:
9f4646706SKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
10f4646706SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
11f4646706SKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
12f4646706SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
13f4646706SKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
14f4646706SKonstantin Belousov  *
15f4646706SKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16f4646706SKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17f4646706SKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18f4646706SKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19f4646706SKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20f4646706SKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21f4646706SKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22f4646706SKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23f4646706SKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24f4646706SKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25f4646706SKonstantin Belousov  * SUCH DAMAGE.
26f4646706SKonstantin Belousov  *
27f4646706SKonstantin Belousov  * $FreeBSD$
28f4646706SKonstantin Belousov  */
29f4646706SKonstantin Belousov 
30f4646706SKonstantin Belousov #include <sys/param.h>
31f4646706SKonstantin Belousov #include <sys/sysctl.h>
32f4646706SKonstantin Belousov #include <sys/user.h>
33f4646706SKonstantin Belousov 
34f4646706SKonstantin Belousov #include <ctype.h>
35f4646706SKonstantin Belousov #include <err.h>
36f4646706SKonstantin Belousov #include <errno.h>
37f4646706SKonstantin Belousov #include <signal.h>
38f4646706SKonstantin Belousov #include <stdio.h>
39f4646706SKonstantin Belousov #include <stdlib.h>
40f4646706SKonstantin Belousov #include <string.h>
410daf62d9SStanislav Sedov #include <libprocstat.h>
42f4646706SKonstantin Belousov 
43f4646706SKonstantin Belousov #include "procstat.h"
44f4646706SKonstantin Belousov 
45f4646706SKonstantin Belousov static void
46f4646706SKonstantin Belousov procstat_print_signame(int sig)
47f4646706SKonstantin Belousov {
48f4646706SKonstantin Belousov 	char name[12];
49f4646706SKonstantin Belousov 	int i;
50f4646706SKonstantin Belousov 
51f4646706SKonstantin Belousov 	if (!nflag && sig < sys_nsig) {
52f4646706SKonstantin Belousov 		strlcpy(name, sys_signame[sig], sizeof(name));
53f4646706SKonstantin Belousov 		for (i = 0; name[i] != 0; i++)
54f4646706SKonstantin Belousov 			name[i] = toupper(name[i]);
55474b62b8SAllan Jude 		xo_emit("{d:signal/%-7s/%s} ", name);
56474b62b8SAllan Jude 		xo_open_container(name);
57474b62b8SAllan Jude 	} else {
58474b62b8SAllan Jude 		xo_emit("{d:signal/%-7d/%d} ", sig);
59474b62b8SAllan Jude 		snprintf(name, 12, "%d", sig);
60474b62b8SAllan Jude 		xo_open_container(name);
61474b62b8SAllan Jude 	}
62474b62b8SAllan Jude }
63474b62b8SAllan Jude 
64474b62b8SAllan Jude static void
65474b62b8SAllan Jude procstat_close_signame(int sig)
66474b62b8SAllan Jude {
67474b62b8SAllan Jude 	char name[12];
68474b62b8SAllan Jude 	int i;
69474b62b8SAllan Jude 
70474b62b8SAllan Jude 	if (!nflag && sig < sys_nsig) {
71474b62b8SAllan Jude 		strlcpy(name, sys_signame[sig], sizeof(name));
72474b62b8SAllan Jude 		for (i = 0; name[i] != 0; i++)
73474b62b8SAllan Jude 			name[i] = toupper(name[i]);
74474b62b8SAllan Jude 		xo_close_container(name);
75f4646706SKonstantin Belousov 	} else
76474b62b8SAllan Jude 		snprintf(name, 12, "%d", sig);
77474b62b8SAllan Jude 		xo_close_container(name);
78f4646706SKonstantin Belousov }
79f4646706SKonstantin Belousov 
80f4646706SKonstantin Belousov static void
81f4646706SKonstantin Belousov procstat_print_sig(const sigset_t *set, int sig, char flag)
82f4646706SKonstantin Belousov {
83474b62b8SAllan Jude 	xo_emit("{d:sigmember/%c}", sigismember(set, sig) ? flag : '-');
84474b62b8SAllan Jude 	switch (flag) {
85474b62b8SAllan Jude 		case 'B':
86474b62b8SAllan Jude 			xo_emit("{en:mask/%s}", sigismember(set, sig) ?
87474b62b8SAllan Jude 			    "true" : "false");
88474b62b8SAllan Jude 			break;
89474b62b8SAllan Jude 		case 'C':
90474b62b8SAllan Jude 			xo_emit("{en:catch/%s}", sigismember(set, sig) ?
91474b62b8SAllan Jude 			    "true" : "false");
92474b62b8SAllan Jude 			break;
93474b62b8SAllan Jude 		case 'P':
94474b62b8SAllan Jude 			xo_emit("{en:list/%s}", sigismember(set, sig) ?
95474b62b8SAllan Jude 			    "true" : "false");
96474b62b8SAllan Jude 			break;
97474b62b8SAllan Jude 		case 'I':
98474b62b8SAllan Jude 			xo_emit("{en:ignore/%s}", sigismember(set, sig) ?
99474b62b8SAllan Jude 			    "true" : "false");
100474b62b8SAllan Jude 			break;
101474b62b8SAllan Jude 		default:
102474b62b8SAllan Jude 			xo_emit("{en:unknown/%s}", sigismember(set, sig) ?
103474b62b8SAllan Jude 			    "true" : "false");
104474b62b8SAllan Jude 			break;
105474b62b8SAllan Jude 	}
106f4646706SKonstantin Belousov }
107f4646706SKonstantin Belousov 
108f4646706SKonstantin Belousov void
1090daf62d9SStanislav Sedov procstat_sigs(struct procstat *prstat __unused, struct kinfo_proc *kipp)
110f4646706SKonstantin Belousov {
111f4646706SKonstantin Belousov 	int j;
112f4646706SKonstantin Belousov 
113f4646706SKonstantin Belousov 	if (!hflag)
114474b62b8SAllan Jude 		xo_emit("{T:/%5s %-16s %-7s %4s}\n", "PID", "COMM", "SIG",
115474b62b8SAllan Jude 		    "FLAGS");
116f4646706SKonstantin Belousov 
117474b62b8SAllan Jude 	xo_emit("{ek:process_id/%5d/%d}", kipp->ki_pid);
118474b62b8SAllan Jude 	xo_emit("{e:command/%-16s/%s}", kipp->ki_comm);
119474b62b8SAllan Jude 	xo_open_container("signals");
120f4646706SKonstantin Belousov 	for (j = 1; j <= _SIG_MAXSIG; j++) {
121474b62b8SAllan Jude 		xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid);
122474b62b8SAllan Jude 		xo_emit("{d:command/%-16s/%s} ", kipp->ki_comm);
123f4646706SKonstantin Belousov 		procstat_print_signame(j);
124474b62b8SAllan Jude 		xo_emit(" ");
125f4646706SKonstantin Belousov 		procstat_print_sig(&kipp->ki_siglist, j, 'P');
126f4646706SKonstantin Belousov 		procstat_print_sig(&kipp->ki_sigignore, j, 'I');
127f4646706SKonstantin Belousov 		procstat_print_sig(&kipp->ki_sigcatch, j, 'C');
128474b62b8SAllan Jude 		procstat_close_signame(j);
129474b62b8SAllan Jude 		xo_emit("\n");
130f4646706SKonstantin Belousov 	}
131474b62b8SAllan Jude 	xo_close_container("signals");
132f4646706SKonstantin Belousov }
133f4646706SKonstantin Belousov 
134f4646706SKonstantin Belousov void
135efade150SMikolaj Golub procstat_threads_sigs(struct procstat *procstat, struct kinfo_proc *kipp)
136f4646706SKonstantin Belousov {
137f4646706SKonstantin Belousov 	struct kinfo_proc *kip;
138efade150SMikolaj Golub 	int j;
139efade150SMikolaj Golub 	unsigned int count, i;
140474b62b8SAllan Jude 	char *threadid;
141f4646706SKonstantin Belousov 
142f4646706SKonstantin Belousov 	if (!hflag)
143474b62b8SAllan Jude 		xo_emit("{T:/%5s %6s %-16s %-7s %4s}\n", "PID", "TID", "COMM",
144f4646706SKonstantin Belousov 		     "SIG", "FLAGS");
145f4646706SKonstantin Belousov 
146efade150SMikolaj Golub 	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
147474b62b8SAllan Jude 	    kipp->ki_pid, &count);
148f4646706SKonstantin Belousov 	if (kip == NULL)
149f4646706SKonstantin Belousov 		return;
150474b62b8SAllan Jude 	xo_emit("{ek:process_id/%5d/%d}", kipp->ki_pid);
151474b62b8SAllan Jude 	xo_emit("{e:command/%-16s/%s}", kipp->ki_comm);
152474b62b8SAllan Jude 	xo_open_container("threads");
153efade150SMikolaj Golub 	kinfo_proc_sort(kip, count);
154efade150SMikolaj Golub 	for (i = 0; i < count; i++) {
155f4646706SKonstantin Belousov 		kipp = &kip[i];
156474b62b8SAllan Jude 		asprintf(&threadid, "%d", kipp->ki_tid);
157474b62b8SAllan Jude 		if (threadid == NULL)
158474b62b8SAllan Jude 			xo_errc(1, ENOMEM, "Failed to allocate memory in "
159474b62b8SAllan Jude 			    "procstat_threads_sigs()");
160474b62b8SAllan Jude 		xo_open_container(threadid);
161474b62b8SAllan Jude 		xo_emit("{e:thread_id/%6d/%d}", kipp->ki_tid);
162474b62b8SAllan Jude 		xo_open_container("signals");
163f4646706SKonstantin Belousov 		for (j = 1; j <= _SIG_MAXSIG; j++) {
164474b62b8SAllan Jude 			xo_emit("{dk:process_id/%5d/%d} ", kipp->ki_pid);
165474b62b8SAllan Jude 			xo_emit("{d:thread_id/%6d/%d} ", kipp->ki_tid);
166474b62b8SAllan Jude 			xo_emit("{d:command/%-16s/%s} ", kipp->ki_comm);
167f4646706SKonstantin Belousov 			procstat_print_signame(j);
168474b62b8SAllan Jude 			xo_emit(" ");
169f4646706SKonstantin Belousov 			procstat_print_sig(&kipp->ki_siglist, j, 'P');
170f4646706SKonstantin Belousov 			procstat_print_sig(&kipp->ki_sigmask, j, 'B');
171474b62b8SAllan Jude 			procstat_close_signame(j);
172474b62b8SAllan Jude 			xo_emit("\n");
173f4646706SKonstantin Belousov 		}
174474b62b8SAllan Jude 		xo_close_container("signals");
175474b62b8SAllan Jude 		xo_close_container(threadid);
176474b62b8SAllan Jude 		free(threadid);
177f4646706SKonstantin Belousov 	}
178474b62b8SAllan Jude 	xo_close_container("threads");
179efade150SMikolaj Golub 	procstat_freeprocs(procstat, kip);
180f4646706SKonstantin Belousov }
181