On 2011-14-03 I wrote in <http://lists.gnu.org/archive/html/bug-gnulib/2011-03/msg00117.html>: > 2) The perror replacement uses strerror, thus clobbering the strerror > buffer. > 3) On Cygwin, perror clobbers the strerror buffer. > > The fix for 2) should be to change lib/perror.c to call strerror_r. > The fix for 3) should be to change m4/perror.m4 to enable the replacement > on Cygwin.
Here comes part 2. Eric, I leave part 3 to you. 2011-05-19 Bruno Haible <br...@clisp.org> perror: Avoid clobbering the strerror buffer when possible. * lib/strerror-impl.h: New file, extracted from lib/strerror.c. * lib/strerror.c: Include it. * modules/strerror (Files): Add lib/strerror-impl.h. * lib/perror.c: Include <stdlib.h>, intprops.h, verify.h. (my_strerror): New function, defined through lib/strerror-impl.h. (perror): Use it instead of strerror. * modules/perror (Files): Add lib/strerror-impl.h. (Depends-on): Remove strerror. Add intprops, verify, strerror_r-posix. ============================= lib/strerror-impl.h ============================= /* strerror-impl.h --- Implementation of POSIX compatible strerror() function. Copyright (C) 2007-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 of the License, 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, see <http://www.gnu.org/licenses/>. */ #ifdef STATIC STATIC #endif char * strerror (int n) { static char buf[256]; int ret = strerror_r (n, buf, sizeof (buf)); if (ret == 0) return buf; if (ret == ERANGE) /* If this happens, increase the size of buf. */ abort (); { static char const fmt[] = "Unknown error (%d)"; verify (sizeof (buf) >= sizeof (fmt) + INT_STRLEN_BOUND (n)); sprintf (buf, fmt, n); return buf; } } =============================================================================== --- lib/perror.c.orig Thu May 19 21:44:53 2011 +++ lib/perror.c Thu May 19 21:40:43 2011 @@ -21,12 +21,26 @@ #include <stdio.h> #include <errno.h> +#include <stdlib.h> #include <string.h> +#include "intprops.h" +#include "verify.h" + +/* Use the system functions, not the gnulib overrides in this file. */ +#undef sprintf + +/* my_strerror (errnum) is equivalent to strerror (errnum). + But it uses its own buffer, not the one from strerror(). */ +#define STATIC static +#undef strerror +#define strerror my_strerror +#include "strerror-impl.h" + void perror (const char *string) { - const char *errno_description = strerror (errno); + const char *errno_description = my_strerror (errno); if (string != NULL && *string != '\0') fprintf (stderr, "%s: %s\n", string, errno_description); --- lib/strerror.c.orig Thu May 19 21:44:53 2011 +++ lib/strerror.c Thu May 19 21:22:27 2011 @@ -32,26 +32,6 @@ /* Use the system functions, not the gnulib overrides in this file. */ # undef sprintf -char * -strerror (int n) -{ - static char buf[256]; - - int ret = strerror_r (n, buf, sizeof (buf)); - - if (ret == 0) - return buf; - - if (ret == ERANGE) - /* If this happens, increase the size of buf. */ - abort (); - - { - static char const fmt[] = "Unknown error (%d)"; - verify (sizeof (buf) >= sizeof (fmt) + INT_STRLEN_BOUND (n)); - sprintf (buf, fmt, n); - return buf; - } -} +# include "strerror-impl.h" #endif --- modules/perror.orig Thu May 19 21:44:53 2011 +++ modules/perror Thu May 19 21:23:39 2011 @@ -3,12 +3,15 @@ Files: lib/perror.c +lib/strerror-impl.h m4/perror.m4 Depends-on: stdio -errno [test $REPLACE_PERROR = 1] -strerror [test $REPLACE_PERROR = 1] +errno [test $REPLACE_PERROR = 1] +intprops [test $REPLACE_PERROR = 1] +verify [test $REPLACE_PERROR = 1] +strerror_r-posix [test $REPLACE_PERROR = 1] configure.ac: gl_FUNC_PERROR --- modules/strerror.orig Thu May 19 21:44:53 2011 +++ modules/strerror Thu May 19 21:19:22 2011 @@ -3,6 +3,7 @@ Files: lib/strerror.c +lib/strerror-impl.h m4/strerror.m4 Depends-on: -- In memoriam Anne Boleyn <http://en.wikipedia.org/wiki/Anne_Boleyn>