Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / signal / sig2str.c
blobf4df913e2d535748bdb7c951d3c21d99292e0a1f
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (C) 2021 Matthew Joyce
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
28 FUNCTION
29 <<sig2str>>, <<str2sig>>---Translate between signal number and name
31 INDEX
32 sig2str
33 INDEX
34 str2sig
36 SYNOPSIS
37 #include <signal.h>
38 int sig2str(int <[signum]>, char *<[str]>);
40 int str2sig(const char *restrict <[str]>, int *restrict <[pnum]>);
42 DESCRIPTION
43 The <<sig2str>> function translates the signal number specified by <[signum]> to
44 a signal name and stores this string in the location specified by <[str]>. The
45 application must ensure that <[str]> points to a location that can store the
46 string including the terminating null byte. The symbolic constant
47 <[SIG2STR_MAX]> defined in `<<signal.h>>' gives the maximum number of bytes
48 required.
50 The <<str2sig>> function translates the signal name in the string pointed to by
51 <[str]> to a signal number and stores this value in the location specified by
52 <[pnum]>.
54 RETURNS
55 <<sig2str>> returns <<0>> if <[signum]>> is a valid, supported signal number.
56 Otherwise, it returns <<-1>>.
58 <<str2sig>> returns <<0>> if it stores a value in the location pointed to by
59 <[pnum]>. Otherwise it returns <<-1>>.
62 #include <signal.h>
63 #include <string.h>
64 #include <stdio.h>
65 #include <stdlib.h>
67 #define SPACES_TO_N 6 /* Allows indexing to RT Signal number in str2sig */
68 #define NUM_OF_SIGS (sizeof(sig_array) / sizeof(sig_name_and_num))
70 typedef struct sig_name_and_num {
71 const char *sig_name;
72 const int sig_num;
73 } sig_name_and_num;
75 static const sig_name_and_num sig_array[] = {
76 { "EXIT", 0 },
77 #ifdef SIGHUP
78 { "HUP", SIGHUP },
79 #endif
80 #ifdef SIGINT
81 { "INT", SIGINT },
82 #endif
83 #ifdef SIGQUIT
84 { "QUIT", SIGQUIT },
85 #endif
86 #ifdef SIGILL
87 { "ILL", SIGILL },
88 #endif
89 #ifdef SIGTRAP
90 { "TRAP", SIGTRAP },
91 #endif
92 #ifdef SIGABRT
93 { "ABRT", SIGABRT },
94 #endif
95 #ifdef SIGIOT
96 { "IOT", SIGIOT},
97 #endif
98 #ifdef SIGEMT
99 { "EMT", SIGEMT },
100 #endif
101 #ifdef SIGFPE
102 { "FPE", SIGFPE },
103 #endif
104 #ifdef SIGKILL
105 { "KILL", SIGKILL },
106 #endif
107 #ifdef SIGBUS
108 { "BUS", SIGBUS },
109 #endif
110 #ifdef SIGSEGV
111 { "SEGV", SIGSEGV },
112 #endif
113 #ifdef SIGSYS
114 { "SYS", SIGSYS },
115 #endif
116 #ifdef SIGPIPE
117 { "PIPE", SIGPIPE },
118 #endif
119 #ifdef SIGALRM
120 { "ALRM", SIGALRM },
121 #endif
122 #ifdef SIGTERM
123 { "TERM", SIGTERM },
124 #endif
125 #ifdef SIGURG
126 { "URG", SIGURG },
127 #endif
128 #ifdef SIGSTOP
129 { "STOP", SIGSTOP },
130 #endif
131 #ifdef SIGTSTP
132 { "TSTP", SIGTSTP },
133 #endif
134 #ifdef SIGCONT
135 { "CONT", SIGCONT },
136 #endif
137 #ifdef SIGCHLD
138 { "CHLD", SIGCHLD },
139 #endif
140 #ifdef SIGCLD
141 { "CLD", SIGCLD },
142 #endif
143 #ifdef SIGTTIN
144 { "TTIN", SIGTTIN },
145 #endif
146 #ifdef SIGTTOU
147 { "TTOU", SIGTTOU },
148 #endif
149 #ifdef SIGIO
150 { "IO", SIGIO },
151 #endif
152 #ifdef SIGPOLL
153 { "POLL", SIGPOLL },
154 #endif
155 #ifdef SIGWINCH
156 { "WINCH", SIGWINCH },
157 #endif
158 #ifdef SIGUSR1
159 { "USR1", SIGUSR1 },
160 #endif
161 #ifdef SIGUSR2
162 { "USR2", SIGUSR2 },
163 #endif
164 #ifdef SIGPWR
165 { "PWR", SIGPWR },
166 #endif
167 #ifdef SIGXCPU
168 { "XCPU", SIGXCPU },
169 #endif
170 #ifdef SIGXFSZ
171 { "XFSZ", SIGXFSZ },
172 #endif
173 #ifdef SIGVTALRM
174 { "VTALRM", SIGVTALRM },
175 #endif
176 #ifdef SIGPROF
177 { "PROF", SIGPROF },
178 #endif
179 #ifdef SIGLOST
180 { "LOST", SIGLOST },
181 #endif
182 /* The Issue 8 standard requires that SIGRTMIN and SIGRTMAX be included
183 * as valid results to be saved from calls to sig2str/str2sig. */
184 #ifdef SIGRTMIN
185 { "RTMIN", SIGRTMIN },
186 #endif
187 #ifdef SIGRTMAX
188 { "RTMAX", SIGRTMAX }
189 #endif
193 sig2str(int signum, char *str)
195 const sig_name_and_num *sptr;
197 #if defined (SIGRTMIN) && defined (SIGRTMAX)
198 /* If signum falls in lower half of the real time signals range, define
199 * the saved str value as "RTMIN+n" according to the Issue 8 standard */
200 if ((SIGRTMIN + 1) <= signum &&
201 signum <= (SIGRTMIN + SIGRTMAX) / 2) {
202 sprintf(str, "RTMIN+%d", (signum-SIGRTMIN));
203 return 0;
206 /* If signum falls in upper half of the real time signals range, define
207 * the saved str value as "RTMAX-m" according to the Issue 8 standard */
208 if ((((SIGRTMIN + SIGRTMAX) / 2) + 1) <= signum &&
209 signum <= (SIGRTMAX - 1)) {
210 sprintf(str, "RTMAX-%d", (SIGRTMAX - signum));
211 return 0;
213 #endif
215 /* Otherwise, search for signal matching signum in sig_array. If found,
216 * save its string value in str. */
217 for (sptr = sig_array; sptr < &sig_array[NUM_OF_SIGS]; sptr++) {
218 if (sptr->sig_num == signum) {
219 strcpy(str, sptr->sig_name);
220 return 0;
224 /* If signum is not a recognized signal number, return -1 */
225 return -1;
229 str2sig(const char *__restrict str, int *__restrict pnum)
231 unsigned long j = 0;
232 char *endp;
233 const sig_name_and_num *sptr;
234 unsigned long is_valid_decimal;
236 #if defined (SIGRTMIN) && defined (SIGRTMAX)
237 /* i686 Cygwin only supports one RT signal. For this case, skip checks
238 * for "RTMIN+n" and "RTMAX-m". */
239 if (SIGRTMIN != SIGRTMAX) {
241 /* If str is in RT signal range, get number of of RT signal, save it as an
242 * integer. */
243 if (strncmp(str, "RTMIN+", SPACES_TO_N) == 0) {
244 j = strtoul(&str[SPACES_TO_N], &endp, 10);
246 /* If number is valid, save it in pnum. */
247 if (*endp == '\0') {
248 if (1 <= j &&
249 j <= ((SIGRTMAX - SIGRTMIN)-1)) {
250 *pnum = (SIGRTMIN + j);
251 return 0;
253 return -1;
255 return -1;
258 /* If str is in RT signal range, get number of of RT signal, save it as an
259 * integer. */
260 if (strncmp(str, "RTMAX-", SPACES_TO_N) == 0) {
261 j = strtoul(&str[SPACES_TO_N], &endp, 10); // and endptr null check
263 /* If number is valid, save it in pnum. */
264 if (*endp == '\0') {
265 if (1 <= j &&
266 j <= ((SIGRTMAX - SIGRTMIN)-1)) {
267 *pnum = (SIGRTMAX - j);
268 return 0;
270 return -1;
272 return -1;
275 #endif
277 /*If str is a valid signal name, save its corresponding number in pnum. */
278 for (sptr = sig_array; sptr < &sig_array[NUM_OF_SIGS]; sptr++) {
279 if (strcmp(sptr->sig_name, str) == 0) {
280 *pnum = sptr->sig_num;
281 return 0;
285 /* str was not found in sig_array. Check whether str is a string
286 * representation of a valid integer. */
287 is_valid_decimal = strtoul(str, &endp, 10);
289 if (*endp != '\0') {
290 return -1;
293 /* If str is a representation of a decimal value, save its integer value
294 * in pnum. */
295 if (1 <= is_valid_decimal &&
296 is_valid_decimal <= (NSIG - 1)) {
297 *pnum = is_valid_decimal;
298 return 0;
301 return -1;