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);
+}

Reply via email to