* [musl] [PATCH v3 1/3] src/signal/sys_signame.c: create hidden value-name table of signals @ 2024-08-09 15:34 contact 2024-08-09 15:34 ` [musl] [PATCH v3 2/3] signal: add sig2str(3) from POSIX.1-2024 contact 2024-08-09 15:34 ` [musl] [PATCH v3 3/3] signal: add str2sig(3) " contact 0 siblings, 2 replies; 5+ messages in thread From: contact @ 2024-08-09 15:34 UTC (permalink / raw) To: musl; +Cc: Haelwenn (lanodan) Monnier From: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me> --- src/include/signal.h | 2 ++ src/signal/sys_signame.c | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/signal/sys_signame.c diff --git a/src/include/signal.h b/src/include/signal.h index bb566784..6bbc51d9 100644 --- a/src/include/signal.h +++ b/src/include/signal.h @@ -11,4 +11,6 @@ hidden void __restore_sigs(void *); hidden void __get_handler_set(sigset_t *); +hidden extern const char __sys_signame[SIGSYS+1][sizeof("STKFLT")]; + #endif diff --git a/src/signal/sys_signame.c b/src/signal/sys_signame.c new file mode 100644 index 00000000..9b30c1a1 --- /dev/null +++ b/src/signal/sys_signame.c @@ -0,0 +1,44 @@ +#include <signal.h> + +#define SIG(s) [SIG##s] = #s +const char __sys_signame[SIGSYS+1][sizeof("STKFLT")] = { + SIG(HUP), + SIG(INT), + SIG(QUIT), + SIG(ILL), + SIG(TRAP), + SIG(ABRT), + SIG(BUS), + SIG(FPE), + SIG(KILL), + SIG(USR1), + SIG(SEGV), + SIG(USR2), + SIG(PIPE), + SIG(ALRM), + SIG(TERM), +#if defined(SIGSTKFLT) + SIG(STKFLT), +#endif +#if defined(SIGEMT) + SIG(EMT), +#endif + SIG(CHLD), + SIG(CONT), + SIG(STOP), + SIG(TSTP), + SIG(TTIN), + SIG(TTOU), + SIG(URG), + SIG(XCPU), + SIG(XFSZ), + SIG(VTALRM), + SIG(PROF), + SIG(WINCH), + SIG(IO), +#if SIGPOLL != SIGIO + SIG(POLL), +#endif + SIG(PWR), + SIG(SYS) +}; -- 2.44.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [musl] [PATCH v3 2/3] signal: add sig2str(3) from POSIX.1-2024 2024-08-09 15:34 [musl] [PATCH v3 1/3] src/signal/sys_signame.c: create hidden value-name table of signals contact @ 2024-08-09 15:34 ` contact 2024-08-09 15:34 ` [musl] [PATCH v3 3/3] signal: add str2sig(3) " contact 1 sibling, 0 replies; 5+ messages in thread From: contact @ 2024-08-09 15:34 UTC (permalink / raw) To: musl; +Cc: Haelwenn (lanodan) Monnier From: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me> --- include/signal.h | 5 +++++ src/signal/sig2str.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/signal/sig2str.c diff --git a/include/signal.h b/include/signal.h index c347f861..94ac29b1 100644 --- a/include/signal.h +++ b/include/signal.h @@ -233,6 +233,11 @@ int pthread_kill(pthread_t, int); void psiginfo(const siginfo_t *, const char *); void psignal(int, const char *); +// SIG2STR_MAX needs to at least fit "RTMIN+nn" (9 bytes) +// Bumped to 13 to be safe if a case like "SIGRTMIN+nnn" happens +#define SIG2STR_MAX 13 +int sig2str(int signum, char *str); + #endif #if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) diff --git a/src/signal/sig2str.c b/src/signal/sig2str.c new file mode 100644 index 00000000..989d3645 --- /dev/null +++ b/src/signal/sig2str.c @@ -0,0 +1,34 @@ +#include <signal.h> +#include <string.h> + +int sig2str(int sig, char *str) +{ + if (sig <= 0) return -1; + + if (sig <= SIGSYS) + return (strcpy(str, __sys_signame[sig]), 0); + + if (sig == SIGRTMIN) + return (strcpy(str, "RTMIN"), 0); + if (sig == SIGRTMAX) + return (strcpy(str, "RTMAX"), 0); + + if (sig > SIGRTMIN && sig <= SIGRTMAX) + { + strcpy(str, "RTMIN+"); + int sigrt = sig-SIGRTMIN; + + char *s = str+6; + if (sigrt>=10) + { + *s++ = '0' + sigrt/10; + sigrt %= 10; + } + *s++ = '0' + sigrt; + *s = '\0'; + + return 0; + } + + return -1; +} -- 2.44.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [musl] [PATCH v3 3/3] signal: add str2sig(3) from POSIX.1-2024 2024-08-09 15:34 [musl] [PATCH v3 1/3] src/signal/sys_signame.c: create hidden value-name table of signals contact 2024-08-09 15:34 ` [musl] [PATCH v3 2/3] signal: add sig2str(3) from POSIX.1-2024 contact @ 2024-08-09 15:34 ` contact 2024-08-11 0:43 ` Rich Felker 1 sibling, 1 reply; 5+ messages in thread From: contact @ 2024-08-09 15:34 UTC (permalink / raw) To: musl; +Cc: Haelwenn (lanodan) Monnier From: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me> --- include/signal.h | 1 + src/signal/str2sig.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/signal/str2sig.c diff --git a/include/signal.h b/include/signal.h index 94ac29b1..5451424d 100644 --- a/include/signal.h +++ b/include/signal.h @@ -237,6 +237,7 @@ void psignal(int, const char *); // Bumped to 13 to be safe if a case like "SIGRTMIN+nnn" happens #define SIG2STR_MAX 13 int sig2str(int signum, char *str); +int str2sig(const char *__restrict str, int *__restrict pnum); #endif diff --git a/src/signal/str2sig.c b/src/signal/str2sig.c new file mode 100644 index 00000000..e4c17c57 --- /dev/null +++ b/src/signal/str2sig.c @@ -0,0 +1,54 @@ +#include <signal.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <ctype.h> + +int str2sig(const char *restrict str, int *restrict pnum) +{ + if (str[0] == '\0') return -1; + + errno = 0; + long signum = strtol(str, NULL, 10); + if (errno == 0 && signum < _NSIG) return (*pnum = signum, 0); + + if (strnlen(str, sizeof *__sys_signame) <= sizeof *__sys_signame) + for (int i = 0; i < sizeof __sys_signame/sizeof *__sys_signame; i++) + if (strncmp(str, __sys_signame[i], sizeof *__sys_signame) == 0) + return (*pnum = i, 0); + + // signal aliases + if (strcmp(str, "IOT") == 0) + return (*pnum = SIGIOT, 0); + if (strcmp(str, "UNUSED") == 0) + return (*pnum = SIGUNUSED, 0); +#if SIGPOLL == SIGIO + if (strcmp(str, "POLL") == 0) + return (*pnum = SIGPOLL, 0); +#endif + + if (strcmp(str, "RTMIN") == 0) + return (*pnum = SIGRTMIN, 0); + if (strcmp(str, "RTMAX") == 0) + return (*pnum = SIGRTMAX, 0); + + if (strncmp(str, "RTMIN+", 6) == 0 || strncmp(str, "RTMAX-", 6) == 0) + { + if(!isdigit(str[6])) return -1; + + int sigrt = str[6]-'0'; + + if(str[7] != '\0') + { + if(!isdigit(str[7])) return -1; + + sigrt *= 10; + sigrt += str[7]-'0'; + } + + *pnum = str[5] == '+' ? SIGRTMIN + sigrt : SIGRTMAX - sigrt; + return 0; + } + + return -1; +} -- 2.44.2 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [musl] [PATCH v3 3/3] signal: add str2sig(3) from POSIX.1-2024 2024-08-09 15:34 ` [musl] [PATCH v3 3/3] signal: add str2sig(3) " contact @ 2024-08-11 0:43 ` Rich Felker 2024-08-11 2:54 ` Rich Felker 0 siblings, 1 reply; 5+ messages in thread From: Rich Felker @ 2024-08-11 0:43 UTC (permalink / raw) To: contact; +Cc: musl A few things I didn't catch before: On Fri, Aug 09, 2024 at 05:34:23PM +0200, contact@hacktivis.me wrote: > From: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me> > > --- > include/signal.h | 1 + > src/signal/str2sig.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 55 insertions(+) > create mode 100644 src/signal/str2sig.c > > diff --git a/include/signal.h b/include/signal.h > index 94ac29b1..5451424d 100644 > --- a/include/signal.h > +++ b/include/signal.h > @@ -237,6 +237,7 @@ void psignal(int, const char *); > // Bumped to 13 to be safe if a case like "SIGRTMIN+nnn" happens > #define SIG2STR_MAX 13 > int sig2str(int signum, char *str); > +int str2sig(const char *__restrict str, int *__restrict pnum); As a matter of conformance, declarations in public headers can't have non-reserved identifiers like str or pnum in them (these might already have been #defined'd by the application). As a matter of policy, we just don't use argument names or other "creative" content (including comments) in the public headers at all, mainly because the headers have been intended to be statements of fact not subject to copyright (so a dynamic program using them is not a derived work and doesn't rely on license at all). (There might be a few places where that's not entirely followed, but if so they should be fixed.) > #endif > > diff --git a/src/signal/str2sig.c b/src/signal/str2sig.c > new file mode 100644 > index 00000000..e4c17c57 > --- /dev/null > +++ b/src/signal/str2sig.c > @@ -0,0 +1,54 @@ > +#include <signal.h> > +#include <string.h> > +#include <errno.h> > +#include <stdlib.h> > +#include <ctype.h> > + > +int str2sig(const char *restrict str, int *restrict pnum) > +{ > + if (str[0] == '\0') return -1; > + > + errno = 0; > + long signum = strtol(str, NULL, 10); > + if (errno == 0 && signum < _NSIG) return (*pnum = signum, 0); I don't think the errno check is either necessary or sufficient. As written, this code won't reject something like "12x". Generally, you need to pass a pend argument, like: char *end; long signum = strtol(str, &end, 10); if (!*end && signum < _NSIG) ... which checks that the whole input was consumed, and thereby also that there was no error except possible range overflow (which would be caught by range checks). However there's also a missing range check for negative values. This could probably be handled by use of an unsigned type here, but unless the intent is to accept inputs starting with + or -, the entire strtol path should probably only be attempted if (isdigit(str[0])), in which case negative can't happen. > + if (strnlen(str, sizeof *__sys_signame) <= sizeof *__sys_signame) > + for (int i = 0; i < sizeof __sys_signame/sizeof *__sys_signame; i++) > + if (strncmp(str, __sys_signame[i], sizeof *__sys_signame) == 0) > + return (*pnum = i, 0); I think the indexing for __sys_signame could be adjusted by 1 so there's not an unused slot 0. The entries could also be 6-byte rather than 7-byte. > + // signal aliases > + if (strcmp(str, "IOT") == 0) > + return (*pnum = SIGIOT, 0); > + if (strcmp(str, "UNUSED") == 0) > + return (*pnum = SIGUNUSED, 0); > +#if SIGPOLL == SIGIO > + if (strcmp(str, "POLL") == 0) > + return (*pnum = SIGPOLL, 0); > +#endif > + > + if (strcmp(str, "RTMIN") == 0) > + return (*pnum = SIGRTMIN, 0); > + if (strcmp(str, "RTMAX") == 0) > + return (*pnum = SIGRTMAX, 0); > + > + if (strncmp(str, "RTMIN+", 6) == 0 || strncmp(str, "RTMAX-", 6) == 0) > + { > + if(!isdigit(str[6])) return -1; > + > + int sigrt = str[6]-'0'; > + > + if(str[7] != '\0') > + { > + if(!isdigit(str[7])) return -1; > + > + sigrt *= 10; > + sigrt += str[7]-'0'; > + } At this point you're missing a check that there's not further junk (or more digits) after the second one. It could be something like: + if(!isdigit(str[7]) || str[8]) return -1; This isn't highly important, but the style str[8] vs str[8]!='\0' is generally preferred in musl. Rich ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [musl] [PATCH v3 3/3] signal: add str2sig(3) from POSIX.1-2024 2024-08-11 0:43 ` Rich Felker @ 2024-08-11 2:54 ` Rich Felker 0 siblings, 0 replies; 5+ messages in thread From: Rich Felker @ 2024-08-11 2:54 UTC (permalink / raw) To: contact; +Cc: musl On Sat, Aug 10, 2024 at 08:43:15PM -0400, Rich Felker wrote: > A few things I didn't catch before: > > On Fri, Aug 09, 2024 at 05:34:23PM +0200, contact@hacktivis.me wrote: > > From: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me> > > > > --- > > include/signal.h | 1 + > > src/signal/str2sig.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ > > 2 files changed, 55 insertions(+) > > create mode 100644 src/signal/str2sig.c > > > > diff --git a/include/signal.h b/include/signal.h > > index 94ac29b1..5451424d 100644 > > --- a/include/signal.h > > +++ b/include/signal.h > > @@ -237,6 +237,7 @@ void psignal(int, const char *); > > // Bumped to 13 to be safe if a case like "SIGRTMIN+nnn" happens > > #define SIG2STR_MAX 13 > > int sig2str(int signum, char *str); > > +int str2sig(const char *__restrict str, int *__restrict pnum); > > As a matter of conformance, declarations in public headers can't have > non-reserved identifiers like str or pnum in them (these might already > have been #defined'd by the application). As a matter of policy, we > just don't use argument names or other "creative" content (including > comments) in the public headers at all, mainly because the headers > have been intended to be statements of fact not subject to copyright > (so a dynamic program using them is not a derived work and doesn't > rely on license at all). > > (There might be a few places where that's not entirely followed, but > if so they should be fixed.) > > > #endif > > > > diff --git a/src/signal/str2sig.c b/src/signal/str2sig.c > > new file mode 100644 > > index 00000000..e4c17c57 > > --- /dev/null > > +++ b/src/signal/str2sig.c > > @@ -0,0 +1,54 @@ > > +#include <signal.h> > > +#include <string.h> > > +#include <errno.h> > > +#include <stdlib.h> > > +#include <ctype.h> > > + > > +int str2sig(const char *restrict str, int *restrict pnum) > > +{ > > + if (str[0] == '\0') return -1; > > + > > + errno = 0; > > + long signum = strtol(str, NULL, 10); > > + if (errno == 0 && signum < _NSIG) return (*pnum = signum, 0); > > I don't think the errno check is either necessary or sufficient. As > written, this code won't reject something like "12x". Generally, you > need to pass a pend argument, like: > > char *end; > long signum = strtol(str, &end, 10); > if (!*end && signum < _NSIG) ... > > which checks that the whole input was consumed, and thereby also that > there was no error except possible range overflow (which would be > caught by range checks). > > However there's also a missing range check for negative values. This > could probably be handled by use of an unsigned type here, but unless > the intent is to accept inputs starting with + or -, the entire strtol > path should probably only be attempted if (isdigit(str[0])), in which > case negative can't happen. > > > + if (strnlen(str, sizeof *__sys_signame) <= sizeof *__sys_signame) > > + for (int i = 0; i < sizeof __sys_signame/sizeof *__sys_signame; i++) > > + if (strncmp(str, __sys_signame[i], sizeof *__sys_signame) == 0) > > + return (*pnum = i, 0); > > I think the indexing for __sys_signame could be adjusted by 1 so > there's not an unused slot 0. The entries could also be 6-byte rather > than 7-byte. > > > + // signal aliases > > + if (strcmp(str, "IOT") == 0) > > + return (*pnum = SIGIOT, 0); > > + if (strcmp(str, "UNUSED") == 0) > > + return (*pnum = SIGUNUSED, 0); > > +#if SIGPOLL == SIGIO > > + if (strcmp(str, "POLL") == 0) > > + return (*pnum = SIGPOLL, 0); > > +#endif > > + > > + if (strcmp(str, "RTMIN") == 0) > > + return (*pnum = SIGRTMIN, 0); > > + if (strcmp(str, "RTMAX") == 0) > > + return (*pnum = SIGRTMAX, 0); > > + > > + if (strncmp(str, "RTMIN+", 6) == 0 || strncmp(str, "RTMAX-", 6) == 0) > > + { > > + if(!isdigit(str[6])) return -1; > > + > > + int sigrt = str[6]-'0'; > > + > > + if(str[7] != '\0') > > + { > > + if(!isdigit(str[7])) return -1; > > + > > + sigrt *= 10; > > + sigrt += str[7]-'0'; > > + } > > At this point you're missing a check that there's not further junk (or > more digits) after the second one. It could be something like: > > + if(!isdigit(str[7]) || str[8]) return -1; > > This isn't highly important, but the style str[8] vs str[8]!='\0' is > generally preferred in musl. OK, I've finally gone and dug up and read the specification: https://pubs.opengroup.org/onlinepubs/9799919799/functions/sig2str.html and it requires: "If str points to a string of the form "RTMIN+n", where n is a decimal representation of a number between 1 and SIGRTMAX-SIGRTMIN-1 inclusive, the stored value shall be equal to SIGRTMIN+n. "If str points to a string of the form "RTMAX-n", where n is a decimal representation of a number between 1 and SIGRTMAX-SIGRTMIN-1 inclusive, the stored value shall be equal to SIGRTMAX-n." So there is no requirement that the decimal number be in shortest form. As such this needs a loop or strtol (after checking isdigit). Rich ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-08-11 2:54 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2024-08-09 15:34 [musl] [PATCH v3 1/3] src/signal/sys_signame.c: create hidden value-name table of signals contact 2024-08-09 15:34 ` [musl] [PATCH v3 2/3] signal: add sig2str(3) from POSIX.1-2024 contact 2024-08-09 15:34 ` [musl] [PATCH v3 3/3] signal: add str2sig(3) " contact 2024-08-11 0:43 ` Rich Felker 2024-08-11 2:54 ` Rich Felker
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/musl/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).