X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstrerror.c;h=d0dd1af98431674050072e6c725a6909408dc5c6;hb=258036d8674583fce2002a04afc996f18c8b8486;hp=9d1f1659792be4feb1c9a3acfc5f370c66907c31;hpb=886f8503bc5a9022475c729054037668cee58087;p=gnulib.git diff --git a/lib/strerror.c b/lib/strerror.c index 9d1f16597..d0dd1af98 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -23,11 +23,61 @@ #include #include #include +#include #include "intprops.h" +#include "strerror-override.h" #include "verify.h" /* Use the system functions, not the gnulib overrides in this file. */ #undef sprintf -#include "strerror-impl.h" +char * +strerror (int n) +#undef strerror +{ + static char buf[STACKBUF_LEN]; + size_t len; + + /* Cast away const, due to the historical signature of strerror; + callers should not be modifying the string. */ + const char *msg = strerror_override (n); + if (msg) + return (char *) msg; + + /* FreeBSD rejects 0; see http://austingroupbugs.net/view.php?id=382. + MacOS X 10.5 does not distinguish 0 from -1. */ + if (n) + msg = strerror (n); + else + { + int saved_errno = errno; + errno = 0; + msg = strerror (n); + if (errno || (msg && + (strstr (msg, "nknown") || strstr (msg, "ndefined")))) + msg = "Success"; + errno = saved_errno; + } + + /* Our strerror_r implementation might use the system's strerror + buffer, so all other clients of strerror have to see the error + copied into a buffer that we manage. This is not thread-safe, + even if the system strerror is, but portable programs shouldn't + be using strerror if they care about thread-safety. */ + if (!msg || !*msg) + { + static char const fmt[] = "Unknown error %d"; + verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); + sprintf (buf, fmt, n); + errno = EINVAL; + return buf; + } + + /* Fix STACKBUF_LEN if this ever aborts. */ + len = strlen (msg); + if (sizeof buf <= len) + abort (); + + return memcpy (buf, msg, len + 1); +}