1#include <signal.h>
2#include <ctype.h>
3#include <string.h>
4#include <stdlib.h>
5#include <stdio.h>
6
7struct signal_name {
8	const char *name;
9	int number;
10};
11
12static const struct signal_name signames[] = {
13	/* POSIX signals */
14	{ "EXIT",       0 },            /* 0 */
15	{ "HUP",        SIGHUP },       /* 1 */
16	{ "INT",        SIGINT },       /* 2 */
17	{ "QUIT",       SIGQUIT },      /* 3 */
18	{ "ILL",        SIGILL },       /* 4 */
19	{ "ABRT",       SIGABRT },      /* 6 */
20	{ "FPE",        SIGFPE },       /* 8 */
21	{ "KILL",       SIGKILL },      /* 9 */
22	{ "SEGV",       SIGSEGV },      /* 11 */
23	{ "PIPE",       SIGPIPE },      /* 13 */
24	{ "ALRM",       SIGALRM },      /* 14 */
25	{ "TERM",       SIGTERM },      /* 15 */
26	{ "USR1",       SIGUSR1 },      /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
27	{ "USR2",       SIGUSR2 },      /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
28	{ "CHLD",       SIGCHLD },      /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
29	{ "CONT",       SIGCONT },      /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
30	{ "STOP",       SIGSTOP },      /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
31	{ "TSTP",       SIGTSTP },      /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
32	{ "TTIN",       SIGTTIN },      /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
33	{ "TTOU",       SIGTTOU },      /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
34	/* Miscellaneous other signals */
35#ifdef SIGTRAP
36	{ "TRAP",       SIGTRAP },      /* 5 */
37#endif
38#ifdef SIGIOT
39	{ "IOT",        SIGIOT },       /* 6, same as SIGABRT */
40#endif
41#ifdef SIGEMT
42	{ "EMT",        SIGEMT },       /* 7 (mips,alpha,sparc*) */
43#endif
44#ifdef SIGBUS
45	{ "BUS",        SIGBUS },       /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
46#endif
47#ifdef SIGSYS
48	{ "SYS",        SIGSYS },       /* 12 (mips,alpha,sparc*) */
49#endif
50#ifdef SIGSTKFLT
51	{ "STKFLT",     SIGSTKFLT },    /* 16 (arm,i386,m68k,ppc) */
52#endif
53#ifdef SIGURG
54	{ "URG",        SIGURG },       /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
55#endif
56#ifdef SIGIO
57	{ "IO",         SIGIO },        /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
58#endif
59#ifdef SIGPOLL
60	{ "POLL",       SIGPOLL },      /* same as SIGIO */
61#endif
62#ifdef SIGCLD
63	{ "CLD",        SIGCLD },       /* same as SIGCHLD (mips) */
64#endif
65#ifdef SIGXCPU
66	{ "XCPU",       SIGXCPU },      /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
67#endif
68#ifdef SIGXFSZ
69	{ "XFSZ",       SIGXFSZ },      /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
70#endif
71#ifdef SIGVTALRM
72	{ "VTALRM",     SIGVTALRM },    /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
73#endif
74#ifdef SIGPROF
75	{ "PROF",       SIGPROF },      /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
76#endif
77#ifdef SIGPWR
78	{ "PWR",        SIGPWR },       /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
79#endif
80#ifdef SIGINFO
81	{ "INFO",       SIGINFO },      /* 29 (alpha) */
82#endif
83#ifdef SIGLOST
84	{ "LOST",       SIGLOST },      /* 29 (arm,i386,m68k,ppc,sparc*) */
85#endif
86#ifdef SIGWINCH
87	{ "WINCH",      SIGWINCH },     /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
88#endif
89#ifdef SIGUNUSED
90	{ "UNUSED",     SIGUNUSED },    /* 31 (arm,i386,m68k,ppc) */
91#endif
92	{0, 0}
93};
94
95/*
96	if str_sig == NULL returned signal name [*signo],
97	if str_sig != NULL - set *signo from signal_name,
98		findings with digit number or with or without SIG-prefix name
99
100	if startnum=0 flag for support finding zero signal,
101		but str_sig="0" always found, (hmm - standart or realize?)
102	if startnum<0 returned reverse signal_number  <-> signal_name
103	if found error - returned NULL
104
105*/
106
107const char *
108u_signal_names(const char *str_sig, int *signo, int startnum)
109{
110	static char retstr[16];
111	const struct signal_name *s = signames;
112	static const char prefix[] = "SIG";
113	const char *sptr;
114
115	if(startnum)
116		s++;
117	if(str_sig==NULL) {
118		while (s->name != 0) {
119			if(s->number == *signo)
120				break;
121			s++;
122		}
123	} else {
124		if (isdigit(((unsigned char)*str_sig))) {
125			char *endp;
126			long int sn = strtol(str_sig, &endp, 10);
127			/* test correct and overflow */
128			if(*endp == 0 && sn >= 0 && sn < NSIG) {
129				*signo = (int)sn;
130				/* test for unnamed */
131				sptr = u_signal_names(0, signo, 0);
132				if(sptr==NULL)
133					return NULL;
134				if(sn!=0)
135					sptr += 3;
136				return sptr;
137			}
138		} else {
139			sptr = str_sig;
140			while (s->name != 0) {
141				if (strcasecmp(s->name, sptr) == 0) {
142					*signo = s->number;
143					if(startnum<0) {
144						sprintf(retstr, "%d", *signo);
145						return retstr;
146					}
147					break;
148				}
149				if(s!=signames && sptr == str_sig &&
150						strncasecmp(sptr, prefix, 3) == 0) {
151					sptr += 3;      /* strlen(prefix) */
152					continue;
153				}
154				sptr = str_sig;
155				s++;
156			}
157		}
158	}
159	if(s->name==0)
160		return NULL;
161	if(s!=signames)
162		strcpy(retstr, prefix);
163	 else
164		retstr[0] = 0;
165	return strcat(retstr, s->name);
166}
167