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

Joel Sherrill joel at rtems.org
Fri Jul 16 21:37:03 UTC 2021


This looks OK to me.

GO ahead and submit to newlib@ for their review.

--joel

On Fri, Jul 9, 2021 at 3:01 AM Matt Joyce <mfjoyce2004 at gmail.com> wrote:
>
> 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
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list