Add the POSIX sig2str(3) & str2sig(3) calls

Signed-off-by: Ricardo Branco <rbranco@suse.de>
Reviewed by: imp, kib, des, jilles
Pull Request: https://github.com/freebsd/freebsd-src/pull/1696
This commit is contained in:
Ricardo Branco 2025-05-10 22:56:03 +02:00 committed by Warner Losh
parent 6ff5a5bc1a
commit 3d12567133
5 changed files with 180 additions and 2 deletions

View file

@ -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);

View file

@ -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

View file

@ -464,6 +464,8 @@ FBSD_1.8 {
rtld_get_var;
rtld_set_var;
uexterr_gettext;
sig2str;
str2sig;
};
FBSDprivate_1.0 {

View file

@ -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 .

112
lib/libc/gen/sig2str.c Normal file
View file

@ -0,0 +1,112 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2025 Ricardo Branco <rbranco@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);
}