OSDN Git Service

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