xref: /freebsd/lib/libc/gen/sig2str.c (revision b0334450aa527ccbac7a3c37d1ba75ef96c7be91)
13d125671SRicardo Branco /*-
23d125671SRicardo Branco  * SPDX-License-Identifier: BSD-2-Clause
33d125671SRicardo Branco  *
43d125671SRicardo Branco  * Copyright (c) 2025 Ricardo Branco <rbranco@suse.de>.
53d125671SRicardo Branco  *
63d125671SRicardo Branco  * Redistribution and use in source and binary forms, with or without
73d125671SRicardo Branco  * modification, are permitted provided that the following conditions
83d125671SRicardo Branco  * are met:
93d125671SRicardo Branco  * 1. Redistributions of source code must retain the above copyright
103d125671SRicardo Branco  *      notice, this list of conditions and the following disclaimer.
113d125671SRicardo Branco  * 2. Redistributions in binary form must reproduce the above copyright
123d125671SRicardo Branco  *      notice, this list of conditions and the following disclaimer in the
133d125671SRicardo Branco  *      documentation and/or other materials provided with the distribution.
143d125671SRicardo Branco  *
153d125671SRicardo Branco  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
163d125671SRicardo Branco  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
173d125671SRicardo Branco  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
183d125671SRicardo Branco  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
193d125671SRicardo Branco  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
203d125671SRicardo Branco  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
213d125671SRicardo Branco  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
223d125671SRicardo Branco  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
233d125671SRicardo Branco  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
243d125671SRicardo Branco  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
253d125671SRicardo Branco  * SUCH DAMAGE.
263d125671SRicardo Branco  */
273d125671SRicardo Branco 
283d125671SRicardo Branco /*
293d125671SRicardo Branco  * Translate between signal names and numbers
303d125671SRicardo Branco  */
313d125671SRicardo Branco #include "namespace.h"
323d125671SRicardo Branco #include <ctype.h>
333d125671SRicardo Branco #include <limits.h>
343d125671SRicardo Branco #include <signal.h>
353d125671SRicardo Branco #include <stdio.h>
363d125671SRicardo Branco #include <stdlib.h>
373d125671SRicardo Branco #include <string.h>
38*b0334450SRicardo Branco #include <ssp/ssp.h>
393d125671SRicardo Branco #include "un-namespace.h"
403d125671SRicardo Branco 
413d125671SRicardo Branco static const char rtmin_str[] = "RTMIN";
423d125671SRicardo Branco static const char rtmax_str[] = "RTMAX";
433d125671SRicardo Branco 
443d125671SRicardo Branco int
__ssp_real(sig2str)45*b0334450SRicardo Branco __ssp_real(sig2str)(int signum, char *str)
463d125671SRicardo Branco {
473d125671SRicardo Branco 	if (signum <= 0 || signum > SIGRTMAX)
483d125671SRicardo Branco 		return (-1);
493d125671SRicardo Branco 
503d125671SRicardo Branco 	if (signum < sys_nsig)
513d125671SRicardo Branco 		(void)strlcpy(str, sys_signame[signum], SIG2STR_MAX);
523d125671SRicardo Branco 	else if (signum < SIGRTMIN)
533d125671SRicardo Branco 		(void)snprintf(str, SIG2STR_MAX, "%d", signum);
543d125671SRicardo Branco 	else if (signum == SIGRTMIN)
553d125671SRicardo Branco 		(void)strlcpy(str, rtmin_str, SIG2STR_MAX);
563d125671SRicardo Branco 	else if (signum == SIGRTMAX)
573d125671SRicardo Branco 		(void)strlcpy(str, rtmax_str, SIG2STR_MAX);
583d125671SRicardo Branco 	else if (signum <= (SIGRTMIN + SIGRTMAX) / 2)
593d125671SRicardo Branco 		(void)snprintf(str, SIG2STR_MAX, "%s+%d",
603d125671SRicardo Branco 		    rtmin_str, signum - SIGRTMIN);
613d125671SRicardo Branco 	else
623d125671SRicardo Branco 		(void)snprintf(str, SIG2STR_MAX, "%s-%d",
633d125671SRicardo Branco 		    rtmax_str, SIGRTMAX - signum);
643d125671SRicardo Branco 
653d125671SRicardo Branco 	return (0);
663d125671SRicardo Branco }
673d125671SRicardo Branco 
683d125671SRicardo Branco int
str2sig(const char * restrict str,int * restrict pnum)693d125671SRicardo Branco str2sig(const char * restrict str, int * restrict pnum)
703d125671SRicardo Branco {
713d125671SRicardo Branco 	const char *errstr;
723d125671SRicardo Branco 	long long n;
733d125671SRicardo Branco 	int sig;
743d125671SRicardo Branco 	int rtend = sizeof(rtmin_str) - 1;
753d125671SRicardo Branco 
763d125671SRicardo Branco 	if (strncasecmp(str, "SIG", 3) == 0)
773d125671SRicardo Branco 		str += 3;
783d125671SRicardo Branco 
793d125671SRicardo Branco 	if (strncasecmp(str, rtmin_str, sizeof(rtmin_str) - 1) == 0 ||
803d125671SRicardo Branco 	    strncasecmp(str, rtmax_str, sizeof(rtmax_str) - 1) == 0) {
813d125671SRicardo Branco 		sig = (toupper(str[4]) == 'X') ? SIGRTMAX : SIGRTMIN;
823d125671SRicardo Branco 		n = 0;
833d125671SRicardo Branco 		if (str[rtend] == '+' || str[rtend] == '-') {
843d125671SRicardo Branco 			n = strtonum(str + rtend, INT_MIN, INT_MAX, &errstr);
853d125671SRicardo Branco 			if (n == 0 || errstr != NULL)
863d125671SRicardo Branco 				return (-1);
873d125671SRicardo Branco 		} else if (str[rtend] != '\0') {
883d125671SRicardo Branco 			return (-1);
893d125671SRicardo Branco 		}
903d125671SRicardo Branco 		sig += (int)n;
913d125671SRicardo Branco 		if (sig < SIGRTMIN || sig > SIGRTMAX)
923d125671SRicardo Branco 			return (-1);
933d125671SRicardo Branco 		*pnum = sig;
943d125671SRicardo Branco 		return (0);
953d125671SRicardo Branco 	}
963d125671SRicardo Branco 
973d125671SRicardo Branco 	if (isdigit((unsigned char)str[0])) {
983d125671SRicardo Branco 		n = strtonum(str, 1, SIGRTMAX, &errstr);
993d125671SRicardo Branco 		if (errstr == NULL) {
1003d125671SRicardo Branco 			*pnum = (int)n;
1013d125671SRicardo Branco 			return (0);
1023d125671SRicardo Branco 		}
1033d125671SRicardo Branco 	}
1043d125671SRicardo Branco 
1053d125671SRicardo Branco 	for (sig = 1; sig < sys_nsig; sig++) {
1063d125671SRicardo Branco 		if (strcasecmp(sys_signame[sig], str) == 0) {
1073d125671SRicardo Branco 			*pnum = sig;
1083d125671SRicardo Branco 			return (0);
1093d125671SRicardo Branco 		}
1103d125671SRicardo Branco 	}
1113d125671SRicardo Branco 
1123d125671SRicardo Branco 	return (-1);
1133d125671SRicardo Branco }
114