summaryrefslogtreecommitdiff
path: root/src/lib/libc/string/strerror_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/string/strerror_r.c')
-rw-r--r--src/lib/libc/string/strerror_r.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/lib/libc/string/strerror_r.c b/src/lib/libc/string/strerror_r.c
new file mode 100644
index 0000000000..aa63408ab8
--- /dev/null
+++ b/src/lib/libc/string/strerror_r.c
@@ -0,0 +1,137 @@
1/* $OpenBSD: strerror_r.c,v 1.7 2007/03/01 16:29:09 bluhm Exp $ */
2/* Public Domain <marc@snafu.org> */
3
4#ifdef NLS
5#define catclose _catclose
6#define catgets _catgets
7#define catopen _catopen
8#include <nl_types.h>
9#endif
10
11#define sys_errlist _sys_errlist
12#define sys_nerr _sys_nerr
13#define sys_siglist _sys_siglist
14
15#include <errno.h>
16#include <limits.h>
17#include <signal.h>
18#include <string.h>
19
20static size_t
21__digits10(unsigned int num)
22{
23 size_t i = 0;
24
25 do {
26 num /= 10;
27 i++;
28 } while (num != 0);
29
30 return i;
31}
32
33static int
34__itoa(int num, int sign, char *buffer, size_t start, size_t end)
35{
36 size_t pos;
37 unsigned int a;
38 int neg;
39
40 if (sign && num < 0) {
41 a = -num;
42 neg = 1;
43 }
44 else {
45 a = num;
46 neg = 0;
47 }
48
49 pos = start + __digits10(a);
50 if (neg)
51 pos++;
52
53 if (pos < end)
54 buffer[pos] = '\0';
55 else
56 return ERANGE;
57 pos--;
58 do {
59 buffer[pos] = (a % 10) + '0';
60 pos--;
61 a /= 10;
62 } while (a != 0);
63 if (neg)
64 buffer[pos] = '-';
65 return 0;
66}
67
68
69static int
70__num2string(int num, int sign, int setid, char *buf, size_t buflen,
71 char * list[], size_t max, const char *def)
72{
73 int ret = 0;
74 size_t len;
75
76#ifdef NLS
77 nl_catd catd;
78 catd = catopen("libc", 0);
79#endif
80
81 if (0 <= num && num < max) {
82#ifdef NLS
83 len = strlcpy(buf, catgets(catd, setid, num, list[num]),
84 buflen);
85#else
86 len = strlcpy(buf, list[num], buflen);
87#endif
88 if (len >= buflen)
89 ret = ERANGE;
90 } else {
91#ifdef NLS
92 len = strlcpy(buf, catgets(catd, setid, 0xffff, def), buflen);
93#else
94 len = strlcpy(buf, def, buflen);
95#endif
96 if (len >= buflen)
97 ret = ERANGE;
98 else {
99 ret = __itoa(num, sign, buf, len, buflen);
100 if (ret == 0)
101 ret = EINVAL;
102 }
103 }
104
105#ifdef NLS
106 catclose(catd);
107#endif
108
109 return ret;
110}
111
112#define UPREFIX "Unknown error: "
113
114int
115strerror_r(int errnum, char *strerrbuf, size_t buflen)
116{
117 int save_errno;
118 int ret_errno;
119
120 save_errno = errno;
121
122 ret_errno = __num2string(errnum, 1, 1, strerrbuf, buflen,
123 sys_errlist, sys_nerr, UPREFIX);
124
125 errno = ret_errno ? ret_errno : save_errno;
126 return (ret_errno);
127}
128
129#define USIGPREFIX "Unknown signal: "
130
131char *
132__strsignal(int num, char *buf)
133{
134 __num2string(num, 0, 2, buf, NL_TEXTMAX, (char **)sys_siglist, NSIG,
135 USIGPREFIX);
136 return buf;
137}