strerror.c revision 1.7 1 1.1 christos /* Extended support for using errno values.
2 1.1 christos Written by Fred Fish. fnf (at) cygnus.com
3 1.1 christos This file is in the public domain. --Per Bothner. */
4 1.1 christos
5 1.1 christos #include "config.h"
6 1.1 christos
7 1.1 christos #ifdef HAVE_SYS_ERRLIST
8 1.1 christos /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
9 1.1 christos might declare sys_errlist in a way that the compiler might consider
10 1.1 christos incompatible with our later declaration, perhaps by using const
11 1.1 christos attributes. So we hide the declaration in errno.h (if any) using a
12 1.1 christos macro. */
13 1.1 christos #define sys_nerr sys_nerr__
14 1.1 christos #define sys_errlist sys_errlist__
15 1.1 christos #endif
16 1.1 christos
17 1.1 christos #include "ansidecl.h"
18 1.1 christos #include "libiberty.h"
19 1.1 christos
20 1.1 christos #include <stdio.h>
21 1.1 christos #include <errno.h>
22 1.1 christos
23 1.1 christos #ifdef HAVE_SYS_ERRLIST
24 1.1 christos #undef sys_nerr
25 1.1 christos #undef sys_errlist
26 1.1 christos #endif
27 1.1 christos
28 1.1 christos /* Routines imported from standard C runtime libraries. */
29 1.1 christos
30 1.1 christos #ifdef HAVE_STDLIB_H
31 1.1 christos #include <stdlib.h>
32 1.1 christos #else
33 1.1 christos extern PTR malloc ();
34 1.1 christos #endif
35 1.1 christos
36 1.1 christos #ifdef HAVE_STRING_H
37 1.1 christos #include <string.h>
38 1.1 christos #else
39 1.1 christos extern PTR memset ();
40 1.1 christos #endif
41 1.1 christos
42 1.1 christos #ifndef MAX
43 1.1 christos # define MAX(a,b) ((a) > (b) ? (a) : (b))
44 1.1 christos #endif
45 1.1 christos
46 1.1 christos static void init_error_tables (void);
47 1.1 christos
48 1.1 christos /* Translation table for errno values. See intro(2) in most UNIX systems
49 1.1 christos Programmers Reference Manuals.
50 1.1 christos
51 1.1 christos Note that this table is generally only accessed when it is used at runtime
52 1.1 christos to initialize errno name and message tables that are indexed by errno
53 1.1 christos value.
54 1.1 christos
55 1.1 christos Not all of these errnos will exist on all systems. This table is the only
56 1.1 christos thing that should have to be updated as new error numbers are introduced.
57 1.1 christos It's sort of ugly, but at least its portable. */
58 1.1 christos
59 1.1 christos struct error_info
60 1.1 christos {
61 1.1 christos const int value; /* The numeric value from <errno.h> */
62 1.1 christos const char *const name; /* The equivalent symbolic value */
63 1.1 christos #ifndef HAVE_SYS_ERRLIST
64 1.1 christos const char *const msg; /* Short message about this value */
65 1.1 christos #endif
66 1.1 christos };
67 1.1 christos
68 1.1 christos #ifndef HAVE_SYS_ERRLIST
69 1.1 christos # define ENTRY(value, name, msg) {value, name, msg}
70 1.1 christos #else
71 1.1 christos # define ENTRY(value, name, msg) {value, name}
72 1.1 christos #endif
73 1.1 christos
74 1.1 christos static const struct error_info error_table[] =
75 1.1 christos {
76 1.1 christos #if defined (EPERM)
77 1.1 christos ENTRY(EPERM, "EPERM", "Not owner"),
78 1.1 christos #endif
79 1.1 christos #if defined (ENOENT)
80 1.1 christos ENTRY(ENOENT, "ENOENT", "No such file or directory"),
81 1.1 christos #endif
82 1.1 christos #if defined (ESRCH)
83 1.1 christos ENTRY(ESRCH, "ESRCH", "No such process"),
84 1.1 christos #endif
85 1.1 christos #if defined (EINTR)
86 1.1 christos ENTRY(EINTR, "EINTR", "Interrupted system call"),
87 1.1 christos #endif
88 1.1 christos #if defined (EIO)
89 1.1 christos ENTRY(EIO, "EIO", "I/O error"),
90 1.1 christos #endif
91 1.1 christos #if defined (ENXIO)
92 1.1 christos ENTRY(ENXIO, "ENXIO", "No such device or address"),
93 1.1 christos #endif
94 1.1 christos #if defined (E2BIG)
95 1.1 christos ENTRY(E2BIG, "E2BIG", "Arg list too long"),
96 1.1 christos #endif
97 1.1 christos #if defined (ENOEXEC)
98 1.1 christos ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
99 1.1 christos #endif
100 1.1 christos #if defined (EBADF)
101 1.1 christos ENTRY(EBADF, "EBADF", "Bad file number"),
102 1.1 christos #endif
103 1.1 christos #if defined (ECHILD)
104 1.1 christos ENTRY(ECHILD, "ECHILD", "No child processes"),
105 1.1 christos #endif
106 1.1 christos #if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
107 1.1 christos ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
108 1.1 christos #endif
109 1.1 christos #if defined (EAGAIN)
110 1.1 christos ENTRY(EAGAIN, "EAGAIN", "No more processes"),
111 1.1 christos #endif
112 1.1 christos #if defined (ENOMEM)
113 1.1 christos ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
114 1.1 christos #endif
115 1.1 christos #if defined (EACCES)
116 1.1 christos ENTRY(EACCES, "EACCES", "Permission denied"),
117 1.1 christos #endif
118 1.1 christos #if defined (EFAULT)
119 1.1 christos ENTRY(EFAULT, "EFAULT", "Bad address"),
120 1.1 christos #endif
121 1.1 christos #if defined (ENOTBLK)
122 1.1 christos ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
123 1.1 christos #endif
124 1.1 christos #if defined (EBUSY)
125 1.1 christos ENTRY(EBUSY, "EBUSY", "Device busy"),
126 1.1 christos #endif
127 1.1 christos #if defined (EEXIST)
128 1.1 christos ENTRY(EEXIST, "EEXIST", "File exists"),
129 1.1 christos #endif
130 1.1 christos #if defined (EXDEV)
131 1.1 christos ENTRY(EXDEV, "EXDEV", "Cross-device link"),
132 1.1 christos #endif
133 1.1 christos #if defined (ENODEV)
134 1.1 christos ENTRY(ENODEV, "ENODEV", "No such device"),
135 1.1 christos #endif
136 1.1 christos #if defined (ENOTDIR)
137 1.1 christos ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
138 1.1 christos #endif
139 1.1 christos #if defined (EISDIR)
140 1.1 christos ENTRY(EISDIR, "EISDIR", "Is a directory"),
141 1.1 christos #endif
142 1.1 christos #if defined (EINVAL)
143 1.1 christos ENTRY(EINVAL, "EINVAL", "Invalid argument"),
144 1.1 christos #endif
145 1.1 christos #if defined (ENFILE)
146 1.1 christos ENTRY(ENFILE, "ENFILE", "File table overflow"),
147 1.1 christos #endif
148 1.1 christos #if defined (EMFILE)
149 1.1 christos ENTRY(EMFILE, "EMFILE", "Too many open files"),
150 1.1 christos #endif
151 1.1 christos #if defined (ENOTTY)
152 1.1 christos ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
153 1.1 christos #endif
154 1.1 christos #if defined (ETXTBSY)
155 1.1 christos ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
156 1.1 christos #endif
157 1.1 christos #if defined (EFBIG)
158 1.1 christos ENTRY(EFBIG, "EFBIG", "File too large"),
159 1.1 christos #endif
160 1.1 christos #if defined (ENOSPC)
161 1.1 christos ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
162 1.1 christos #endif
163 1.1 christos #if defined (ESPIPE)
164 1.1 christos ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
165 1.1 christos #endif
166 1.1 christos #if defined (EROFS)
167 1.1 christos ENTRY(EROFS, "EROFS", "Read-only file system"),
168 1.1 christos #endif
169 1.1 christos #if defined (EMLINK)
170 1.1 christos ENTRY(EMLINK, "EMLINK", "Too many links"),
171 1.1 christos #endif
172 1.1 christos #if defined (EPIPE)
173 1.1 christos ENTRY(EPIPE, "EPIPE", "Broken pipe"),
174 1.1 christos #endif
175 1.1 christos #if defined (EDOM)
176 1.1 christos ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
177 1.1 christos #endif
178 1.1 christos #if defined (ERANGE)
179 1.1 christos ENTRY(ERANGE, "ERANGE", "Math result not representable"),
180 1.1 christos #endif
181 1.1 christos #if defined (ENOMSG)
182 1.1 christos ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
183 1.1 christos #endif
184 1.1 christos #if defined (EIDRM)
185 1.1 christos ENTRY(EIDRM, "EIDRM", "Identifier removed"),
186 1.1 christos #endif
187 1.1 christos #if defined (ECHRNG)
188 1.1 christos ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
189 1.1 christos #endif
190 1.1 christos #if defined (EL2NSYNC)
191 1.1 christos ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
192 1.1 christos #endif
193 1.1 christos #if defined (EL3HLT)
194 1.1 christos ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
195 1.1 christos #endif
196 1.1 christos #if defined (EL3RST)
197 1.1 christos ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
198 1.1 christos #endif
199 1.1 christos #if defined (ELNRNG)
200 1.1 christos ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
201 1.1 christos #endif
202 1.1 christos #if defined (EUNATCH)
203 1.1 christos ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
204 1.1 christos #endif
205 1.1 christos #if defined (ENOCSI)
206 1.1 christos ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
207 1.1 christos #endif
208 1.1 christos #if defined (EL2HLT)
209 1.1 christos ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
210 1.1 christos #endif
211 1.1 christos #if defined (EDEADLK)
212 1.1 christos ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
213 1.1 christos #endif
214 1.1 christos #if defined (ENOLCK)
215 1.1 christos ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
216 1.1 christos #endif
217 1.1 christos #if defined (EBADE)
218 1.1 christos ENTRY(EBADE, "EBADE", "Invalid exchange"),
219 1.1 christos #endif
220 1.1 christos #if defined (EBADR)
221 1.1 christos ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
222 1.1 christos #endif
223 1.1 christos #if defined (EXFULL)
224 1.1 christos ENTRY(EXFULL, "EXFULL", "Exchange full"),
225 1.1 christos #endif
226 1.1 christos #if defined (ENOANO)
227 1.1 christos ENTRY(ENOANO, "ENOANO", "No anode"),
228 1.1 christos #endif
229 1.1 christos #if defined (EBADRQC)
230 1.1 christos ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
231 1.1 christos #endif
232 1.1 christos #if defined (EBADSLT)
233 1.1 christos ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
234 1.1 christos #endif
235 1.1 christos #if defined (EDEADLOCK)
236 1.1 christos ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
237 1.1 christos #endif
238 1.1 christos #if defined (EBFONT)
239 1.1 christos ENTRY(EBFONT, "EBFONT", "Bad font file format"),
240 1.1 christos #endif
241 1.1 christos #if defined (ENOSTR)
242 1.1 christos ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
243 1.1 christos #endif
244 1.1 christos #if defined (ENODATA)
245 1.1 christos ENTRY(ENODATA, "ENODATA", "No data available"),
246 1.1 christos #endif
247 1.1 christos #if defined (ETIME)
248 1.1 christos ENTRY(ETIME, "ETIME", "Timer expired"),
249 1.1 christos #endif
250 1.1 christos #if defined (ENOSR)
251 1.1 christos ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
252 1.1 christos #endif
253 1.1 christos #if defined (ENONET)
254 1.1 christos ENTRY(ENONET, "ENONET", "Machine is not on the network"),
255 1.1 christos #endif
256 1.1 christos #if defined (ENOPKG)
257 1.1 christos ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
258 1.1 christos #endif
259 1.1 christos #if defined (EREMOTE)
260 1.1 christos ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
261 1.1 christos #endif
262 1.1 christos #if defined (ENOLINK)
263 1.1 christos ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
264 1.1 christos #endif
265 1.1 christos #if defined (EADV)
266 1.1 christos ENTRY(EADV, "EADV", "Advertise error"),
267 1.1 christos #endif
268 1.1 christos #if defined (ESRMNT)
269 1.1 christos ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
270 1.1 christos #endif
271 1.1 christos #if defined (ECOMM)
272 1.1 christos ENTRY(ECOMM, "ECOMM", "Communication error on send"),
273 1.1 christos #endif
274 1.1 christos #if defined (EPROTO)
275 1.1 christos ENTRY(EPROTO, "EPROTO", "Protocol error"),
276 1.1 christos #endif
277 1.1 christos #if defined (EMULTIHOP)
278 1.1 christos ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
279 1.1 christos #endif
280 1.1 christos #if defined (EDOTDOT)
281 1.1 christos ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
282 1.1 christos #endif
283 1.1 christos #if defined (EBADMSG)
284 1.1 christos ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
285 1.1 christos #endif
286 1.1 christos #if defined (ENAMETOOLONG)
287 1.1 christos ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
288 1.1 christos #endif
289 1.1 christos #if defined (EOVERFLOW)
290 1.1 christos ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
291 1.1 christos #endif
292 1.1 christos #if defined (ENOTUNIQ)
293 1.1 christos ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
294 1.1 christos #endif
295 1.1 christos #if defined (EBADFD)
296 1.1 christos ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
297 1.1 christos #endif
298 1.1 christos #if defined (EREMCHG)
299 1.1 christos ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
300 1.1 christos #endif
301 1.1 christos #if defined (ELIBACC)
302 1.7 christos ENTRY(ELIBACC, "ELIBACC", "Cannot access a needed shared library"),
303 1.1 christos #endif
304 1.1 christos #if defined (ELIBBAD)
305 1.1 christos ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
306 1.1 christos #endif
307 1.1 christos #if defined (ELIBSCN)
308 1.1 christos ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
309 1.1 christos #endif
310 1.1 christos #if defined (ELIBMAX)
311 1.1 christos ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
312 1.1 christos #endif
313 1.1 christos #if defined (ELIBEXEC)
314 1.1 christos ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
315 1.1 christos #endif
316 1.1 christos #if defined (EILSEQ)
317 1.1 christos ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
318 1.1 christos #endif
319 1.1 christos #if defined (ENOSYS)
320 1.1 christos ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
321 1.1 christos #endif
322 1.1 christos #if defined (ELOOP)
323 1.1 christos ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
324 1.1 christos #endif
325 1.1 christos #if defined (ERESTART)
326 1.1 christos ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
327 1.1 christos #endif
328 1.1 christos #if defined (ESTRPIPE)
329 1.1 christos ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
330 1.1 christos #endif
331 1.1 christos #if defined (ENOTEMPTY)
332 1.1 christos ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
333 1.1 christos #endif
334 1.1 christos #if defined (EUSERS)
335 1.1 christos ENTRY(EUSERS, "EUSERS", "Too many users"),
336 1.1 christos #endif
337 1.1 christos #if defined (ENOTSOCK)
338 1.1 christos ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
339 1.1 christos #endif
340 1.1 christos #if defined (EDESTADDRREQ)
341 1.1 christos ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
342 1.1 christos #endif
343 1.1 christos #if defined (EMSGSIZE)
344 1.1 christos ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
345 1.1 christos #endif
346 1.1 christos #if defined (EPROTOTYPE)
347 1.1 christos ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
348 1.1 christos #endif
349 1.1 christos #if defined (ENOPROTOOPT)
350 1.6 christos ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
351 1.1 christos #endif
352 1.1 christos #if defined (EPROTONOSUPPORT)
353 1.1 christos ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
354 1.1 christos #endif
355 1.1 christos #if defined (ESOCKTNOSUPPORT)
356 1.1 christos ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
357 1.1 christos #endif
358 1.1 christos #if defined (EOPNOTSUPP)
359 1.1 christos ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
360 1.1 christos #endif
361 1.1 christos #if defined (EPFNOSUPPORT)
362 1.1 christos ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
363 1.1 christos #endif
364 1.1 christos #if defined (EAFNOSUPPORT)
365 1.1 christos ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
366 1.1 christos #endif
367 1.1 christos #if defined (EADDRINUSE)
368 1.1 christos ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
369 1.1 christos #endif
370 1.1 christos #if defined (EADDRNOTAVAIL)
371 1.1 christos ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
372 1.1 christos #endif
373 1.1 christos #if defined (ENETDOWN)
374 1.1 christos ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
375 1.1 christos #endif
376 1.1 christos #if defined (ENETUNREACH)
377 1.1 christos ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
378 1.1 christos #endif
379 1.1 christos #if defined (ENETRESET)
380 1.1 christos ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
381 1.1 christos #endif
382 1.1 christos #if defined (ECONNABORTED)
383 1.1 christos ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
384 1.1 christos #endif
385 1.1 christos #if defined (ECONNRESET)
386 1.1 christos ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
387 1.1 christos #endif
388 1.1 christos #if defined (ENOBUFS)
389 1.1 christos ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
390 1.1 christos #endif
391 1.1 christos #if defined (EISCONN)
392 1.1 christos ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
393 1.1 christos #endif
394 1.1 christos #if defined (ENOTCONN)
395 1.1 christos ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
396 1.1 christos #endif
397 1.1 christos #if defined (ESHUTDOWN)
398 1.1 christos ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
399 1.1 christos #endif
400 1.1 christos #if defined (ETOOMANYREFS)
401 1.1 christos ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
402 1.1 christos #endif
403 1.1 christos #if defined (ETIMEDOUT)
404 1.1 christos ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
405 1.1 christos #endif
406 1.1 christos #if defined (ECONNREFUSED)
407 1.1 christos ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
408 1.1 christos #endif
409 1.1 christos #if defined (EHOSTDOWN)
410 1.1 christos ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
411 1.1 christos #endif
412 1.1 christos #if defined (EHOSTUNREACH)
413 1.1 christos ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
414 1.1 christos #endif
415 1.1 christos #if defined (EALREADY)
416 1.1 christos ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
417 1.1 christos #endif
418 1.1 christos #if defined (EINPROGRESS)
419 1.1 christos ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
420 1.1 christos #endif
421 1.1 christos #if defined (ESTALE)
422 1.1 christos ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
423 1.1 christos #endif
424 1.1 christos #if defined (EUCLEAN)
425 1.1 christos ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
426 1.1 christos #endif
427 1.1 christos #if defined (ENOTNAM)
428 1.1 christos ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
429 1.1 christos #endif
430 1.1 christos #if defined (ENAVAIL)
431 1.1 christos ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
432 1.1 christos #endif
433 1.1 christos #if defined (EISNAM)
434 1.1 christos ENTRY(EISNAM, "EISNAM", "Is a named type file"),
435 1.1 christos #endif
436 1.1 christos #if defined (EREMOTEIO)
437 1.1 christos ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
438 1.1 christos #endif
439 1.1 christos ENTRY(0, NULL, NULL)
440 1.1 christos };
441 1.1 christos
442 1.1 christos #ifdef EVMSERR
443 1.1 christos /* This is not in the table, because the numeric value of EVMSERR (32767)
444 1.1 christos lies outside the range of sys_errlist[]. */
445 1.1 christos static struct { int value; const char *name, *msg; }
446 1.1 christos evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" };
447 1.1 christos #endif
448 1.1 christos
449 1.1 christos /* Translation table allocated and initialized at runtime. Indexed by the
450 1.1 christos errno value to find the equivalent symbolic value. */
451 1.1 christos
452 1.1 christos static const char **error_names;
453 1.1 christos static int num_error_names = 0;
454 1.1 christos
455 1.1 christos /* Translation table allocated and initialized at runtime, if it does not
456 1.1 christos already exist in the host environment. Indexed by the errno value to find
457 1.1 christos the descriptive string.
458 1.1 christos
459 1.1 christos We don't export it for use in other modules because even though it has the
460 1.1 christos same name, it differs from other implementations in that it is dynamically
461 1.1 christos initialized rather than statically initialized. */
462 1.1 christos
463 1.1 christos #ifndef HAVE_SYS_ERRLIST
464 1.1 christos
465 1.1 christos #define sys_nerr sys_nerr__
466 1.1 christos #define sys_errlist sys_errlist__
467 1.1 christos static int sys_nerr;
468 1.1 christos static const char **sys_errlist;
469 1.1 christos
470 1.1 christos #else
471 1.1 christos
472 1.3 christos
473 1.3 christos #ifndef sys_nerr
474 1.1 christos extern int sys_nerr;
475 1.3 christos #endif
476 1.3 christos #ifndef sys_errlist
477 1.1 christos extern char *sys_errlist[];
478 1.3 christos #endif
479 1.1 christos
480 1.1 christos #endif
481 1.1 christos
482 1.1 christos /*
483 1.1 christos
484 1.1 christos NAME
485 1.1 christos
486 1.1 christos init_error_tables -- initialize the name and message tables
487 1.1 christos
488 1.1 christos SYNOPSIS
489 1.1 christos
490 1.1 christos static void init_error_tables ();
491 1.1 christos
492 1.1 christos DESCRIPTION
493 1.1 christos
494 1.1 christos Using the error_table, which is initialized at compile time, generate
495 1.1 christos the error_names and the sys_errlist (if needed) tables, which are
496 1.1 christos indexed at runtime by a specific errno value.
497 1.1 christos
498 1.1 christos BUGS
499 1.1 christos
500 1.1 christos The initialization of the tables may fail under low memory conditions,
501 1.1 christos in which case we don't do anything particularly useful, but we don't
502 1.1 christos bomb either. Who knows, it might succeed at a later point if we free
503 1.1 christos some memory in the meantime. In any case, the other routines know
504 1.1 christos how to deal with lack of a table after trying to initialize it. This
505 1.1 christos may or may not be considered to be a bug, that we don't specifically
506 1.1 christos warn about this particular failure mode.
507 1.1 christos
508 1.1 christos */
509 1.1 christos
510 1.1 christos static void
511 1.1 christos init_error_tables (void)
512 1.1 christos {
513 1.1 christos const struct error_info *eip;
514 1.1 christos int nbytes;
515 1.1 christos
516 1.1 christos /* If we haven't already scanned the error_table once to find the maximum
517 1.1 christos errno value, then go find it now. */
518 1.1 christos
519 1.1 christos if (num_error_names == 0)
520 1.1 christos {
521 1.1 christos for (eip = error_table; eip -> name != NULL; eip++)
522 1.1 christos {
523 1.1 christos if (eip -> value >= num_error_names)
524 1.1 christos {
525 1.1 christos num_error_names = eip -> value + 1;
526 1.1 christos }
527 1.1 christos }
528 1.1 christos }
529 1.1 christos
530 1.1 christos /* Now attempt to allocate the error_names table, zero it out, and then
531 1.1 christos initialize it from the statically initialized error_table. */
532 1.1 christos
533 1.1 christos if (error_names == NULL)
534 1.1 christos {
535 1.1 christos nbytes = num_error_names * sizeof (char *);
536 1.1 christos if ((error_names = (const char **) malloc (nbytes)) != NULL)
537 1.1 christos {
538 1.1 christos memset (error_names, 0, nbytes);
539 1.1 christos for (eip = error_table; eip -> name != NULL; eip++)
540 1.1 christos {
541 1.1 christos error_names[eip -> value] = eip -> name;
542 1.1 christos }
543 1.1 christos }
544 1.1 christos }
545 1.1 christos
546 1.1 christos #ifndef HAVE_SYS_ERRLIST
547 1.1 christos
548 1.1 christos /* Now attempt to allocate the sys_errlist table, zero it out, and then
549 1.1 christos initialize it from the statically initialized error_table. */
550 1.1 christos
551 1.1 christos if (sys_errlist == NULL)
552 1.1 christos {
553 1.1 christos nbytes = num_error_names * sizeof (char *);
554 1.1 christos if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
555 1.1 christos {
556 1.1 christos memset (sys_errlist, 0, nbytes);
557 1.1 christos sys_nerr = num_error_names;
558 1.1 christos for (eip = error_table; eip -> name != NULL; eip++)
559 1.1 christos {
560 1.1 christos sys_errlist[eip -> value] = eip -> msg;
561 1.1 christos }
562 1.1 christos }
563 1.1 christos }
564 1.1 christos
565 1.1 christos #endif
566 1.1 christos
567 1.1 christos }
568 1.1 christos
569 1.1 christos /*
570 1.1 christos
571 1.1 christos
572 1.1 christos @deftypefn Extension int errno_max (void)
573 1.1 christos
574 1.1 christos Returns the maximum @code{errno} value for which a corresponding
575 1.1 christos symbolic name or message is available. Note that in the case where we
576 1.1 christos use the @code{sys_errlist} supplied by the system, it is possible for
577 1.1 christos there to be more symbolic names than messages, or vice versa. In
578 1.1 christos fact, the manual page for @code{perror(3C)} explicitly warns that one
579 1.1 christos should check the size of the table (@code{sys_nerr}) before indexing
580 1.1 christos it, since new error codes may be added to the system before they are
581 1.1 christos added to the table. Thus @code{sys_nerr} might be smaller than value
582 1.1 christos implied by the largest @code{errno} value defined in @code{<errno.h>}.
583 1.1 christos
584 1.1 christos We return the maximum value that can be used to obtain a meaningful
585 1.1 christos symbolic name or message.
586 1.1 christos
587 1.1 christos @end deftypefn
588 1.1 christos
589 1.1 christos */
590 1.1 christos
591 1.1 christos int
592 1.1 christos errno_max (void)
593 1.1 christos {
594 1.1 christos int maxsize;
595 1.1 christos
596 1.1 christos if (error_names == NULL)
597 1.1 christos {
598 1.1 christos init_error_tables ();
599 1.1 christos }
600 1.1 christos maxsize = MAX (sys_nerr, num_error_names);
601 1.1 christos return (maxsize - 1);
602 1.1 christos }
603 1.1 christos
604 1.1 christos #ifndef HAVE_STRERROR
605 1.1 christos
606 1.1 christos /*
607 1.1 christos
608 1.1 christos @deftypefn Supplemental char* strerror (int @var{errnoval})
609 1.1 christos
610 1.1 christos Maps an @code{errno} number to an error message string, the contents
611 1.1 christos of which are implementation defined. On systems which have the
612 1.1 christos external variables @code{sys_nerr} and @code{sys_errlist}, these
613 1.1 christos strings will be the same as the ones used by @code{perror}.
614 1.1 christos
615 1.1 christos If the supplied error number is within the valid range of indices for
616 1.1 christos the @code{sys_errlist}, but no message is available for the particular
617 1.1 christos error number, then returns the string @samp{Error @var{num}}, where
618 1.1 christos @var{num} is the error number.
619 1.1 christos
620 1.1 christos If the supplied error number is not a valid index into
621 1.1 christos @code{sys_errlist}, returns @code{NULL}.
622 1.1 christos
623 1.1 christos The returned string is only guaranteed to be valid only until the
624 1.1 christos next call to @code{strerror}.
625 1.1 christos
626 1.1 christos @end deftypefn
627 1.1 christos
628 1.1 christos */
629 1.1 christos
630 1.1 christos char *
631 1.1 christos strerror (int errnoval)
632 1.1 christos {
633 1.1 christos const char *msg;
634 1.1 christos static char buf[32];
635 1.1 christos
636 1.1 christos #ifndef HAVE_SYS_ERRLIST
637 1.1 christos
638 1.1 christos if (error_names == NULL)
639 1.1 christos {
640 1.1 christos init_error_tables ();
641 1.1 christos }
642 1.1 christos
643 1.1 christos #endif
644 1.1 christos
645 1.1 christos if ((errnoval < 0) || (errnoval >= sys_nerr))
646 1.1 christos {
647 1.1 christos #ifdef EVMSERR
648 1.1 christos if (errnoval == evmserr.value)
649 1.1 christos msg = evmserr.msg;
650 1.1 christos else
651 1.1 christos #endif
652 1.1 christos /* Out of range, just return NULL */
653 1.1 christos msg = NULL;
654 1.1 christos }
655 1.1 christos else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
656 1.1 christos {
657 1.1 christos /* In range, but no sys_errlist or no entry at this index. */
658 1.1 christos sprintf (buf, "Error %d", errnoval);
659 1.1 christos msg = buf;
660 1.1 christos }
661 1.1 christos else
662 1.1 christos {
663 1.1 christos /* In range, and a valid message. Just return the message. */
664 1.1 christos msg = (char *) sys_errlist[errnoval];
665 1.1 christos }
666 1.1 christos
667 1.1 christos return (msg);
668 1.1 christos }
669 1.1 christos
670 1.1 christos #endif /* ! HAVE_STRERROR */
671 1.1 christos
672 1.1 christos
673 1.1 christos /*
674 1.1 christos
675 1.1 christos @deftypefn Replacement {const char*} strerrno (int @var{errnum})
676 1.1 christos
677 1.1 christos Given an error number returned from a system call (typically returned
678 1.1 christos in @code{errno}), returns a pointer to a string containing the
679 1.1 christos symbolic name of that error number, as found in @code{<errno.h>}.
680 1.1 christos
681 1.1 christos If the supplied error number is within the valid range of indices for
682 1.1 christos symbolic names, but no name is available for the particular error
683 1.1 christos number, then returns the string @samp{Error @var{num}}, where @var{num}
684 1.1 christos is the error number.
685 1.1 christos
686 1.1 christos If the supplied error number is not within the range of valid
687 1.1 christos indices, then returns @code{NULL}.
688 1.1 christos
689 1.1 christos The contents of the location pointed to are only guaranteed to be
690 1.1 christos valid until the next call to @code{strerrno}.
691 1.1 christos
692 1.1 christos @end deftypefn
693 1.1 christos
694 1.1 christos */
695 1.1 christos
696 1.1 christos const char *
697 1.1 christos strerrno (int errnoval)
698 1.1 christos {
699 1.1 christos const char *name;
700 1.1 christos static char buf[32];
701 1.1 christos
702 1.1 christos if (error_names == NULL)
703 1.1 christos {
704 1.1 christos init_error_tables ();
705 1.1 christos }
706 1.1 christos
707 1.1 christos if ((errnoval < 0) || (errnoval >= num_error_names))
708 1.1 christos {
709 1.1 christos #ifdef EVMSERR
710 1.1 christos if (errnoval == evmserr.value)
711 1.1 christos name = evmserr.name;
712 1.1 christos else
713 1.1 christos #endif
714 1.1 christos /* Out of range, just return NULL */
715 1.1 christos name = NULL;
716 1.1 christos }
717 1.1 christos else if ((error_names == NULL) || (error_names[errnoval] == NULL))
718 1.1 christos {
719 1.1 christos /* In range, but no error_names or no entry at this index. */
720 1.1 christos sprintf (buf, "Error %d", errnoval);
721 1.1 christos name = (const char *) buf;
722 1.1 christos }
723 1.1 christos else
724 1.1 christos {
725 1.1 christos /* In range, and a valid name. Just return the name. */
726 1.1 christos name = error_names[errnoval];
727 1.1 christos }
728 1.1 christos
729 1.1 christos return (name);
730 1.1 christos }
731 1.1 christos
732 1.1 christos /*
733 1.1 christos
734 1.1 christos @deftypefn Extension int strtoerrno (const char *@var{name})
735 1.1 christos
736 1.1 christos Given the symbolic name of a error number (e.g., @code{EACCES}), map it
737 1.1 christos to an errno value. If no translation is found, returns 0.
738 1.1 christos
739 1.1 christos @end deftypefn
740 1.1 christos
741 1.1 christos */
742 1.1 christos
743 1.1 christos int
744 1.1 christos strtoerrno (const char *name)
745 1.1 christos {
746 1.1 christos int errnoval = 0;
747 1.1 christos
748 1.1 christos if (name != NULL)
749 1.1 christos {
750 1.1 christos if (error_names == NULL)
751 1.1 christos {
752 1.1 christos init_error_tables ();
753 1.1 christos }
754 1.1 christos for (errnoval = 0; errnoval < num_error_names; errnoval++)
755 1.1 christos {
756 1.1 christos if ((error_names[errnoval] != NULL) &&
757 1.1 christos (strcmp (name, error_names[errnoval]) == 0))
758 1.1 christos {
759 1.1 christos break;
760 1.1 christos }
761 1.1 christos }
762 1.1 christos if (errnoval == num_error_names)
763 1.1 christos {
764 1.1 christos #ifdef EVMSERR
765 1.1 christos if (strcmp (name, evmserr.name) == 0)
766 1.1 christos errnoval = evmserr.value;
767 1.1 christos else
768 1.1 christos #endif
769 1.1 christos errnoval = 0;
770 1.1 christos }
771 1.1 christos }
772 1.1 christos return (errnoval);
773 1.1 christos }
774 1.1 christos
775 1.1 christos
776 1.1 christos /* A simple little main that does nothing but print all the errno translations
777 1.1 christos if MAIN is defined and this file is compiled and linked. */
778 1.1 christos
779 1.1 christos #ifdef MAIN
780 1.1 christos
781 1.1 christos #include <stdio.h>
782 1.1 christos
783 1.1 christos int
784 1.1 christos main (void)
785 1.1 christos {
786 1.1 christos int errn;
787 1.1 christos int errnmax;
788 1.1 christos const char *name;
789 1.1 christos const char *msg;
790 1.1 christos char *strerror ();
791 1.1 christos
792 1.1 christos errnmax = errno_max ();
793 1.1 christos printf ("%d entries in names table.\n", num_error_names);
794 1.1 christos printf ("%d entries in messages table.\n", sys_nerr);
795 1.1 christos printf ("%d is max useful index.\n", errnmax);
796 1.1 christos
797 1.1 christos /* Keep printing values until we get to the end of *both* tables, not
798 1.1 christos *either* table. Note that knowing the maximum useful index does *not*
799 1.1 christos relieve us of the responsibility of testing the return pointer for
800 1.1 christos NULL. */
801 1.1 christos
802 1.1 christos for (errn = 0; errn <= errnmax; errn++)
803 1.1 christos {
804 1.1 christos name = strerrno (errn);
805 1.1 christos name = (name == NULL) ? "<NULL>" : name;
806 1.1 christos msg = strerror (errn);
807 1.1 christos msg = (msg == NULL) ? "<NULL>" : msg;
808 1.1 christos printf ("%-4d%-18s%s\n", errn, name, msg);
809 1.1 christos }
810 1.1 christos
811 1.1 christos return 0;
812 1.1 christos }
813 1.1 christos
814 1.1 christos #endif
815