Home | History | Annotate | Download | only in bionic
      1 /* $OpenBSD: strerror_r.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
      2 /* Public Domain <marc (at) snafu.org> */
      3 
      4 #include <errno.h>
      5 #include <limits.h>
      6 #include <signal.h>
      7 #include <stdio.h>
      8 #include <string.h>
      9 
     10 #include "private/ErrnoRestorer.h"
     11 #include "private/libc_logging.h"
     12 
     13 struct Pair {
     14   int code;
     15   const char* msg;
     16 };
     17 
     18 static const char* __code_string_lookup(const Pair* strings, int code) {
     19   for (size_t i = 0; strings[i].msg != NULL; ++i) {
     20     if (strings[i].code == code) {
     21       return strings[i].msg;
     22     }
     23   }
     24   return NULL;
     25 }
     26 
     27 static const Pair _sys_error_strings[] = {
     28 #define  __BIONIC_ERRDEF(x,y,z)  { x, z },
     29 #include <sys/_errdefs.h>
     30   { 0, NULL }
     31 };
     32 
     33 extern "C" __LIBC_HIDDEN__ const char* __strerror_lookup(int error_number) {
     34   return __code_string_lookup(_sys_error_strings, error_number);
     35 }
     36 
     37 static const Pair _sys_signal_strings[] = {
     38 #define  __BIONIC_SIGDEF(signal_number, signal_description)  { signal_number, signal_description },
     39 #include <sys/_sigdefs.h>
     40   { 0, NULL }
     41 };
     42 
     43 extern "C" __LIBC_HIDDEN__ const char* __strsignal_lookup(int signal_number) {
     44   return __code_string_lookup(_sys_signal_strings, signal_number);
     45 }
     46 
     47 int strerror_r(int error_number, char* buf, size_t buf_len) {
     48   ErrnoRestorer errno_restorer;
     49   size_t length;
     50 
     51   const char* error_name = __strerror_lookup(error_number);
     52   if (error_name != NULL) {
     53     length = strlcpy(buf, error_name, buf_len);
     54   } else {
     55     length = __libc_format_buffer(buf, buf_len, "Unknown error %d", error_number);
     56   }
     57   if (length >= buf_len) {
     58     errno_restorer.override(ERANGE);
     59     return -1;
     60   }
     61 
     62   return 0;
     63 }
     64 
     65 extern "C" __LIBC_HIDDEN__ const char* __strsignal(int signal_number, char* buf, size_t buf_len) {
     66   const char* signal_name = __strsignal_lookup(signal_number);
     67   if (signal_name != NULL) {
     68     return signal_name;
     69   }
     70 
     71   const char* prefix = "Unknown";
     72   if (signal_number >= SIGRTMIN && signal_number <= SIGRTMAX) {
     73     prefix = "Real-time";
     74     signal_number -= SIGRTMIN;
     75   }
     76   size_t length = snprintf(buf, buf_len, "%s signal %d", prefix, signal_number);
     77   if (length >= buf_len) {
     78     return NULL;
     79   }
     80   return buf;
     81 }
     82