1 /* SPDX-License-Identifier: BSD-2-Clause */
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
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.
29 <<sig2str>>, <<str2sig>>---Translate between signal number and name
38 int sig2str(int <[signum]>, char *<[str]>);
40 int str2sig(const char *restrict <[str]>, int *restrict <[pnum]>);
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
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
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>>.
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
{
75 static const sig_name_and_num sig_array
[] = {
156 { "WINCH", SIGWINCH
},
174 { "VTALRM", SIGVTALRM
},
182 /* The Issue 8 standard requires that SIGRTMIN and SIGRTMAX be included
183 * as valid results to be saved from calls to sig2str/str2sig. */
185 { "RTMIN", SIGRTMIN
},
188 { "RTMAX", SIGRTMAX
}
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
));
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
));
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
);
224 /* If signum is not a recognized signal number, return -1 */
229 str2sig(const char *__restrict str
, int *__restrict pnum
)
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
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. */
249 j
<= ((SIGRTMAX
- SIGRTMIN
)-1)) {
250 *pnum
= (SIGRTMIN
+ j
);
258 /* If str is in RT signal range, get number of of RT signal, save it as an
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. */
266 j
<= ((SIGRTMAX
- SIGRTMIN
)-1)) {
267 *pnum
= (SIGRTMAX
- j
);
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
;
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);
293 /* If str is a representation of a decimal value, save its integer value
295 if (1 <= is_valid_decimal
&&
296 is_valid_decimal
<= (NSIG
- 1)) {
297 *pnum
= is_valid_decimal
;