blob: 2f26f173c87caf415fb6d3707a56a05d93d92f58 [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001/* $OpenBSD: strerror_r.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
2/* Public Domain <marc@snafu.org> */
3
4#define sys_siglist _sys_siglist
5
6#include <errno.h>
7#include <limits.h>
8#include <signal.h>
9#include <string.h>
10
11typedef struct {
12 int code;
13 const char* msg;
14} CodeString;
15
16static const char*
17__code_string_lookup( const CodeString* strings,
18 int code )
19{
20 int nn = 0;
21
22 for (;;)
23 {
Elliott Hughesbf018292011-05-13 10:53:53 -070024 if (strings[nn].msg == NULL)
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080025 break;
26
27 if (strings[nn].code == code)
28 return strings[nn].msg;
29
30 nn++;
31 }
32 return NULL;
33}
34
35
36static const CodeString _sys_error_strings[] =
37{
38#define __BIONIC_ERRDEF(x,y,z) { y, z },
39#include <sys/_errdefs.h>
40 { 0, NULL }
41};
42
43static size_t
44__digits10(unsigned int num)
45{
46 size_t i = 0;
47
48 do {
49 num /= 10;
50 i++;
51 } while (num != 0);
52
53 return i;
54}
55
56static int
57__itoa(int num, int sign, char *buffer, size_t start, size_t end)
58{
59 size_t pos;
60 unsigned int a;
61 int neg;
62
63 if (sign && num < 0) {
64 a = -num;
65 neg = 1;
66 }
67 else {
68 a = num;
69 neg = 0;
70 }
71
72 pos = start + __digits10(a);
73 if (neg)
74 pos++;
75
76 if (pos < end)
77 buffer[pos] = '\0';
78 else
79 return ERANGE;
80 pos--;
81 do {
82 buffer[pos] = (a % 10) + '0';
83 pos--;
84 a /= 10;
85 } while (a != 0);
86 if (neg)
87 buffer[pos] = '-';
88 return 0;
89}
90
91
92int
93strerror_r(int errnum, char *strerrbuf, size_t buflen)
94{
95 int save_errno;
96 int len, ret = 0;
97 const char* msg;
98
99 save_errno = errno;
100 msg = __code_string_lookup( _sys_error_strings, errnum );
101 if (msg != NULL) {
102 len = strlcpy(strerrbuf, msg, buflen);
103 if ((size_t)len >= buflen)
104 ret = ERANGE;
105 } else {
106 len = strlcpy(strerrbuf, "Unknown error: ", buflen);
107 if ((size_t)len >= buflen)
108 ret = ERANGE;
109 else {
110 int ret = __itoa(errnum, 1, strerrbuf, len, buflen);
111
112 if (ret == 0)
113 ret = EINVAL;
114 }
115 }
116 return ret;
117}
118
119#if 0
120static const CodeString _sys_signal_strings[] =
121{
122#define SIGDEF(x,y,z) { y, z },
123#include <sys/_sigdefs.h>
124};
125
126
127static int
128__num2string(int num, int sign, int setid, char *buf, size_t buflen,
129 char * list[], size_t max, const char *def)
130{
131 int ret = 0;
132 size_t len;
133
134 if (0 <= num && num < max) {
135 len = strlcpy(buf, def, buflen);
136 if (len >= buflen)
137 ret = ERANGE;
138 } else {
139 len = strlcpy(buf, def, buflen);
140 if (len >= buflen)
141 ret = ERANGE;
142 else {
143 ret = __itoa(num, sign, buf, len, buflen);
144 if (ret == 0)
145 ret = EINVAL;
146 }
147 }
148
149 return ret;
150}
151
152
153
154#define USIGPREFIX "Unknown signal: "
155
156char *
157__strsignal(int num, char *buf)
158{
159 __num2string(num, 0, 2, buf, NL_TEXTMAX, (char **)sys_siglist, NSIG,
160 USIGPREFIX);
161 return buf;
162}
163#endif