Re: [PATCH 1/1] libc: Added implementations and prototypes for

Joel Sherrill <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <CAF9ehCV1c+dBdER3RiOm4BVjeuxG9=rhbCZxLL1+HG+iNS32kA@mail.gmail.com>
On Mon, Jul 19, 2021 at 4:48 AM Corinna Vinschen <[email protected]> wrote:
>
> Hi Matt,
>
>
> thanks for this implementation.  The patch looks bascically fine.
> A few issues, though.
>
> First, it's missing the Makefile.am entries to build the new files,
> please add them.
>
> On Jul 17 12:10, Matt Joyce wrote:
> > Added implementations for sig2str() and str2sig() in libc/signal in order
> > to improve POSIX compliance. Added function prototypes 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 ")
>
> While looking through your patch I realized that this request of mine
> was nonsense.  The idea was that the buffers of length SIG2STR_MAX
> have to store descriptive signal texts, like "Floating point exception"
> or "Real-time signal 10", but that's not the case here anyway.
>
> If SIG2STR_MAX isn't already defined, gnulib defines SIG2STR_MAX
> basically as sizeof "SIGRTMAX" + sizeof (max numerical string of type
> int).  This results in different SIG2STR_MAX values depending of sizeof
> int being 2, 4, or 8.
>
> Given we strive for supporting smaller targets we might want to express
> this similary, just a bit simpler.  For one thing, do we ever want to
> support more than 4 billion RT signals?  I guess not.  My suggestion would
> be something like:
>
> #if __STDINT_EXP(INT_MAX) > 0x7fff
> #define SIG2STR_MAX (sizeof ("RTMAX+") + sizeof ("4294967295") - 1)
> #else
> #define SIG2STR_MAX (sizeof ("RTMAX+") + sizeof ("65535") - 1)
> #endif

Just checking here about the terminating NUL. The sizeof("RTMAX+") includes
a NUL so the -1 at the end of the expression subtracts the one from the
sizeof("NUM"). Is that right?

An off by one error here would be hard to catch if it slipped through.

>
> > +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)) {
>                                                          ^^^
>                                                          space
>
> > +    sprintf(str, "RTMIN+%d", (signum-SIGRTMIN));
> > +    return 0;
> > +  }
>
> This is not entirely correct.  The POSIX draft requires the signal
> string to be returned for RT signals to be expressed as either "RTMIN+x"
> and "RTMAX-x", dependent on the signal number.  Please see
> https://www.opengroup.org/austin/docs/austin_1110.pdf, page 85, the two
> paragraphs starting at line 61678 (unfortunately copy/paste from this
> doc doesn't work nicely).

He implemented it this way initially but it looks like I optimistically misread
"the paragraph at line 61681 which gives an option on how to do the upper
half of the RT signals and thought/hoped it let the code have to produce
one format. But reading it again, there is a clear qualifier:

"If signum is between (SIGRTMIN+SIGRTMAX)/2 + 1 and SIGRTMAX−1
inclusive, ..."

>
> > +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 */
>                                               ^^^
>                                               Looks truncated?
>
> > +  if (strncmp(str, "RTMIN+", SPACES_TO_N) == 0) {
> > +    j = atoi(&str[SPACES_TO_N]);
>
> Oops... strncmp returns 0, but you didn't check if the next char is
> actually a non-NUL char, or even a digit.  Only digits are valid, so
> atoi should be replaced with strtoul with an extra check for endptr.
>
> > +    /* If number is valid, save it in pnum. */
> > +    if (1 <= j && j <= ((SIGRTMAX - SIGRTMIN)-1)) {
>                                                ^^^
>                                                spaces
>
> We have a special problem here.  i686 Cygwin only supports a single RT
> signal.  For historical reasons, don't ask.
>
> I. e., SIGRTMIN == SIGRTMAX.  This special case should be checked here,
> to make sure the code works with this very special, very non-POSIX
> behaviour.  I think the easiest way to handle that is to skip the
> entire "RTMIN+"/"RTMAX-" code if SIGRTMIN == SIGRTMAX.  There just is
> no such valid value in this case.

Do I interpret this as adding a conditionally compiled block to handle the
special case when SIGRTMIN == SIGRTMAX?

Is it possible for a target OS not to define any real-time signals? If so, it
might be necessary to enclose the encode RTMIN+/RTMAX- code like
this:

#ifdef SIGRTMIN
#if (SIGRTMIN == SIGRTMAX)
   Whatever i686 Cygwin want as output
#else
   RTMIN+/RTMAX- code
#endif
#endif

Things are always more complicated when you have to consider so
many target OSes. :)

>
> > +      *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]);
>
> Ditto.
>
> > +    /* If number is valid, save it in pnum. */
> > +    if (1 <= j && j <= ((SIGRTMAX - SIGRTMIN)-1)) {
>                                                ^^^
>                                                spaces
>

--joel

>
> Thanks,
> Corinna
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.