cURL / Mailing Lists / curl-library / Single Mail

curl-library

Curl_strerror and strerror_r on glibc

From: Tor Arntsen <tor_at_spacetec.no>
Date: Thu, 25 Mar 2004 12:30:43 +0100

lib/curl_strerror.c:
const char *Curl_strerror(struct connectdata *conn, int err)
{
..
#ifdef HAVE_STRERROR_R
    strerror_r(err, buf, max);
    /* this may set errno to ERANGE if insufficient storage was supplied via
       strerrbuf and buflen to contain the generated message string, or EINVAL
       if the value of errnum is not a valid error number.*/
#else
    strncpy(buf, strerror(err), max);
#endif
..

Unfortunately this won't work on glibc-based systems, e.g. Linux. The code
above expexts a POSIX strerror_r, i.e. this one:

       int strerror_r(int errnum, char *buf, size_t n);

which copies the error string into buf.

But glibc (despite the confusing manpage on at least some Linux distros)
has an old, incompatible implementation that *appears* to be similar enough,
but isn't:

       char *strerror_r(int errnum, char *buf, size_t n);

What this one does is to return the error string (no surprises there), but
it doesn't usually copy anything into buf! The 'buf' and 'n' parameters are
only meant as an optional working area, in case strerror_r needs it. A quick
test on a few systems shows that it's generally not touched at all. In other
words, on Linux and other glibc-based OS'es the construct in Curl_strerror()
will return an empty string.

There's a problem with configure too, because it sets HAVE_STRERROR_R on my
Linux box (which won't work), but it doesn't set it on AIX, which indeed does
have a working POSIX strerror_r()... (it even has a glibc-compatible version
for Linux compatibility, with another name and a #define in case you set
_LINUX_SOURCE_COMPAT.. but never mind that. Oh, it seems you have to set
_THREAD_SAFE to get access to strerror_r() (the POSIX one) on AIX. Maybe
that's why configure doesn't find it).

-Tor
Received on 2004-03-25