Mercurial > hg > octave-lyh > gnulib-hg
changeset 9224:404ee875898f
Fix strerror on Interix.
* lib/string_.h (strerror): Declare replacement.
* doc/functions/strerror.texi (strerror): Document the Interix
shortcoming.
* modules/string (Makefile.am): Support new hooks.
* m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): Add new hooks.
* m4/strerror.m4 (gl_FUNC_STRERROR): Defer to
gl_FUNC_STRERROR_SEPARATE.
(gl_FUNC_STRERROR_SEPARATE): Check for Interix bug.
* lib/strerror.c (rpl_strerror): Provide replacement.
* modules/strerror (Depends-on): Add string.
(configure.ac): Detect use of module.
* tests/test-strerror.c: New file.
* modules/strerror-tests: New test module.
* modules/argp (Depends-on): Add strerror.
* modules/error (Depends-on): Likewise.
Reported by Martin Koeppe.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Tue, 25 Sep 2007 10:40:16 -0600 |
parents | eea467fa230c |
children | 5a4ec2c38ec4 |
files | ChangeLog doc/functions/strerror.texi lib/strerror.c lib/string_.h m4/strerror.m4 m4/string_h.m4 modules/argp modules/error modules/strerror modules/strerror-tests modules/string tests/test-strerror.c |
diffstat | 12 files changed, 167 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2007-09-25 Eric Blake <ebb9@byu.net> + + Fix strerror on Interix. + * lib/string_.h (strerror): Declare replacement. + * doc/functions/strerror.texi (strerror): Document the Interix + shortcoming. + * modules/string (Makefile.am): Support new hooks. + * m4/string_h.m4 (gl_HEADER_STRING_H_DEFAULTS): Add new hooks. + * m4/strerror.m4 (gl_FUNC_STRERROR): Defer to + gl_FUNC_STRERROR_SEPARATE. + (gl_FUNC_STRERROR_SEPARATE): Check for Interix bug. + * lib/strerror.c (rpl_strerror): Provide replacement. + * modules/strerror (Depends-on): Add string. + (configure.ac): Detect use of module. + * tests/test-strerror.c: New file. + * modules/strerror-tests: New test module. + * modules/argp (Depends-on): Add strerror. + * modules/error (Depends-on): Likewise. + Reported by Martin Koeppe. + 2007-09-24 Bruno Haible <bruno@clisp.org> * README: Update git instructions.
--- a/doc/functions/strerror.texi +++ b/doc/functions/strerror.texi @@ -10,6 +10,11 @@ @itemize @item This function is missing on some old platforms. + +@item +This function fails to return a string for out-of-range integers on +some platforms: +Interix @end itemize Portability problems not fixed by Gnulib:
--- a/lib/strerror.c +++ b/lib/strerror.c @@ -19,7 +19,29 @@ #include <config.h> -#if !HAVE_STRERROR +#if REPLACE_STRERROR + +# include <string.h> +# include <stdio.h> + +# undef strerror + +char *rpl_strerror (int n) +{ + static char const fmt[] = "Unknown error (%d)"; + static char mesg[sizeof fmt + sizeof n * CHAR_BIT / 3]; + + char *result = strerror (n); + + if (! result) + { + sprintf (mesg, fmt, n); + return mesg; + } + return result; +} + +#elif !HAVE_STRERROR #include <limits.h>
--- a/lib/string_.h +++ b/lib/string_.h @@ -539,6 +539,23 @@ extern char * mbstok_r (char *string, const char *delim, char **save_ptr); #endif +/* Map any int, typically from errno, into an error message. */ +#if @GNULIB_STRERROR@ +# if @REPLACE_STRERROR@ +# undef strerror +# define strerror rpl_strerror +# endif +# if !@HAVE_DECL_STRERROR@ || @REPLACE_STRERROR@ +extern char *strerror (int); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strerror +# define strerror(e) \ + (GL_LINK_WARNING ("strerror is unportable - " \ + "use gnulib module strerror to guarantee non-NULL result"), \ + strerror (e)) +#endif + #ifdef __cplusplus }
--- a/m4/strerror.m4 +++ b/m4/strerror.m4 @@ -1,4 +1,4 @@ -# strerror.m4 serial 3 +# strerror.m4 serial 4 dnl Copyright (C) 2002, 2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -6,10 +6,11 @@ AC_DEFUN([gl_FUNC_STRERROR], [ - AC_CHECK_FUNCS_ONCE([strerror]) - if test $ac_cv_func_strerror = no; then + AC_REQUIRE([gl_FUNC_STRERROR_SEPARATE]) + if test $gl_cv_func_working_strerror = no; then AC_LIBOBJ([strerror]) - gl_PREREQ_STRERROR + AC_DEFINE_UNQUOTED([REPLACE_STRERROR], [$REPLACE_STRERROR], + [Define this to 1 if strerror is broken.]) fi ]) @@ -18,6 +19,28 @@ [ AC_CHECK_FUNCS_ONCE([strerror]) gl_PREREQ_STRERROR + if test $ac_cv_func_strerror = no; then + HAVE_DECL_STRERROR=0 + gl_cv_func_working_strerror=no + else + AC_CACHE_CHECK([for working strerror function], + [gl_cv_func_working_strerror], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([ +#include <string.h> + ], [return !*strerror (-2);])], + [gl_cv_func_working_strerror=yes], [gl_cv_func_working_strerror=no], + [dnl assume success except on Interix + AC_EGREP_CPP([assuming success], [ +#ifndef __INTERIX + assuming success +#endif + ], [gl_cv_func_working_strerror=yes], + [gl_cv_func_working_strerror=no])])]) + if test $gl_cv_func_working_strerror = no ; then + REPLACE_STRERROR=1 + fi + fi ]) # Prerequisites of lib/strerror.c.
--- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -57,6 +57,7 @@ GNULIB_MBSSPN=0; AC_SUBST([GNULIB_MBSSPN]) GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R]) + GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) @@ -74,4 +75,6 @@ HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP]) HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) + HAVE_DECL_STRERROR=1; AC_SUBST([HAVE_DECL_STRERROR]) + REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) ])
--- a/modules/argp +++ b/modules/argp @@ -30,6 +30,7 @@ extensions vsnprintf sleep +strerror configure.ac: gl_ARGP
--- a/modules/error +++ b/modules/error @@ -7,6 +7,7 @@ m4/error.m4 Depends-on: +strerror configure.ac: gl_ERROR
--- a/modules/strerror +++ b/modules/strerror @@ -6,9 +6,11 @@ m4/strerror.m4 Depends-on: +string configure.ac: gl_FUNC_STRERROR +gl_STRING_MODULE_INDICATOR([strerror]) Makefile.am:
new file mode 100644 --- /dev/null +++ b/modules/strerror-tests @@ -0,0 +1,10 @@ +Files: +tests/test-strerror.c + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-strerror +check_PROGRAMS += test-strerror
--- a/modules/string +++ b/modules/string @@ -50,6 +50,7 @@ -e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \ -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \ -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \ + -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \ -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ -e 's|@''HAVE_DECL_MEMRCHR''@|$(HAVE_DECL_MEMRCHR)|g' \ @@ -66,6 +67,8 @@ -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ + -e 's|@''HAVE_DECL_STRERROR''@|$(HAVE_DECL_STRERROR)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ < $(srcdir)/string_.h; \ } > $@-t
new file mode 100644 --- /dev/null +++ b/tests/test-strerror.c @@ -0,0 +1,55 @@ +/* Test of strerror() function. + Copyright (C) 2007 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. */ + +/* Written by Eric Blake <ebb9@byu.net>, 2007. */ + +#include <config.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + abort (); \ + } \ + } \ + while (0) + +int +main (int argc, char **argv) +{ + char *str; + str = strerror (EACCES); + ASSERT (str); + ASSERT (*str); + + str = strerror (0); + ASSERT (str); + ASSERT (*str); + + str = strerror (-3); + ASSERT (str); + ASSERT (*str); + + return 0; +}