summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2007-09-25 10:40:16 -0600
committerEric Blake <ebb9@byu.net>2007-09-25 10:40:16 -0600
commitd5d3e86d326de4aa7d661fde1ebb636f3efbffd5 (patch)
tree63d0f761271c9884d613824cfd89f42caeda91bf
parenta1d5bf4615a98dd53267bf49646a09b823df3fe2 (diff)
downloadgnulib-d5d3e86d326de4aa7d661fde1ebb636f3efbffd5.tar.gz
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>
-rw-r--r--ChangeLog20
-rw-r--r--doc/functions/strerror.texi5
-rw-r--r--lib/strerror.c24
-rw-r--r--lib/string_.h17
-rw-r--r--m4/strerror.m431
-rw-r--r--m4/string_h.m43
-rw-r--r--modules/argp1
-rw-r--r--modules/error1
-rw-r--r--modules/strerror2
-rw-r--r--modules/strerror-tests10
-rw-r--r--modules/string3
-rw-r--r--tests/test-strerror.c55
12 files changed, 167 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 90c041432e..78fa16cada 100644
--- 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.
diff --git a/doc/functions/strerror.texi b/doc/functions/strerror.texi
index 9ac63e5a6e..aad375497d 100644
--- a/doc/functions/strerror.texi
+++ b/doc/functions/strerror.texi
@@ -10,6 +10,11 @@ Portability problems fixed by Gnulib:
@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:
diff --git a/lib/strerror.c b/lib/strerror.c
index 54b851bdaf..ef6234e4fa 100644
--- 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>
diff --git a/lib/string_.h b/lib/string_.h
index bfb22b0ebc..41e539f235 100644
--- a/lib/string_.h
+++ b/lib/string_.h
@@ -539,6 +539,23 @@ extern char * mbssep (char **stringp, const char *delim);
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
}
diff --git a/m4/strerror.m4 b/m4/strerror.m4
index bbcda30508..52f3e3fdc3 100644
--- 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 @@ dnl with or without modifications, as long as this notice is preserved.
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_DEFUN([gl_FUNC_STRERROR_SEPARATE],
[
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.
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index ec51e9a018..d811e26b88 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -57,6 +57,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
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 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS],
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])
])
diff --git a/modules/argp b/modules/argp
index b188e8ac5e..da65d4f3c0 100644
--- a/modules/argp
+++ b/modules/argp
@@ -30,6 +30,7 @@ strcase
extensions
vsnprintf
sleep
+strerror
configure.ac:
gl_ARGP
diff --git a/modules/error b/modules/error
index 4e999ca88e..cdf57f07d5 100644
--- a/modules/error
+++ b/modules/error
@@ -7,6 +7,7 @@ lib/error.c
m4/error.m4
Depends-on:
+strerror
configure.ac:
gl_ERROR
diff --git a/modules/strerror b/modules/strerror
index f86dd709ff..24dacabe12 100644
--- a/modules/strerror
+++ b/modules/strerror
@@ -6,9 +6,11 @@ lib/strerror.c
m4/strerror.m4
Depends-on:
+string
configure.ac:
gl_FUNC_STRERROR
+gl_STRING_MODULE_INDICATOR([strerror])
Makefile.am:
diff --git a/modules/strerror-tests b/modules/strerror-tests
new file mode 100644
index 0000000000..0341c12c51
--- /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
diff --git a/modules/string b/modules/string
index e6d5762025..c4e9f2f9b3 100644
--- a/modules/string
+++ b/modules/string
@@ -50,6 +50,7 @@ string.h: string_.h
-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 @@ string.h: string_.h
-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
diff --git a/tests/test-strerror.c b/tests/test-strerror.c
new file mode 100644
index 0000000000..036ce458cd
--- /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;
+}