From c0fb797b4075b0e5f93207d4df1704aa6615cac0 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 20 May 2011 10:42:26 -0600 Subject: [PATCH] test-perror: check for strerror interactions This uncovered a glibc bug, although not many people check for perror failures, so for now I'm not working around it. http://sourceware.org/bugzilla/show_bug.cgi?id=12792 * tests/macros.h (STREQ) Add macro. * modules/perror-tests (Files): Add second test. * tests/test-perror2.c (main): New file. * doc/posix-functions/perror.texi (perror): Document glibc bug. Signed-off-by: Eric Blake --- ChangeLog | 6 +++ doc/posix-functions/perror.texi | 4 ++ modules/perror-tests | 6 ++- tests/macros.h | 4 ++ tests/test-perror2.c | 110 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 tests/test-perror2.c diff --git a/ChangeLog b/ChangeLog index 30bccca37..5001637a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2011-05-20 Eric Blake + test-perror: check for strerror interactions + * tests/macros.h (STREQ) Add macro. + * modules/perror-tests (Files): Add second test. + * tests/test-perror2.c (main): New file. + * doc/posix-functions/perror.texi (perror): Document glibc bug. + test-perror: rewrite to use init script * modules/perror-tests (Files): Add init.sh. * tests/test-perror.sh: Use temporary directory. diff --git a/doc/posix-functions/perror.texi b/doc/posix-functions/perror.texi index dc6121722..29231064b 100644 --- a/doc/posix-functions/perror.texi +++ b/doc/posix-functions/perror.texi @@ -16,4 +16,8 @@ OpenBSD 4.0, OSF/1 5.1, Cygwin 1.5.x, mingw. Portability problems not fixed by Gnulib: @itemize +@item +POSIX requires that this function set the stream error bit (detected +by @code{ferror}) on write failure, but not all platforms do this: +glibc 2.13. @end itemize diff --git a/modules/perror-tests b/modules/perror-tests index bad23fd9c..9a6ba4736 100644 --- a/modules/perror-tests +++ b/modules/perror-tests @@ -1,7 +1,9 @@ Files: tests/init.sh +tests/macros.h tests/signature.h tests/test-perror.c +tests/test-perror2.c tests/test-perror.sh Depends-on: @@ -9,5 +11,5 @@ Depends-on: configure.ac: Makefile.am: -TESTS += test-perror.sh -check_PROGRAMS += test-perror +TESTS += test-perror.sh test-perror2 +check_PROGRAMS += test-perror test-perror2 diff --git a/tests/macros.h b/tests/macros.h index 89226758e..adb3744d5 100644 --- a/tests/macros.h +++ b/tests/macros.h @@ -62,3 +62,7 @@ *not* work for function parameters of array type, because they are actually parameters of pointer type. */ #define SIZEOF(array) (sizeof (array) / sizeof (array[0])) + +/* STREQ (str1, str2) + Return true if two strings compare equal. */ +#define STREQ(a, b) (strcmp (a, b) == 0) diff --git a/tests/test-perror2.c b/tests/test-perror2.c new file mode 100644 index 000000000..dfcabb4fb --- /dev/null +++ b/tests/test-perror2.c @@ -0,0 +1,110 @@ +/* Test of perror() function. + Copyright (C) 2011 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +#include + +#include +#include +#include + +/* This test intentionally parses stderr. So, we arrange to have fd 10 + (outside the range of interesting fd's during the test) set up to + duplicate the original stderr. */ +#define BACKUP_STDERR_FILENO 10 +#define ASSERT_STREAM myerr +#include "macros.h" + +static FILE *myerr; + +#define BASE "test-perror2" + +int +main (void) +{ + FILE *fp; + + /* We change fd 2 later, so save it in fd 10. */ + if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO + || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL) + return 2; + + ASSERT (freopen (BASE ".tmp", "w+", stderr) == stderr); + + /* Test that perror does not clobber strerror buffer. */ + { + const char *msg1; + const char *msg2; + const char *msg3; + const char *msg4; + char *str1; + char *str2; + char *str3; + char *str4; + + msg1 = strerror (ENOENT); + ASSERT (msg1); + str1 = strdup (msg1); + ASSERT (str1); + + msg2 = strerror (ERANGE); + ASSERT (msg2); + str2 = strdup (msg2); + ASSERT (str2); + + msg3 = strerror (-4); + ASSERT (msg3); + str3 = strdup (msg3); + ASSERT (str3); + + msg4 = strerror (1729576); + ASSERT (msg4); + str4 = strdup (msg4); + ASSERT (str4); + + errno = EACCES; + perror (""); + errno = -5; + perror (""); + ASSERT (!ferror (stderr)); + ASSERT (msg1 == msg2 || msg1 == msg4 || STREQ (msg1, str1)); + ASSERT (msg2 == msg4 || STREQ (msg2, str2)); + ASSERT (msg3 == msg4 || STREQ (msg3, str3)); + ASSERT (STREQ (msg4, str4)); + } + + /* Test that perror reports write failure. */ + { + ASSERT (freopen (BASE ".tmp", "r", stderr) == stderr); + ASSERT (setvbuf (stderr, NULL, _IOLBF, BUFSIZ) == 0); + errno = -1; + ASSERT (!ferror (stderr)); + perror (NULL); + ASSERT (errno > 0); +#if 0 + /* Commented out until glibc behaves: + http://sourceware.org/bugzilla/show_bug.cgi?id=12792 */ + ASSERT (ferror (stderr)); +#endif + } + + ASSERT (fclose (stderr) == 0); + ASSERT (remove (BASE ".tmp") == 0); + + return 0; +} -- 2.11.0