diff options
author | Eric Blake <eblake@redhat.com> | 2011-05-20 11:09:53 -0600 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2011-05-20 12:01:05 -0600 |
commit | 88dabde472b81a034a72484a32ef51d0fd549db8 (patch) | |
tree | 8bacd95a16e20782e3974205b567e89a9a3d1560 | |
parent | c0fb797b4075b0e5f93207d4df1704aa6615cac0 (diff) | |
download | gnulib-88dabde472b81a034a72484a32ef51d0fd549db8.tar.gz |
perror: work around FreeBSD bug
POSIX requires that 'errno = 0; perror ("")' print the same message
as strerror(0), but this failed if we were replacing strerror to work
around the FreeBSD bug of treating 0 as a failure.
The goal here is to _not_ replace perror on glibc, even though
strerror_r has to be replaced, because the strerror_r replacement is
only for the sake of correcting the signature rather than working
around bugs in the handling of any particular errnum value. Recall
that $gl_cv_func_strerror_r_works is only set if the POSIX signature
was detected in the first place.
* m4/perror.m4 (gl_FUNC_PERROR): Also replace perror if strerror_r
is broken. Move AC_LIBOBJ...
* modules/perror (configure.ac): Here.
* doc/posix-functions/perror.texi (perror): Document this.
* tests/test-perror2.c (main): Enhance test.
Signed-off-by: Eric Blake <eblake@redhat.com>
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | doc/posix-functions/perror.texi | 4 | ||||
-rw-r--r-- | m4/perror.m4 | 10 | ||||
-rw-r--r-- | modules/perror | 3 | ||||
-rw-r--r-- | tests/test-perror2.c | 22 |
5 files changed, 44 insertions, 2 deletions
@@ -1,5 +1,12 @@ 2011-05-20 Eric Blake <eblake@redhat.com> + perror: work around FreeBSD bug + * m4/perror.m4 (gl_FUNC_PERROR): Also replace perror if strerror_r + is broken. Move AC_LIBOBJ... + * modules/perror (configure.ac): Here. + * doc/posix-functions/perror.texi (perror): Document this. + * tests/test-perror2.c (main): Enhance test. + test-perror: check for strerror interactions * tests/macros.h (STREQ) Add macro. * modules/perror-tests (Files): Add second test. diff --git a/doc/posix-functions/perror.texi b/doc/posix-functions/perror.texi index 29231064b3..cf6ac79d1c 100644 --- a/doc/posix-functions/perror.texi +++ b/doc/posix-functions/perror.texi @@ -12,6 +12,10 @@ Portability problems fixed by Gnulib: This function does not support the error values that are specified by POSIX but not defined by the system, on some platforms: OpenBSD 4.0, OSF/1 5.1, Cygwin 1.5.x, mingw. +@item +This function treats @code{errno} of 0 like failure, although POSIX +requires that the message declare it as a success, on some platforms: +FreeBSD 8.2 @end itemize Portability problems not fixed by Gnulib: diff --git a/m4/perror.m4 b/m4/perror.m4 index 2a03e0809d..d08f365e07 100644 --- a/m4/perror.m4 +++ b/m4/perror.m4 @@ -1,4 +1,4 @@ -# perror.m4 serial 1 +# perror.m4 serial 2 dnl Copyright (C) 2008-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,10 +8,16 @@ AC_DEFUN([gl_FUNC_PERROR], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_REQUIRE([gl_HEADER_ERRNO_H]) + AC_REQUIRE([gl_FUNC_STRERROR_R]) if test -n "$ERRNO_H"; then dnl The system's perror() cannot know about the new errno values we add dnl to <errno.h>. Replace it. REPLACE_PERROR=1 - AC_LIBOBJ([perror]) fi + case ${gl_cv_func_strerror_r_works-unset} in + unset|*yes) ;; + *) dnl The system's perror() probably inherits the bugs in the + dnl system's strerror_r(). Replace it. + REPLACE_PERROR=1 ;; + esac ]) diff --git a/modules/perror b/modules/perror index af79a0d8e7..1ff9ec27e5 100644 --- a/modules/perror +++ b/modules/perror @@ -16,6 +16,9 @@ strerror_r-posix [test $REPLACE_PERROR = 1] configure.ac: gl_FUNC_PERROR gl_STRING_MODULE_INDICATOR([perror]) +if test $REPLACE_PERROR = 1; then + AC_LIBOBJ([perror]) +fi Makefile.am: diff --git a/tests/test-perror2.c b/tests/test-perror2.c index dfcabb4fb7..fe5e33eba0 100644 --- a/tests/test-perror2.c +++ b/tests/test-perror2.c @@ -88,6 +88,28 @@ main (void) ASSERT (STREQ (msg4, str4)); } + /* Test that perror uses the same message as strerror. */ + { + int errs[] = { EACCES, 0, -3, }; + int i; + for (i = 0; i < SIZEOF (errs); i++) + { + char buf[256]; + char *err = strerror (errs[i]); + + ASSERT (err); + ASSERT (strlen (err) < sizeof buf); + rewind (stderr); + ASSERT (ftruncate (fileno (stderr), 0) == 0); + errno = errs[i]; + perror (NULL); + ASSERT (!ferror (stderr)); + rewind (stderr); + ASSERT (fgets (buf, sizeof buf, stderr) == buf); + ASSERT (strstr (buf, err)); + } + } + /* Test that perror reports write failure. */ { ASSERT (freopen (BASE ".tmp", "r", stderr) == stderr); |