[PATCH v2] libc: Added implementations for sig2str/str2sig methods

Matt Joyce mfjoyce2004 at gmail.com
Fri Jul 9 08:00:17 UTC 2021


Added implementations for sig2str() and str2sig() in libc/signal in order
to improve POSIX compliance. Added function prototypes added to
sys/signal.h.
---
 newlib/libc/include/sys/signal.h |  12 ++
 newlib/libc/signal/sig2str.c     | 235 +++++++++++++++++++++++++++++++
 2 files changed, 247 insertions(+)
 create mode 100644 newlib/libc/signal/sig2str.c

diff --git a/newlib/libc/include/sys/signal.h b/newlib/libc/include/sys/signal.h
index 45cc0366c..847dc59bd 100644
--- a/newlib/libc/include/sys/signal.h
+++ b/newlib/libc/include/sys/signal.h
@@ -238,6 +238,18 @@ int sigqueue (pid_t, int, const union sigval);
 
 #endif /* __POSIX_VISIBLE >= 199309 */
 
+#if __GNU_VISIBLE
+
+/* POSIX Issue 8 adds sig2str() and str2sig(). */
+
+/* This allows for the max length of the error message and longest integer. */
+#define SIG2STR_MAX sizeof("Unknown signal 4294967295 ")
+
+int sig2str(int, char *);
+int str2sig(const char *__restrict, int *__restrict);
+
+#endif /* __GNU_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/sig2str.c b/newlib/libc/signal/sig2str.c
new file mode 100644
index 000000000..04b4bb1be
--- /dev/null
+++ b/newlib/libc/signal/sig2str.c
@@ -0,0 +1,235 @@
+/* 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.
+ */
+
+/* Defining _GNU_SOURCE to have access to SIG2STR_MAX in signal.h. */
+#define _GNU_SOURCE 
+#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[] = {
+    #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 the real time signals range, the Issue 8 standard 
+  * gives the option of defining the saved str value as either "RTMIN+n" or
+  * "RTMAX-m".*/
+  if ((SIGRTMIN + 1) <= signum && signum <= (SIGRTMAX -1)) {
+    sprintf(str, "RTMIN+%d", (signum-SIGRTMIN));
+    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, store this message in str. */
+  sprintf(str, "Unknown signal %d", signum); 
+  return -1; 
+}
+
+int
+str2sig(const char *restrict str, int *restrict pnum)
+{
+  int j = 0;
+  const sig_name_and_num *sptr; 
+  char dest[SIG2STR_MAX];
+  int is_valid_decimal;
+  is_valid_decimal = atoi(str);
+
+  /* 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; 
+  }
+
+  /* If str is in RT signal range, get number of of RT signal, save it as an 
+   * integer. The Issue 8 standard requires */
+  if (strncmp(str, "RTMIN+", SPACES_TO_N) == 0) {
+    j = atoi(&str[SPACES_TO_N]);
+
+    /* If number is valid, save it in pnum. */
+    if (1 <= j && j <= ((SIGRTMAX - SIGRTMIN)-1)) {
+      *pnum = (SIGRTMIN + j);
+      return 0;  
+    }
+    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 = atoi(&str[SPACES_TO_N]);
+
+    /* If number is valid, save it in pnum. */
+    if (1 <= j && j <= ((SIGRTMAX - SIGRTMIN)-1)) {
+      *pnum = (SIGRTMAX - j);
+      return 0;  
+    }
+    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; 
+    }    
+  }
+  return -1; 
+}
-- 
2.31.1



More information about the devel mailing list