Simplify and modernize strerror substitute, partly to fix Solaris 8 bug.
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 11 Oct 2007 21:43:30 +0000 (14:43 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 11 Oct 2007 21:43:30 +0000 (14:43 -0700)
* lib/strerror.c: Include <string.h> always, to test interface,
and to remove the need for the dummy.
Include intprops.h to compute width instead of doing it ourselves
and missing a CHAR_BIT declaration, which broke tar 1.19 on Solaris 8.
(strerror): Define it to return NULL if there's no system strerror.
(rpl_strerror): Use INT_STRLEN_BOUND to compute bound.
Omit !HAVE_STRERROR code.  We don't need to worry about supporting
ancient pre-strerror Unix systems well any more.  Saying "unknown
system error" is enough.
* lib/string.in.h (strerror): Simplify the ifdef to reflect the
simpler strerror.c implementation.
* m4/strerror.m4 (gl_FUNC_STRERROR_SEPARATE, gl_PREREQ_STDERROR):
Simplify the tests to reflect the simpler strerror implementation.
* modules/strerror (Depends-on): Add intprops.

ChangeLog
lib/strerror.c
lib/string.in.h
m4/strerror.m4
modules/strerror

index bb9a664..bc1abee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2007-10-11  Paul Eggert  <eggert@cs.ucla.edu>
+
+       Simplify and modernize strerror substitute, partly to fix Solaris 8 bug.
+
+       * lib/strerror.c: Include <string.h> always, to test interface,
+       and to remove the need for the dummy.
+       Include intprops.h to compute width instead of doing it ourselves
+       and missing a CHAR_BIT declaration, which broke tar 1.19 on Solaris 8.
+       (strerror): Define it to return NULL if there's no system strerror.
+       (rpl_strerror): Use INT_STRLEN_BOUND to compute bound.
+       Omit !HAVE_STRERROR code.  We don't need to worry about supporting
+       ancient pre-strerror Unix systems well any more.  Saying "unknown
+       system error" is enough.
+       * lib/string.in.h (strerror): Simplify the ifdef to reflect the
+       simpler strerror.c implementation.
+       * m4/strerror.m4 (gl_FUNC_STRERROR_SEPARATE, gl_PREREQ_STDERROR):
+       Simplify the tests to reflect the simpler strerror implementation.
+       * modules/strerror (Depends-on): Add intprops.
+
 2007-10-09  Eric Blake  <ebb9@byu.net>
 
        Silence test-fpending.
index fd5ec15..9b9ffd1 100644 (file)
@@ -1,7 +1,6 @@
-/* strerror.c --- ANSI C compatible system error routine
+/* strerror.c --- POSIX compatible system error routine
 
-   Copyright (C) 1986, 1988, 1989, 1991, 2002, 2003, 2006, 2007 Free
-   Software Foundation, Inc.
+   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
 
 #include <config.h>
 
+#include <string.h>
+
 #if REPLACE_STRERROR
 
-# include <string.h>
 # include <stdio.h>
 
+# include "intprops.h"
+
 # undef strerror
+# if ! HAVE_DECL_STRERROR
+#  define strerror(n) NULL
+# endif
 
-char *rpl_strerror (int n)
+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)
     {
+      static char const fmt[] = "Unknown error (%d)";
+      static char mesg[sizeof fmt + INT_STRLEN_BOUND (n)];
       sprintf (mesg, fmt, n);
       return mesg;
     }
-  return result;
-}
-
-#elif !HAVE_STRERROR
-
-#include <limits.h>
 
-/* Don't include <stdio.h>, since it may or may not declare
-   sys_errlist and its declarations may collide with ours.  Just
-   declare the stuff that we need directly.  Standard hosted C89
-   implementations define strerror and they don't need this strerror
-   function, so take some liberties with the standard to cater to
-   ancient or limited freestanding implementations.  */
-int sprintf (char *, char const *, ...);
-extern int sys_nerr;
-extern char *sys_errlist[];
-
-char *
-strerror (int n)
-{
-  static char const fmt[] = "Unknown error (%d)";
-  static char mesg[sizeof fmt + sizeof n * CHAR_BIT / 3];
-
-  if (n < 0 || n >= sys_nerr)
-    {
-      sprintf (mesg, fmt, n);
-      return mesg;
-    }
-  else
-    return sys_errlist[n];
+  return result;
 }
 
-#else
-
-/* This declaration is solely to ensure that after preprocessing
-   this file is never empty.  */
-typedef int dummy;
-
 #endif
index 41e539f..ba7ca53 100644 (file)
@@ -544,8 +544,6 @@ extern char * mbstok_r (char *string, const char *delim, char **save_ptr);
 # 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
index 52f3e3f..f59c710 100644 (file)
@@ -1,4 +1,4 @@
-# strerror.m4 serial 4
+# strerror.m4 serial 5
 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,
@@ -17,33 +17,33 @@ AC_DEFUN([gl_FUNC_STRERROR],
 # Like gl_FUNC_STRERROR, except prepare for separate compilation (no AC_LIBOBJ).
 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
+  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 crossbuild works if it compiles, except for Interix.
+       AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+           [#include <string.h>
+            #ifdef __INTERIX
+              Interix is broken;
+            #endif
+           ],
+           [return !*strerror (-2);])],
+        [gl_cv_func_working_strerror=yes],
+        [gl_cv_func_working_strerror=no])])])
+  if test $gl_cv_func_working_strerror = no ; then
+    REPLACE_STRERROR=1
+    gl_PREREQ_STRERROR
   fi
 ])
 
 # Prerequisites of lib/strerror.c.
 AC_DEFUN([gl_PREREQ_STRERROR], [
-  :
+  AC_CHECK_DECLS([strerror])
 ])
index 24dacab..2e914b3 100644 (file)
@@ -6,6 +6,7 @@ lib/strerror.c
 m4/strerror.m4
 
 Depends-on:
+intprops
 string
 
 configure.ac: