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.c124
1 files changed, 124 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..c0ca434cbd
--- /dev/null
+++ b/src/lib/libc/string/strerror_r.c
@@ -0,0 +1,124 @@
1/* $OpenBSD: strerror_r.c,v 1.3 2005/04/20 23:38:15 beck Exp $ */
2/* Public Domain <marc@snafu.org> */
3
4#if defined(LIBC_SCCS) && !defined(lint)
5static char *rcsid = "$OpenBSD: strerror_r.c,v 1.3 2005/04/20 23:38:15 beck Exp $";
6#endif /* LIBC_SCCS and not lint */
7
8#ifdef NLS
9#define catclose _catclose
10#define catgets _catgets
11#define catopen _catopen
12#include <nl_types.h>
13#endif
14
15#define sys_errlist _sys_errlist
16#define sys_nerr _sys_nerr
17
18#include <errno.h>
19#include <limits.h>
20#include <string.h>
21
22static size_t
23__digits10(unsigned int num)
24{
25 size_t i = 0;
26
27 do {
28 num /= 10;
29 i++;
30 } while (num != 0);
31
32 return i;
33}
34
35static void
36__itoa(int num, char *buffer, size_t start, size_t end)
37{
38 size_t pos;
39 unsigned int a;
40 int neg;
41
42 if (num < 0) {
43 a = -num;
44 neg = 1;
45 }
46 else {
47 a = num;
48 neg = 0;
49 }
50
51 pos = start + __digits10(a);
52 if (neg)
53 pos++;
54
55 if (pos < end)
56 buffer[pos] = '\0';
57 else {
58 if (end)
59 buffer[--end] = '\0'; /* XXX */
60 }
61 pos--;
62 do {
63
64 if (pos < end)
65 buffer[pos] = (a % 10) + '0';
66 pos--;
67 a /= 10;
68 } while (a != 0);
69 if (neg)
70 if (pos < end)
71 buffer[pos] = '-';
72}
73
74
75#define UPREFIX "Unknown error: "
76
77int
78strerror_r(int errnum, char *strerrbuf, size_t buflen)
79{
80 int save_errno;
81 int ret_errno;
82 size_t len;
83#ifdef NLS
84 nl_catd catd;
85#endif
86
87 save_errno = errno;
88 ret_errno = 0;
89
90#ifdef NLS
91 catd = catopen("libc", 0);
92#endif
93
94 if (errnum >= 0 && errnum < sys_nerr) {
95#ifdef NLS
96 len = strlcpy(strerrbuf, catgets(catd, 1, errnum,
97 (char *)sys_errlist[errnum]), buflen);
98#else
99 len = strlcpy(strerrbuf, sys_errlist[errnum], buflen);
100#endif
101 if (len >= buflen)
102 ret_errno = ERANGE;
103 } else {
104#ifdef NLS
105 len = strlcpy(strerrbuf, catgets(catd, 1, 0xffff, UPREFIX),
106 buflen);
107#else
108 len = strlcpy(strerrbuf, UPREFIX, buflen);
109#endif
110 if (len >= buflen)
111 ret_errno = ERANGE;
112 else {
113 __itoa(errnum, strerrbuf, len, buflen);
114 ret_errno = EINVAL;
115 }
116 }
117
118#ifdef NLS
119 catclose(catd);
120#endif
121
122 errno = ret_errno ? ret_errno : save_errno;
123 return (ret_errno);
124}