The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=3d12567133bfb4082a5115f16a71a865ff2af7fb
commit 3d12567133bfb4082a5115f16a71a865ff2af7fb Author: Ricardo Branco <rbra...@suse.de> AuthorDate: 2025-05-10 20:56:03 +0000 Commit: Warner Losh <i...@freebsd.org> CommitDate: 2025-06-11 23:16:22 +0000 Add the POSIX sig2str(3) & str2sig(3) calls Signed-off-by: Ricardo Branco <rbra...@suse.de> Reviewed by: imp, kib, des, jilles Pull Request: https://github.com/freebsd/freebsd-src/pull/1696 --- include/signal.h | 9 ++++ lib/libc/gen/Makefile.inc | 3 ++ lib/libc/gen/Symbol.map | 2 + lib/libc/gen/psignal.3 | 56 ++++++++++++++++++++++- lib/libc/gen/sig2str.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 2 deletions(-) diff --git a/include/signal.h b/include/signal.h index c1d341f317f4..22fefb63568f 100644 --- a/include/signal.h +++ b/include/signal.h @@ -40,6 +40,10 @@ #include <sys/_ucontext.h> #endif +#if __POSIX_VISIBLE >= 202405 || __BSD_VISIBLE +#define SIG2STR_MAX 32 /* size of buffer required for sig2str() */ +#endif + __NULLABILITY_PRAGMA_PUSH #if __BSD_VISIBLE @@ -119,6 +123,11 @@ void psiginfo(const siginfo_t *, const char *); void psignal(int, const char *); #endif +#if __POSIX_VISIBLE >= 202405 || __BSD_VISIBLE +int sig2str(int, char *); +int str2sig(const char * __restrict, int * __restrict); +#endif + #if __BSD_VISIBLE int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right); int sigblock(int); diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 74b18b44e575..65a2b9d19bb6 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -134,6 +134,7 @@ SRCS+= \ setmode.c \ setproctitle.c \ setprogname.c \ + sig2str.c \ siginterrupt.c \ siglist.c \ signal.c \ @@ -473,6 +474,8 @@ MLINKS+=posix_spawn.3 posix_spawnp.3 \ posix_spawnattr_getsigmask.3 posix_spawnattr_setsigmask.3 \ posix_spawnattr_init.3 posix_spawnattr_destroy.3 MLINKS+=psignal.3 psiginfo.3 \ + psignal.3 sig2str.3 \ + psignal.3 str2sig.3 \ psignal.3 strsignal.3 \ psignal.3 sys_siglist.3 \ psignal.3 sys_signame.3 diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index afc277822787..765db07019b5 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -464,6 +464,8 @@ FBSD_1.8 { rtld_get_var; rtld_set_var; uexterr_gettext; + sig2str; + str2sig; }; FBSDprivate_1.0 { diff --git a/lib/libc/gen/psignal.3 b/lib/libc/gen/psignal.3 index 0af5a6706296..098b7b02a9b9 100644 --- a/lib/libc/gen/psignal.3 +++ b/lib/libc/gen/psignal.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd Apr 16, 2025 +.Dd May 10, 2025 .Dt PSIGNAL 3 .Os .Sh NAME @@ -33,7 +33,9 @@ .Nm psiginfo , .Nm strsignal , .Nm sys_siglist , -.Nm sys_signame +.Nm sys_signame , +.Nm sig2str , +.Nm str2sig .Nd system signal messages .Sh LIBRARY .Lb libc @@ -48,6 +50,10 @@ .In string.h .Ft "char *" .Fn strsignal "int sig" +.Ft int +.Fn sig2str "int signum" "char *str" +.Ft int +.Fn str2sig "char *str" "int *pnum" .Sh DESCRIPTION The .Fn psignal @@ -108,10 +114,50 @@ contains a count of the strings in .Va sys_siglist and .Va sys_signame . +.Pp +The +.Fn sig2str +function translates the signal number +.Fa signum +to the signal name, without the +.Dq SIG +prefix, and stores it at the location specified by +.Fa str , +which should be large enough to hold the name and the terminating +.Dv NUL +byte. +The symbol +.Dv SIG2STR_MAX +gives the maximum size in bytes required. +.Pp +The +.Fn str2sig +function translates the signal name +.Fa str +to a signal number and stores it in the location referenced by +.Fa pnum . +The name in +.Fa str +can be either the name of the signal, with or without the +.Dq SIG +prefix, or a decimal number. .Sh SEE ALSO .Xr sigaction 2 , .Xr perror 3 , .Xr strerror 3 +.Sh STANDARDS +The +.Fn psignal +and +.Fn psiginfo +functions are defined by +.St -p1003.1-2008 +, while the +.Fn sig2str +and +.Fn str2sig +functions are defined by +.St -p1003.1-2024 . .Sh HISTORY The .Fn psignal @@ -124,3 +170,9 @@ function appeared in .Nx 6.0 , and .Dx 4.1 . +The +.Fn sig2str +and +.Fn str2sig +functions appeared in +.Fx 15.0 . diff --git a/lib/libc/gen/sig2str.c b/lib/libc/gen/sig2str.c new file mode 100644 index 000000000000..9d0ede0f67fa --- /dev/null +++ b/lib/libc/gen/sig2str.c @@ -0,0 +1,112 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Ricardo Branco <rbra...@suse.de>. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Translate between signal names and numbers + */ +#include "namespace.h" +#include <ctype.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "un-namespace.h" + +static const char rtmin_str[] = "RTMIN"; +static const char rtmax_str[] = "RTMAX"; + +int +sig2str(int signum, char *str) +{ + if (signum <= 0 || signum > SIGRTMAX) + return (-1); + + if (signum < sys_nsig) + (void)strlcpy(str, sys_signame[signum], SIG2STR_MAX); + else if (signum < SIGRTMIN) + (void)snprintf(str, SIG2STR_MAX, "%d", signum); + else if (signum == SIGRTMIN) + (void)strlcpy(str, rtmin_str, SIG2STR_MAX); + else if (signum == SIGRTMAX) + (void)strlcpy(str, rtmax_str, SIG2STR_MAX); + else if (signum <= (SIGRTMIN + SIGRTMAX) / 2) + (void)snprintf(str, SIG2STR_MAX, "%s+%d", + rtmin_str, signum - SIGRTMIN); + else + (void)snprintf(str, SIG2STR_MAX, "%s-%d", + rtmax_str, SIGRTMAX - signum); + + return (0); +} + +int +str2sig(const char * restrict str, int * restrict pnum) +{ + const char *errstr; + long long n; + int sig; + int rtend = sizeof(rtmin_str) - 1; + + if (strncasecmp(str, "SIG", 3) == 0) + str += 3; + + if (strncasecmp(str, rtmin_str, sizeof(rtmin_str) - 1) == 0 || + strncasecmp(str, rtmax_str, sizeof(rtmax_str) - 1) == 0) { + sig = (toupper(str[4]) == 'X') ? SIGRTMAX : SIGRTMIN; + n = 0; + if (str[rtend] == '+' || str[rtend] == '-') { + n = strtonum(str + rtend, INT_MIN, INT_MAX, &errstr); + if (n == 0 || errstr != NULL) + return (-1); + } else if (str[rtend] != '\0') { + return (-1); + } + sig += (int)n; + if (sig < SIGRTMIN || sig > SIGRTMAX) + return (-1); + *pnum = sig; + return (0); + } + + if (isdigit((unsigned char)str[0])) { + n = strtonum(str, 1, SIGRTMAX, &errstr); + if (errstr == NULL) { + *pnum = (int)n; + return (0); + } + } + + for (sig = 1; sig < sys_nsig; sig++) { + if (strcasecmp(sys_signame[sig], str) == 0) { + *pnum = sig; + return (0); + } + } + + return (-1); +}