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