]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/string/__xpg_strerror_r.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / string / __xpg_strerror_r.c
1 /*
2  * Copyright (C) 2002     Manuel Novoa III
3  * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
4  *
5  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
6  */
7
8 /* get rid of REDIRECT */
9 #define strerror_r __hide_strerror_r
10
11 #include <features.h>
12 #include <errno.h>
13 #include <string.h>
14 #include "_syserrmsg.h"
15
16 #undef strerror_r
17
18 #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
19
20 extern const char _string_syserrmsgs[] attribute_hidden;
21
22 #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
23
24 static const unsigned char estridx[] = {
25         0,                                                      /* success is always 0 */
26         EPERM,
27         ENOENT,
28         ESRCH,
29         EINTR,
30         EIO,
31         ENXIO,
32         E2BIG,
33         ENOEXEC,
34         EBADF,
35         ECHILD,
36         EAGAIN,
37         ENOMEM,
38         EACCES,
39         EFAULT,
40         ENOTBLK,
41         EBUSY,
42         EEXIST,
43         EXDEV,
44         ENODEV,
45         ENOTDIR,
46         EISDIR,
47         EINVAL,
48         ENFILE,
49         EMFILE,
50         ENOTTY,
51         ETXTBSY,
52         EFBIG,
53         ENOSPC,
54         ESPIPE,
55         EROFS,
56         EMLINK,
57         EPIPE,
58         EDOM,
59         ERANGE,
60         EDEADLK,
61         ENAMETOOLONG,
62         ENOLCK,
63         ENOSYS,
64         ENOTEMPTY,
65         ELOOP,
66         0,
67         ENOMSG,
68         EIDRM,
69         ECHRNG,
70         EL2NSYNC,
71         EL3HLT,
72         EL3RST,
73         ELNRNG,
74         EUNATCH,
75         ENOCSI,
76         EL2HLT,
77         EBADE,
78         EBADR,
79         EXFULL,
80         ENOANO,
81         EBADRQC,
82         EBADSLT,
83         0,
84         EBFONT,
85         ENOSTR,
86         ENODATA,
87         ETIME,
88         ENOSR,
89         ENONET,
90         ENOPKG,
91         EREMOTE,
92         ENOLINK,
93         EADV,
94         ESRMNT,
95         ECOMM,
96         EPROTO,
97         EMULTIHOP,
98         EDOTDOT,
99         EBADMSG,
100         EOVERFLOW,
101         ENOTUNIQ,
102         EBADFD,
103         EREMCHG,
104         ELIBACC,
105         ELIBBAD,
106         ELIBSCN,
107         ELIBMAX,
108         ELIBEXEC,
109         EILSEQ,
110         ERESTART,
111         ESTRPIPE,
112         EUSERS,
113         ENOTSOCK,
114         EDESTADDRREQ,
115         EMSGSIZE,
116         EPROTOTYPE,
117         ENOPROTOOPT,
118         EPROTONOSUPPORT,
119         ESOCKTNOSUPPORT,
120         EOPNOTSUPP,
121         EPFNOSUPPORT,
122         EAFNOSUPPORT,
123         EADDRINUSE,
124         EADDRNOTAVAIL,
125         ENETDOWN,
126         ENETUNREACH,
127         ENETRESET,
128         ECONNABORTED,
129         ECONNRESET,
130         ENOBUFS,
131         EISCONN,
132         ENOTCONN,
133         ESHUTDOWN,
134         ETOOMANYREFS,
135         ETIMEDOUT,
136         ECONNREFUSED,
137         EHOSTDOWN,
138         EHOSTUNREACH,
139         EALREADY,
140         EINPROGRESS,
141         ESTALE,
142         EUCLEAN,
143         ENOTNAM,
144         ENAVAIL,
145         EISNAM,
146         EREMOTEIO,
147 #if EDQUOT > 200                        /* mips has an outrageous value for this... */
148         0,
149 #else
150         EDQUOT,
151 #endif
152         ENOMEDIUM,
153         EMEDIUMTYPE,
154 #if EDEADLOCK != EDEADLK
155         EDEADLOCK,
156 #endif
157 };
158
159 #endif
160
161 int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
162 {
163     register char *s;
164     int i, retval;
165     char buf[_STRERROR_BUFSIZE];
166     static const char unknown[] = {
167                 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
168     };
169
170     retval = EINVAL;
171
172
173 #ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
174
175 #if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
176         /* Need to translate errno to string index. */
177         for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) {
178                 if (estridx[i] == errnum) {
179                         goto GOT_ESTRIDX;
180                 }
181         }
182         i = INT_MAX;    /* Failed, but may need to check mips special case. */
183 #if EDQUOT > 200        /* Deal with large EDQUOT value on mips */
184         if (errnum == EDQUOT)
185                 i = 122;
186 #endif
187  GOT_ESTRIDX:
188 #else
189         /* No errno to string index translation needed. */
190         i = errnum;
191 #endif
192
193     if (((unsigned int) i) < _SYS_NERR) {
194                 /* Trade time for space.  This function should rarely be called
195                  * so rather than keeping an array of pointers for the different
196                  * messages, just run through the buffer until we find the
197                  * correct string. */
198                 for (s = (char *) _string_syserrmsgs ; i ; ++s) {
199                         if (!*s) {
200                                 --i;
201                         }
202                 }
203                 if (*s) {               /* Make sure we have an actual message. */
204                         retval = 0;
205                         goto GOT_MESG;
206                 }
207     }
208
209 #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
210
211     s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
212     memcpy(s, unknown, sizeof(unknown));
213
214  GOT_MESG:
215     if (!strerrbuf) {           /* SUSv3  */
216                 buflen = 0;
217     }
218     i = strlen(s) + 1;
219     if (i > buflen) {
220                 i = buflen;
221                 retval = ERANGE;
222     }
223
224     if (i) {
225                 memcpy(strerrbuf, s, i);
226                 strerrbuf[i-1] = 0;     /* In case buf was too small. */
227     }
228
229     if (retval) {
230                 __set_errno(retval);
231     }
232
233     return retval;
234 }
235
236 #else  /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
237
238 int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
239 {
240     register char *s;
241     int i, retval;
242     char buf[_STRERROR_BUFSIZE];
243     static const char unknown[] = {
244                 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
245     };
246
247     s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
248     memcpy(s, unknown, sizeof(unknown));
249
250     if (!strerrbuf) {           /* SUSv3  */
251                 buflen = 0;
252     }
253
254     retval = EINVAL;
255
256         i = buf + sizeof(buf) - s;
257
258     if (i > buflen) {
259                 i = buflen;
260                 retval = ERANGE;
261     }
262
263     if (i) {
264                 memcpy(strerrbuf, s, i);
265                 strerrbuf[i-1] = 0;     /* In case buf was too small. */
266     }
267
268         __set_errno(retval);
269
270     return retval;
271 }
272
273 #endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
274 libc_hidden_def(__xpg_strerror_r)
275 #if defined __USE_XOPEN2K && !defined __USE_GNU
276 strong_alias(__xpg_strerror_r,strerror_r)
277 #endif