+2011-05-19 Eric Blake <eblake@redhat.com>
+
+ strerror_r: guarantee unchanged errno
+ * lib/strerror_r.c (strerror_r): Guarantee unchanged errno.
+ * lib/strerror-impl.h (strerror): Set errno to match strerror_r
+ failure.
+ * tests/test-strerror_r.c (main): Enhance test.
+
2011-05-19 Bruno Haible <bruno@clisp.org>
strerror_r: Reorder #if blocks.
if (msg)
{
+ int saved_errno = errno;
size_t len = strlen (msg);
+ int ret = ERANGE;
if (len < buflen)
{
memcpy (buf, msg, len + 1);
- return 0;
+ ret = 0;
}
- else
- return ERANGE;
+ errno = saved_errno;
+ return ret;
}
}
#endif
{
int ret;
+ int saved_errno = errno;
#if USE_XPG_STRERROR_R
if (errnum >= 0 && errnum < sys_nerr)
{
# if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
- int saved_errno = errno;
# if defined __NetBSD__
nl_catd catd = catopen ("libc", NL_CAT_LOCALE);
const char *errmsg =
# if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
if (catd != (nl_catd)-1)
catclose (catd);
- errno = saved_errno;
# endif
}
else
#endif
+ errno = saved_errno;
return ret;
}
}
/* Test results with valid errnum and enough room. */
+ errno = 0;
buf[0] = '\0';
ASSERT (strerror_r (EACCES, buf, sizeof (buf)) == 0);
ASSERT (buf[0] != '\0');
+ ASSERT (errno == 0);
+ errno = 0;
buf[0] = '\0';
ASSERT (strerror_r (ETIMEDOUT, buf, sizeof (buf)) == 0);
ASSERT (buf[0] != '\0');
+ ASSERT (errno == 0);
+ errno = 0;
buf[0] = '\0';
ASSERT (strerror_r (EOVERFLOW, buf, sizeof (buf)) == 0);
ASSERT (buf[0] != '\0');
+ ASSERT (errno == 0);
/* POSIX requires strerror (0) to succeed. Reject use of "Unknown
error", but allow "Success", "No error", or even Solaris' "Error
0" which are distinct patterns from true out-of-range strings.
http://austingroupbugs.net/view.php?id=382 */
+ errno = 0;
buf[0] = '\0';
ret = strerror_r (0, buf, sizeof (buf));
ASSERT (ret == 0);
ASSERT (buf[0]);
+ ASSERT (errno == 0);
ASSERT (strstr (buf, "nknown") == NULL);
/* Test results with out-of-range errnum and enough room. */
+ errno = 0;
buf[0] = '^';
ret = strerror_r (-3, buf, sizeof (buf));
ASSERT (ret == 0 || ret == EINVAL);
if (ret == 0)
ASSERT (buf[0] != '^');
+ ASSERT (errno == 0);
/* Test results with a too small buffer. */
for (i = 0; i <= len; i++)
{
strcpy (buf, "BADFACE");
+ errno = 0;
ret = strerror_r (EACCES, buf, i);
+ ASSERT (errno == 0);
if (ret == 0)
{
/* Truncated result. POSIX allows this, and it actually
}
strcpy (buf, "BADFACE");
+ errno = 0;
ret = strerror_r (EACCES, buf, len + 1);
ASSERT (ret == 0);
+ ASSERT (errno == 0);
}
return 0;