bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

GNU tar 1.19 doesn't build on Solaris 8 due to strerror problem


From: Paul Eggert
Subject: GNU tar 1.19 doesn't build on Solaris 8 due to strerror problem
Date: Thu, 11 Oct 2007 14:50:02 -0700
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux)

GNU tar 1.19 doesn't build on Solaris 8, because strerror.c uses
CHAR_BIT without defining it.  The problem occurs on any hosts that
has strerror but where strerror(-2) doesn't return a useful string.

strerror.c contains multiple copies of integer-printing code, and one
copy neglects to include <limits.h>, which defines CHAR_BIT.  I
revamped the code to simplify it, to help avoid this sort of problem
in the future.  The new version no longer caters well to ancient Unix
hosts that lack strerror but have sys_errlist, but these are no longer
of practical importance (the code still runs on them, it just produces
less-useful strings).

Here's what I installed into gnulib.

2007-10-11  Paul Eggert  <address@hidden>

        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.

diff --git a/lib/strerror.c b/lib/strerror.c
index fd5ec15..9b9ffd1 100644
--- a/lib/strerror.c
+++ b/lib/strerror.c
@@ -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
@@ -18,61 +17,33 @@

 #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
diff --git a/lib/string.in.h b/lib/string.in.h
index 41e539f..ba7ca53 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -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 address@hidden@ || @REPLACE_STRERROR@
 extern char *strerror (int);
 # endif
 #elif defined GNULIB_POSIXCHECK
diff --git a/m4/strerror.m4 b/m4/strerror.m4
index 52f3e3f..f59c710 100644
--- a/m4/strerror.m4
+++ b/m4/strerror.m4
@@ -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])
 ])
diff --git a/modules/strerror b/modules/strerror
index 24dacab..2e914b3 100644
--- a/modules/strerror
+++ b/modules/strerror
@@ -6,6 +6,7 @@ lib/strerror.c
 m4/strerror.m4

 Depends-on:
+intprops
 string

 configure.ac:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]