diff options
author | Irina Tirdea <irina.tirdea@intel.com> | 2012-09-08 09:17:54 +0300 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2012-09-13 15:18:21 -0700 |
commit | b5f053b5a7deb084e7a052d527e0aa41339ae05c (patch) | |
tree | a75d6715f7c7c954d22440b8c21c59b01d87e83d /libc/bionic/strerror_r.cpp | |
parent | 4a9b7c694a8312160d3cd953a8227c23a1624868 (diff) | |
download | bionic-b5f053b5a7deb084e7a052d527e0aa41339ae05c.zip bionic-b5f053b5a7deb084e7a052d527e0aa41339ae05c.tar.gz bionic-b5f053b5a7deb084e7a052d527e0aa41339ae05c.tar.bz2 |
Make strerror(3) and strsignal(3) thread-safe, and add psignal(3) and psiginfo(3).
Change-Id: I426109db25e907980d6cb3a7a695796e45783b78
Diffstat (limited to 'libc/bionic/strerror_r.cpp')
-rw-r--r-- | libc/bionic/strerror_r.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/libc/bionic/strerror_r.cpp b/libc/bionic/strerror_r.cpp new file mode 100644 index 0000000..92235a5 --- /dev/null +++ b/libc/bionic/strerror_r.cpp @@ -0,0 +1,71 @@ +/* $OpenBSD: strerror_r.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ +/* Public Domain <marc@snafu.org> */ + +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> + +struct Pair { + int code; + const char* msg; +}; + +static const char* __code_string_lookup(const Pair* strings, int code) { + for (size_t i = 0; strings[i].msg != NULL; ++i) { + if (strings[i].code == code) { + return strings[i].msg; + } + } + return NULL; +} + +static const Pair _sys_error_strings[] = { +#define __BIONIC_ERRDEF(x,y,z) { x, z }, +#include <sys/_errdefs.h> + { 0, NULL } +}; + +int strerror_r(int error_number, char* buf, size_t buf_len) { + int saved_errno = errno; + size_t length; + + const char* error_name = __code_string_lookup(_sys_error_strings, error_number); + if (error_name != NULL) { + length = snprintf(buf, buf_len, "%s", error_name); + } else { + length = snprintf(buf, buf_len, "Unknown error %u", error_number); + } + if (length >= buf_len) { + errno = ERANGE; + return -1; + } + + errno = saved_errno; + return 0; +} + +static const Pair _sys_signal_strings[] = { +#define __BIONIC_SIGDEF(x,y,z) { y, z }, +#include <sys/_sigdefs.h> + { 0, NULL } +}; + +extern "C" const char* __strsignal(int signal_number, char* buf, size_t buf_len) { + const char* signal_name = __code_string_lookup(_sys_signal_strings, signal_number); + if (signal_name != NULL) { + return signal_name; + } + + const char* prefix = "Unknown"; + if (signal_number >= SIGRTMIN && signal_number <= SIGRTMAX) { + prefix = "Real-time"; + signal_number -= SIGRTMIN; + } + size_t length = snprintf(buf, buf_len, "%s signal %d", prefix, signal_number); + if (length >= buf_len) { + return NULL; + } + return buf; +} |