strerror_r questions

Corinna Vinschen vinschen@redhat.com
Thu Feb 10 09:47:00 GMT 2011


On Feb  9 15:43, Eric Blake wrote:
> On 02/09/2011 03:11 PM, Corinna Vinschen wrote:
> > This looks wrong to me.  Glibc guarantees that the copied result in
> > buffer is NUL-terminated, and I'm missing the "Unknown error XXX"
> > message.
> 
> The "Unknown error XXX" message is a cygwin artifact, not a newlib
> artifact.  That is, cygwin should be using it's own strerror_r, since it
> provides its own strerror() with different behavior than newlib's.

The "Unknown error XXX" is not a Cygwin artifact, it's standard glibc
behaviour, see `man strerror_r' on Linux:

  RETURN VALUE
    The strerror() and the GNU-specific strerror_r() functions  return  the
    appropriate error description string, or an "Unknown error nnn" message
    if the error number is unknown.

> >   if (strlen (error) >= n)
> >     return error;
> >   if (!*error)
> >     snprintf (buffer, n, "Unknown error %d", errnum);
> 
> No.  I strongly feel that strerror and strerror_r should return the same
> strings (insofar as possible).  However, newlib's strerror() returns "",
> not "Unknown error XXX", for an unknown string, for three reasons:
> 1. strerror_r must be thread-safe, but it calls strerror, so strerror
> must also be thread-safe in newlib (in general, POSIX does not require
> strerror to be thread-safe, but in that case, strerror_r cannot be
> implemented by calling strerror); newlib achieves its thread-safety by
> returning only constant strings (well, newlib also provides the
> _user_sterror hook, which must be thread-safe for all this to work)
> 2. newlib did not set aside any thread-local storage for computing an
> alternate string, and I don't want to change struct REENT to add such
> storage
> 3. newlib targets embedded systems, and dragging in snprintf() to
> compute an alternate string is bloat.

Good points.

> The glibc docs state merely that the return value is
> NUL-terminated, not that buf is also NUL-terminated (which, for n==0, is
> impossible).

That's not how I understand the sentence

  If the function stores a string in buf, then at most buflen bytes are
  stored (the string may  be  truncated  if buflen  is too small) and
  the string always includes a terminating null byte.

You're right insofar as it doesn't matter if error or buffer is returned,
so we can avoid the truncation, but the aforementioned sentence is quite
clear to me on the NUL-terminated thingy in case buf is used.

> > Same here.  POSIX does not require that the string in buffer is
> > NUL-terminated, that's what the ERANGE is for, but the POSIX man page
> > also contains words about unknown error codes as a [CX] type extension:
> > 
> >   "If the value of errnum is a valid error number, the message string
> >    shall indicate what error occurred; otherwise, if these functions
> >    complete successfully, the message string shall indicate that an
> >    unknown error occurred."
> > 
> > I think it makes sense to implement this as well.
> 
> Back to the idea that strerror_r should give the same output as
> strerror, are you saying that I should add thread-local storage to REENT
> to provide the "unknown error" details instead of ""?  Newlib's
> implementation, while not ideal, is at least compliant, without making
> it more complex to deal with thread-local computed strings.

No, you're right as far as emebdded targets are concerned.


Thanks,
Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat



More information about the Newlib mailing list