utils: Move thread-safe strerror replacement to a separate file
For some utils _GNU_SOURCE might be needed but that conflicts with the signature of strerror_r(3).
This commit is contained in:
@@ -303,84 +303,6 @@ char* tty_escape_get(int fd, tty_escape_t escape)
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the thread-specific error buffer
|
||||
*/
|
||||
#define STRERROR_BUF_LEN 256
|
||||
|
||||
/**
|
||||
* Key to store thread-specific error buffer
|
||||
*/
|
||||
static pthread_key_t strerror_buf_key;
|
||||
|
||||
/**
|
||||
* Only initialize the key above once
|
||||
*/
|
||||
static pthread_once_t strerror_buf_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
/**
|
||||
* Create the key used for the thread-specific error buffer
|
||||
*/
|
||||
static void create_strerror_buf_key()
|
||||
{
|
||||
pthread_key_create(&strerror_buf_key, free);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the error buffer assigned to the current thread (or create it)
|
||||
*/
|
||||
static inline char *get_strerror_buf()
|
||||
{
|
||||
char *buf;
|
||||
|
||||
pthread_once(&strerror_buf_key_once, create_strerror_buf_key);
|
||||
buf = pthread_getspecific(strerror_buf_key);
|
||||
if (!buf)
|
||||
{
|
||||
buf = malloc(STRERROR_BUF_LEN);
|
||||
pthread_setspecific(strerror_buf_key, buf);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRERROR_R
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
const char *safe_strerror(int errnum)
|
||||
{
|
||||
char *buf = get_strerror_buf(), *msg;
|
||||
|
||||
#ifdef STRERROR_R_CHAR_P
|
||||
/* char* version which may or may not return the original buffer */
|
||||
msg = strerror_r(errnum, buf, STRERROR_BUF_LEN);
|
||||
#else
|
||||
/* int version returns 0 on success */
|
||||
msg = strerror_r(errnum, buf, STRERROR_BUF_LEN) ? "Unknown error" : buf;
|
||||
#endif
|
||||
return msg;
|
||||
}
|
||||
#else /* HAVE_STRERROR_R */
|
||||
/* we actually wan't to call strerror(3) below */
|
||||
#undef strerror
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
const char *safe_strerror(int errnum)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
char *buf = get_strerror_buf();
|
||||
|
||||
/* use a mutex to ensure calling strerror(3) is thread-safe */
|
||||
pthread_mutex_lock(&mutex);
|
||||
strncpy(buf, strerror(errnum), STRERROR_BUF_LEN);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
buf[STRERROR_BUF_LEN - 1] = '\0';
|
||||
return buf;
|
||||
}
|
||||
#endif /* HAVE_STRERROR_R */
|
||||
|
||||
|
||||
#ifndef HAVE_CLOSEFROM
|
||||
/**
|
||||
* Described in header.
|
||||
|
||||
Reference in New Issue
Block a user