bug-gnulib
[Top][All Lists]
Advanced

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

a bad use of strerror_r


From: Bruno Haible
Subject: a bad use of strerror_r
Date: Sun, 16 Oct 2016 18:17:17 +0200
User-agent: KMail/4.8.5 (Linux/3.8.0-44-generic; KDE/4.8.5; x86_64; ; )

Hi,

When I compile a gnulib testdir on a glibc system with "gcc -Wall", I see the
following warnings (among others):

argp-help.c: In function 'argp_failure':
argp-help.c:1878:17: warning: assignment makes pointer from integer without a 
cast [enabled by default]

This is a dangerous one, because the code assumes a wrong signature of
strerror_r.

To reproduce, it is enough to have the combination of 3 modules:

$ ./gnulib-tool --create-testdir --with-tests --dir=/tmp/testdir 
strerror_r-posix argp error

When I look at the preprocessed source code for that compilation unit,
I see some more details:

$ gcc ... -E argp-help.c | grep strerror_r
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
extern int rpl_strerror_r (int errnum, char *buf, size_t buflen) __attribute__ 
((__nonnull__ (2)))
              s = rpl_strerror_r (errnum, buf, sizeof buf);


There are two problems:

1) argp-help.c uses STRERROR_R_CHAR_P, which is defined by the macro
   AC_FUNC_STRERROR_R, but argp.m4 does not require it (only error.m4 does).

2) When the strerror_r-posix module is in place, the results of
   AC_FUNC_STRERROR_R have to be ignored, because they don't reflect the
   situation after
     #define strerror_r rpl_strerror_r

With the following proposed patches, we arrive at a sane situation without
warning, and

$ gcc ... -E argp-help.c | grep strerror_r
extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
extern int rpl_strerror_r (int errnum, char *buf, size_t buflen) __attribute__ 
((__nonnull__ (2)))
              if (rpl_strerror_r (errnum, buf, sizeof buf) == 0)


2016-10-16  Bruno Haible  <address@hidden>

        Make the 'argp' module work without the 'error' module.
        * m4/argp.m4 (gl_ARGP): Require AC_FUNC_STRERROR_R.

diff --git a/m4/argp.m4 b/m4/argp.m4
index d36c716..478ec21 100644
--- a/m4/argp.m4
+++ b/m4/argp.m4
@@ -1,4 +1,4 @@
-# argp.m4 serial 14
+# argp.m4 serial 15
 dnl Copyright (C) 2003-2016 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -54,6 +54,7 @@ AC_DEFUN([gl_ARGP],
   AC_CHECK_DECLS_ONCE([putchar_unlocked])
   AC_CHECK_FUNCS_ONCE([flockfile funlockfile])
   AC_CHECK_HEADERS_ONCE([features.h linewrap.h])
+  AC_REQUIRE([AC_FUNC_STRERROR_R])
 ])
 
 dnl argp-parse.c depends on GNU getopt internals, therefore use GNU getopt


2016-10-16  Bruno Haible  <address@hidden>

        Fix conflict between strerror_r-posix module and AC_FUNC_STRERROR_R.
        * m4/strerror_r.m4 (gl_FUNC_STRERROR_R): Override the values set by the
        AC_FUNC_STRERROR_R macro. Define HAVE_DECL_STRERROR_R_ORIG.
        * lib/strerror_r.c: Use HAVE_DECL_STRERROR_R_ORIG instead of
        HAVE_DECL_STRERROR_R.

diff --git a/lib/strerror_r.c b/lib/strerror_r.c
index 07a00cf..b1d4cf5 100644
--- a/lib/strerror_r.c
+++ b/lib/strerror_r.c
@@ -40,7 +40,7 @@ extern
 #endif
 int __xpg_strerror_r (int errnum, char *buf, size_t buflen);
 
-#elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || 
defined __CYGWIN__)
+#elif HAVE_DECL_STRERROR_R_ORIG && !(__GLIBC__ >= 2 || defined __UCLIBC__ || 
defined __CYGWIN__)
 
 /* The system's strerror_r function is OK, except that its third argument
    is 'int', not 'size_t', or its return type is wrong.  */
diff --git a/m4/strerror_r.m4 b/m4/strerror_r.m4
index 2318927..06c51e1 100644
--- a/m4/strerror_r.m4
+++ b/m4/strerror_r.m4
@@ -1,4 +1,4 @@
-# strerror_r.m4 serial 15
+# strerror_r.m4 serial 16
 dnl Copyright (C) 2002, 2007-2016 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -18,6 +18,8 @@ AC_DEFUN([gl_FUNC_STRERROR_R],
   if test $ac_cv_have_decl_strerror_r = no; then
     HAVE_DECL_STRERROR_R=0
   fi
+  AC_DEFINE_UNQUOTED([HAVE_DECL_STRERROR_R_ORIG], [$HAVE_DECL_STRERROR_R],
+    [Define to 1 if you have the declaration of 'strerror_r' in the system 
include files, or to 0 otherwise.])
 
   if test $ac_cv_func_strerror_r = yes; then
     if test "$ERRNO_H:$REPLACE_STRERROR_0" = :0; then
@@ -36,6 +38,11 @@ AC_DEFUN([gl_FUNC_STRERROR_R],
       REPLACE_STRERROR_R=1
     fi
   fi
+
+  # Overwrite the findings of AC_FUNC_STRERROR_R (for code that uses that).
+  AC_REQUIRE([AC_FUNC_STRERROR_R])
+  AC_DEFINE([HAVE_DECL_STRERROR_R], [1])
+  AC_DEFINE([STRERROR_R_CHAR_P], [0])
 ])
 
 # Prerequisites of lib/strerror_r.c.




reply via email to

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