Full_Name: Hallvard B Furuseth
Version: HEAD, RE23, RE24
OS: 
URL: 
Submission from: (NULL) (129.240.6.233)
Submitted by: hallvard


"grep -i strerror" shows some places <strerror/STRERROR>(errno)
are passed to Debug().  However Debug() can evaluate its arguments
twice: for -d output and syslog.  Thus it can syslog the wrong
message, since the -d stdio call can change errno.

Also strerror() can return NULL, which can break with Debug(%s).
STRERROR() fixes that, but not the duplicate call.  And strerror
too can change errno:-(  So the STRERROR() variant
  #elif defined( HAVE_STRERROR )
  #define STRERROR(e) ( strerror(e) ? strerror(e) : _AC_ERRNO_UNKNOWN )
in include/ac/errno.h isn't quite safe either.

I suggest we put something like below in ac/string.h or
ac/errno.h, then we can usually say
        if (whatever) {
                DEF_STRERROR(msg, errno);
                Debug(..., msg, ...);
        }

ac/something.h:
#define DEF_STRERROR(msg, err) \
        DECL_STRERROR(msg); \
        SET_STRERROR(msg, err)

#ifdef HAVE_SYS_ERRLIST
#define DECL_STRERROR(msg) \
        unsigned int msg##_err_; \
        const char *msg
#define SET_STRERROR(msg, err) \
        ((void)(msg = (msg##_err_ = (e)) < (unsigned) sys_nerr \
                        ? sys_errlist[msg##_err_] : _AC_ERRNO_UNKNOWN))

#elif <threaded> && defined( HAVE_NONPOSIX_STRERROR_R )
#define DECL_STRERROR(msg) \
        char msg##_buf_[80]; \
        const char *msg
#define SET_STRERROR(msg, err) \
        ((void) ((msg = strerror_r(err, msg##_buf_, 80)) || \
                (msg = _AC_ERRNO_UNKNOWN)))

#elif <threaded> && defined( HAVE_STRERROR_R )
#define DECL_STRERROR(msg) \
        char msg##_buf_[80]; \
        const char *msg
#define SET_STRERROR(msg, err) \
        ((void) (msg = strerror_r(err, msg##_buf_, 80) != -1 \
                ? msg##_buf_ : _AC_ERRNO_UNKNOWN))

#elif defined( HAVE_STRERROR )
#define DECL_STRERROR(msg) \
        const char *msg
#define SET_STRERROR(msg, err) \
        ((void) ((msg = strerror(err)) || (msg = _AC_ERRNO_UNKNOWN)))

#else
#define DECL_STRERROR(msg)      const char *msg
#define SET_STRERROR(msg, err)  ((void) (msg = "Unknown error"))
#endif


Don't know what the #if <threaded> test should look like, see ITS#5421.


Reply via email to