aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc
diff options
context:
space:
mode:
authorMatt Joyce <mfjoyce2004@gmail.com>2021-07-31 15:22:05 +0200
committerCorinna Vinschen <corinna@vinschen.de>2021-08-02 11:28:15 +0200
commit2b50ec0cd205c72b17d8a905f7cfd9e7bb3a6794 (patch)
treee8f9dcfcdf77164da3f53afc03e61047d7104f65 /newlib/libc
parent38965159dfcaa58a4874d6b00818d41b6f13d5c1 (diff)
downloadnewlib-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.h17
-rw-r--r--newlib/libc/signal/Makefile.am4
-rw-r--r--newlib/libc/signal/Makefile.in14
-rw-r--r--newlib/libc/signal/sig2str.c297
-rw-r--r--newlib/libc/signal/signal.tex4
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