diff options
| -rw-r--r-- | hiredis.c | 2 | ||||
| -rw-r--r-- | hiredis.h | 24 | ||||
| -rw-r--r-- | net.c | 2 | 
3 files changed, 26 insertions, 2 deletions
| @@ -579,7 +579,7 @@ void __redisSetError(redisContext *c, int type, const char *str) {      } else {          /* Only REDIS_ERR_IO may lack a description! */          assert(type == REDIS_ERR_IO); -        strerror_r(errno,c->errstr,sizeof(c->errstr)); +        __redis_strerror_r(errno, c->errstr, sizeof(c->errstr));      }  } @@ -76,6 +76,30 @@   * SO_REUSEADDR is being used. */  #define REDIS_CONNECT_RETRIES  10 +/* strerror_r has two completely different prototypes and behaviors + * depending on system issues, so we need to operate on the error buffer + * differently depending on which strerror_r we're using. */ +#ifndef _GNU_SOURCE +/* "regular" POSIX strerror_r that does the right thing. */ +#define __redis_strerror_r(errno, buf, len)                                    \ +    do {                                                                       \ +        strerror_r((errno), (buf), (len));                                     \ +    } while (0) +#else +/* "bad" GNU strerror_r we need to clean up after. */ +#define __redis_strerror_r(errno, buf, len)                                    \ +    do {                                                                       \ +        char *err_str = strerror_r((errno), (buf), (len));                     \ +        /* If return value _isn't_ the start of the buffer we passed in,       \ +         * then GNU strerror_r returned an internal static buffer and we       \ +         * need to copy the result into our private buffer. */                 \ +        if (err_str != (buf)) {                                                \ +            buf[(len)] = '\0';                                                 \ +            strncat((buf), err_str, ((len) - 1));                              \ +        }                                                                      \ +    } while (0) +#endif +  #ifdef __cplusplus  extern "C" {  #endif @@ -67,7 +67,7 @@ static void __redisSetErrorFromErrno(redisContext *c, int type, const char *pref      if (prefix != NULL)          len = snprintf(buf,sizeof(buf),"%s: ",prefix); -    strerror_r(errno,buf+len,sizeof(buf)-len); +    __redis_strerror_r(errno, (char *)(buf + len), sizeof(buf) - len);      __redisSetError(c,type,buf);  } | 
