diff options
author | Matt Joyce <mfjoyce2004@gmail.com> | 2021-07-31 15:22:05 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2021-08-02 11:28:15 +0200 |
commit | 2b50ec0cd205c72b17d8a905f7cfd9e7bb3a6794 (patch) | |
tree | e8f9dcfcdf77164da3f53afc03e61047d7104f65 /newlib/libc | |
parent | 38965159dfcaa58a4874d6b00818d41b6f13d5c1 (diff) | |
download | newlib-2b50ec0cd205c72b17d8a905f7cfd9e7bb3a6794.zip newlib-2b50ec0cd205c72b17d8a905f7cfd9e7bb3a6794.tar.gz newlib-2b50ec0cd205c72b17d8a905f7cfd9e7bb3a6794.tar.bz2 |
libc: Added implementation for sig2str/str2sig.
Added implementations for sig2str() and str2sig() in libc/signal
in order to improve POSIX compliance. Added fucntion prototypes
in libc/include/sys/signal.h.
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/include/sys/signal.h | 17 | ||||
-rw-r--r-- | newlib/libc/signal/Makefile.am | 4 | ||||
-rw-r--r-- | newlib/libc/signal/Makefile.in | 14 | ||||
-rw-r--r-- | newlib/libc/signal/sig2str.c | 297 | ||||
-rw-r--r-- | newlib/libc/signal/signal.tex | 4 |
5 files changed, 330 insertions, 6 deletions
diff --git a/newlib/libc/include/sys/signal.h b/newlib/libc/include/sys/signal.h index 45cc036..255782e 100644 --- a/newlib/libc/include/sys/signal.h +++ b/newlib/libc/include/sys/signal.h @@ -12,6 +12,7 @@ extern "C" { #include <sys/types.h> #include <sys/_sigset.h> #include <sys/_timespec.h> +#include <stdint.h> #if !defined(_SIGSET_T_DECLARED) #define _SIGSET_T_DECLARED @@ -238,6 +239,22 @@ int sigqueue (pid_t, int, const union sigval); #endif /* __POSIX_VISIBLE >= 199309 */ +/* Using __MISC_VISIBLE until POSIX Issue 8 is officially released */ +#if __MISC_VISIBLE + +/* POSIX Issue 8 adds sig2str() and str2sig() */ + +#if __STDINT_EXP(INT_MAX) > 0x7fff +#define SIG2STR_MAX (sizeof("RTMAX+") + sizeof("4294967295") - 1) +#else +#define SIG2STR_MAX (sizeof("RTMAX+") + sizeof("65535") - 1) +#endif + +int sig2str(int, char *); +int str2sig(const char *__restrict, int *__restrict); + +#endif /* __MISC_VISIBLE */ + #if defined(___AM29K__) /* These all need to be defined for ANSI C, but I don't think they are meaningful. */ diff --git a/newlib/libc/signal/Makefile.am b/newlib/libc/signal/Makefile.am index a93dba7..89db261 100644 --- a/newlib/libc/signal/Makefile.am +++ b/newlib/libc/signal/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -LIB_SOURCES = psignal.c raise.c signal.c +LIB_SOURCES = psignal.c raise.c signal.c sig2str.c libsignal_la_LDFLAGS = -Xcompiler -nostdlib @@ -21,6 +21,6 @@ endif # USE_LIBTOOL include $(srcdir)/../../Makefile.shared -CHEWOUT_FILES = psignal.def raise.def signal.def +CHEWOUT_FILES = psignal.def raise.def signal.def sig2str.def CHAPTERS = signal.tex diff --git a/newlib/libc/signal/Makefile.in b/newlib/libc/signal/Makefile.in index 4c74cd6..d4aae4e 100644 --- a/newlib/libc/signal/Makefile.in +++ b/newlib/libc/signal/Makefile.in @@ -73,12 +73,12 @@ ARFLAGS = cru lib_a_AR = $(AR) $(ARFLAGS) lib_a_LIBADD = am__objects_1 = lib_a-psignal.$(OBJEXT) lib_a-raise.$(OBJEXT) \ - lib_a-signal.$(OBJEXT) + lib_a-signal.$(OBJEXT) lib_a-sig2str.$(OBJEXT) @USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_1) lib_a_OBJECTS = $(am_lib_a_OBJECTS) LTLIBRARIES = $(noinst_LTLIBRARIES) libsignal_la_LIBADD = -am__objects_2 = psignal.lo raise.lo signal.lo +am__objects_2 = psignal.lo raise.lo signal.lo sig2str.lo @USE_LIBTOOL_TRUE@am_libsignal_la_OBJECTS = $(am__objects_2) libsignal_la_OBJECTS = $(am_libsignal_la_OBJECTS) libsignal_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -253,7 +253,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = cygnus INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -LIB_SOURCES = psignal.c raise.c signal.c +LIB_SOURCES = psignal.c raise.c signal.c sig2str.c libsignal_la_LDFLAGS = -Xcompiler -nostdlib @USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = libsignal.la @USE_LIBTOOL_TRUE@libsignal_la_SOURCES = $(LIB_SOURCES) @@ -272,7 +272,7 @@ DOCBOOK_CHEW = ${top_srcdir}/../doc/makedocbook.py DOCBOOK_OUT_FILES = $(CHEWOUT_FILES:.def=.xml) DOCBOOK_CHAPTERS = $(CHAPTERS:.tex=.xml) CLEANFILES = $(CHEWOUT_FILES) $(DOCBOOK_OUT_FILES) -CHEWOUT_FILES = psignal.def raise.def signal.def +CHEWOUT_FILES = psignal.def raise.def signal.def sig2str.def CHAPTERS = signal.tex all: all-am @@ -361,6 +361,12 @@ lib_a-signal.o: signal.c lib_a-signal.obj: signal.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-signal.obj `if test -f 'signal.c'; then $(CYGPATH_W) 'signal.c'; else $(CYGPATH_W) '$(srcdir)/signal.c'; fi` +lib_a-sig2str.o: sig2str.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sig2str.o `test -f 'sig2str.c' || echo '$(srcdir)/'`sig2str.c + +lib_a-sig2str.obj: sig2str.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-sig2str.obj `if test -f 'sig2str.c'; then $(CYGPATH_W) 'sig2str.c'; else $(CYGPATH_W) '$(srcdir)/sig2str.c'; fi` + mostlyclean-libtool: -rm -f *.lo diff --git a/newlib/libc/signal/sig2str.c b/newlib/libc/signal/sig2str.c new file mode 100644 index 0000000..940a5ea --- /dev/null +++ b/newlib/libc/signal/sig2str.c @@ -0,0 +1,297 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Copyright (C) 2021 Matthew Joyce + * + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* +FUNCTION +<<sig2str>>, <<str2sig>>---Translate between signal number and name + +INDEX + sig2str +INDEX + str2sig + +SYNOPSIS + #include <signal.h> + int sig2str(int <[signum]>, char *<[str]>); + + int str2sig(const char *restrict <[str]>, int *restrict <[pnum]>); + +DESCRIPTION +The <<sig2str>> function translates the signal number specified by <[signum]> to +a signal name and stores this string in the location specified by <[str]>. The +application must ensure that <[str]> points to a location that can store the +string including the terminating null byte. The symbolic constant +<[SIG2STR_MAX]> defined in `<<signal.h>>' gives the maximum number of bytes +required. + +The <<str2sig>> function translates the signal name in the string pointed to by +<[str]> to a signal number and stores this value in the location specified by +<[pnum]>. + +RETURNS +<<sig2str>> returns <<0>> if <[signum]>> is a valid, supported signal number. +Otherwise, it returns <<-1>>. + +<<str2sig>> returns <<0>> if it stores a value in the location pointed to by +<[pnum]>. Otherwise it returns <<-1>>. +*/ + +#include <signal.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#define SPACES_TO_N 6 /* Allows indexing to RT Signal number in str2sig */ +#define NUM_OF_SIGS (sizeof(sig_array) / sizeof(sig_name_and_num)) + +typedef struct sig_name_and_num { + const char *sig_name; + const int sig_num; +} sig_name_and_num; + +static const sig_name_and_num sig_array[] = { + { "EXIT", 0 }, + #ifdef SIGHUP + { "HUP", SIGHUP }, + #endif + #ifdef SIGINT + { "INT", SIGINT }, + #endif + #ifdef SIGQUIT + { "QUIT", SIGQUIT }, + #endif + #ifdef SIGILL + { "ILL", SIGILL }, + #endif + #ifdef SIGTRAP + { "TRAP", SIGTRAP }, + #endif + #ifdef SIGABRT + { "ABRT", SIGABRT }, + #endif + #ifdef SIGIOT + { "IOT", SIGIOT}, + #endif + #ifdef SIGEMT + { "EMT", SIGEMT }, + #endif + #ifdef SIGFPE + { "FPE", SIGFPE }, + #endif + #ifdef SIGKILL + { "KILL", SIGKILL }, + #endif + #ifdef SIGBUS + { "BUS", SIGBUS }, + #endif + #ifdef SIGSEGV + { "SEGV", SIGSEGV }, + #endif + #ifdef SIGSYS + { "SYS", SIGSYS }, + #endif + #ifdef SIGPIPE + { "PIPE", SIGPIPE }, + #endif + #ifdef SIGALRM + { "ALRM", SIGALRM }, + #endif + #ifdef SIGTERM + { "TERM", SIGTERM }, + #endif + #ifdef SIGURG + { "URG", SIGURG }, + #endif + #ifdef SIGSTOP + { "STOP", SIGSTOP }, + #endif + #ifdef SIGTSTP + { "TSTP", SIGTSTP }, + #endif + #ifdef SIGCONT + { "CONT", SIGCONT }, + #endif + #ifdef SIGCHLD + { "CHLD", SIGCHLD }, + #endif + #ifdef SIGCLD + { "CLD", SIGCLD }, + #endif + #ifdef SIGTTIN + { "TTIN", SIGTTIN }, + #endif + #ifdef SIGTTOU + { "TTOU", SIGTTOU }, + #endif + #ifdef SIGIO + { "IO", SIGIO }, + #endif + #ifdef SIGPOLL + { "POLL", SIGPOLL }, + #endif + #ifdef SIGWINCH + { "WINCH", SIGWINCH }, + #endif + #ifdef SIGUSR1 + { "USR1", SIGUSR1 }, + #endif + #ifdef SIGUSR2 + { "USR2", SIGUSR2 }, + #endif + #ifdef SIGPWR + { "PWR", SIGPWR }, + #endif + #ifdef SIGXCPU + { "XCPU", SIGXCPU }, + #endif + #ifdef SIGXFSZ + { "XFSZ", SIGXFSZ }, + #endif + #ifdef SIGVTALRM + { "VTALRM", SIGVTALRM }, + #endif + #ifdef SIGPROF + { "PROF", SIGPROF }, + #endif + #ifdef SIGLOST + { "LOST", SIGLOST }, + #endif + /* The Issue 8 standard requires that SIGRTMIN and SIGRTMAX be included + * as valid results to be saved from calls to sig2str/str2sig. */ + #ifdef SIGRTMIN + { "RTMIN", SIGRTMIN }, + #endif + #ifdef SIGRTMAX + { "RTMAX", SIGRTMAX } + #endif +}; + +int +sig2str(int signum, char *str) +{ + const sig_name_and_num *sptr; + + /* If signum falls in lower half of the real time signals range, define + * the saved str value as "RTMIN+n" according to the Issue 8 standard */ + if ((SIGRTMIN + 1) <= signum && + signum <= (SIGRTMIN + SIGRTMAX) / 2) { + sprintf(str, "RTMIN+%d", (signum-SIGRTMIN)); + return 0; + } + + /* If signum falls in upper half of the real time signals range, define + * the saved str value as "RTMAX-m" according to the Issue 8 standard */ + if ((((SIGRTMIN + SIGRTMAX) / 2) + 1) <= signum && + signum <= (SIGRTMAX - 1)) { + sprintf(str, "RTMAX-%d", (SIGRTMAX - signum)); + return 0; + } + + /* Otherwise, search for signal matching signum in sig_array. If found, + * save its string value in str. */ + for (sptr = sig_array; sptr < &sig_array[NUM_OF_SIGS]; sptr++) { + if (sptr->sig_num == signum) { + strcpy(str, sptr->sig_name); + return 0; + } + } + + /* If signum is not a recognized signal number, return -1 */ + return -1; +} + +int +str2sig(const char *restrict str, int *restrict pnum) +{ + unsigned long j = 0; + char *endp; + const sig_name_and_num *sptr; + unsigned long is_valid_decimal; + + /* i686 Cygwin only supports one RT signal. For this case, skip checks + * for "RTMIN+n" and "RTMAX-m". */ + if (SIGRTMIN != SIGRTMAX) { + + /* If str is in RT signal range, get number of of RT signal, save it as an + * integer. */ + if (strncmp(str, "RTMIN+", SPACES_TO_N) == 0) { + j = strtoul(&str[SPACES_TO_N], &endp, 10); + + /* If number is valid, save it in pnum. */ + if (*endp == '\0') { + if (1 <= j && + j <= ((SIGRTMAX - SIGRTMIN)-1)) { + *pnum = (SIGRTMIN + j); + return 0; + } + return -1; + } + return -1; + } + + /* If str is in RT signal range, get number of of RT signal, save it as an + * integer. */ + if (strncmp(str, "RTMAX-", SPACES_TO_N) == 0) { + j = strtoul(&str[SPACES_TO_N], &endp, 10); // and endptr null check + + /* If number is valid, save it in pnum. */ + if (*endp == '\0') { + if (1 <= j && + j <= ((SIGRTMAX - SIGRTMIN)-1)) { + *pnum = (SIGRTMAX - j); + return 0; + } + return -1; + } + return -1; + } + } + + /*If str is a valid signal name, save its corresponding number in pnum. */ + for (sptr = sig_array; sptr < &sig_array[NUM_OF_SIGS]; sptr++) { + if (strcmp(sptr->sig_name, str) == 0) { + *pnum = sptr->sig_num; + return 0; + } + } + + /* str was not found in sig_array. Check whether str is a string + * representation of a valid integer. */ + is_valid_decimal = strtoul(str, &endp, 10); + + if (*endp != '\0') { + return -1; + } + + /* If str is a representation of a decimal value, save its integer value + * in pnum. */ + if (1 <= is_valid_decimal && + is_valid_decimal <= SIGRTMAX) { + *pnum = is_valid_decimal; + return 0; + } + return -1; +} diff --git a/newlib/libc/signal/signal.tex b/newlib/libc/signal/signal.tex index c4d4830..f7dbf9d 100644 --- a/newlib/libc/signal/signal.tex +++ b/newlib/libc/signal/signal.tex @@ -61,6 +61,7 @@ reliable from signal handlers.) @menu * psignal:: Print a signal message to standard error * raise:: Send a signal +* sig2str:: Translate between signal number and name * signal:: Specify handler subroutine for a signal @end menu @@ -71,4 +72,7 @@ reliable from signal handlers.) @include signal/raise.def @page +@include signal/sig2str.def + +@page @include signal/signal.def |