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	Tue Sep 25 02:05:06 2007 +0200
+++ b/ChangeLog	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/doc/functions/strerror.texi	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/lib/strerror.c	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/lib/string_.h	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/m4/strerror.m4	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/m4/string_h.m4	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/modules/argp	Tue Sep 25 10:40:16 2007 -0600
@@ -30,6 +30,7 @@
 extensions
 vsnprintf
 sleep
+strerror
 
 configure.ac:
 gl_ARGP
--- a/modules/error	Tue Sep 25 02:05:06 2007 +0200
+++ b/modules/error	Tue Sep 25 10:40:16 2007 -0600
@@ -7,6 +7,7 @@
 m4/error.m4
 
 Depends-on:
+strerror
 
 configure.ac:
 gl_ERROR
--- a/modules/strerror	Tue Sep 25 02:05:06 2007 +0200
+++ b/modules/strerror	Tue Sep 25 10:40:16 2007 -0600
@@ -6,9 +6,11 @@
 m4/strerror.m4
 
 Depends-on:
+string
 
 configure.ac:
 gl_FUNC_STRERROR
+gl_STRING_MODULE_INDICATOR([strerror])
 
 Makefile.am:
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/strerror-tests	Tue Sep 25 10:40:16 2007 -0600
@@ -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	Tue Sep 25 02:05:06 2007 +0200
+++ b/modules/string	Tue Sep 25 10:40:16 2007 -0600
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-strerror.c	Tue Sep 25 10:40:16 2007 -0600
@@ -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;
+}