1 /* Extended support for using errno values.
2 Written by Fred Fish. fnf@cygnus.com
3 This file is in the public domain. --Per Bothner. */
10 #ifdef HAVE_SYS_ERRLIST
11 /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
12 might declare sys_errlist in a way that the compiler might consider
13 incompatible with our later declaration, perhaps by using const
14 attributes. So we hide the declaration in errno.h (if any) using a
16 #define sys_errlist sys_errlist__
22 #ifdef HAVE_SYS_ERRLIST
26 /* Routines imported from standard C runtime libraries. */
41 # define MAX(a,b) ((a) > (b) ? (a) : (b))
44 static void init_error_tables
PARAMS ((void));
46 /* Translation table for errno values. See intro(2) in most UNIX systems
47 Programmers Reference Manuals.
49 Note that this table is generally only accessed when it is used at runtime
50 to initialize errno name and message tables that are indexed by errno
53 Not all of these errnos will exist on all systems. This table is the only
54 thing that should have to be updated as new error numbers are introduced.
55 It's sort of ugly, but at least its portable. */
59 int value
; /* The numeric value from <errno.h> */
60 const char *name
; /* The equivalent symbolic value */
61 #ifndef HAVE_SYS_ERRLIST
62 const char *msg
; /* Short message about this value */
66 #ifndef HAVE_SYS_ERRLIST
67 # define ENTRY(value, name, msg) {value, name, msg}
69 # define ENTRY(value, name, msg) {value, name}
72 static const struct error_info error_table
[] =
75 ENTRY(EPERM
, "EPERM", "Not owner"),
78 ENTRY(ENOENT
, "ENOENT", "No such file or directory"),
81 ENTRY(ESRCH
, "ESRCH", "No such process"),
84 ENTRY(EINTR
, "EINTR", "Interrupted system call"),
87 ENTRY(EIO
, "EIO", "I/O error"),
90 ENTRY(ENXIO
, "ENXIO", "No such device or address"),
93 ENTRY(E2BIG
, "E2BIG", "Arg list too long"),
96 ENTRY(ENOEXEC
, "ENOEXEC", "Exec format error"),
99 ENTRY(EBADF
, "EBADF", "Bad file number"),
102 ENTRY(ECHILD
, "ECHILD", "No child processes"),
104 #if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
105 ENTRY(EWOULDBLOCK
, "EWOULDBLOCK", "Operation would block"),
108 ENTRY(EAGAIN
, "EAGAIN", "No more processes"),
111 ENTRY(ENOMEM
, "ENOMEM", "Not enough space"),
114 ENTRY(EACCES
, "EACCES", "Permission denied"),
117 ENTRY(EFAULT
, "EFAULT", "Bad address"),
119 #if defined (ENOTBLK)
120 ENTRY(ENOTBLK
, "ENOTBLK", "Block device required"),
123 ENTRY(EBUSY
, "EBUSY", "Device busy"),
126 ENTRY(EEXIST
, "EEXIST", "File exists"),
129 ENTRY(EXDEV
, "EXDEV", "Cross-device link"),
132 ENTRY(ENODEV
, "ENODEV", "No such device"),
134 #if defined (ENOTDIR)
135 ENTRY(ENOTDIR
, "ENOTDIR", "Not a directory"),
138 ENTRY(EISDIR
, "EISDIR", "Is a directory"),
141 ENTRY(EINVAL
, "EINVAL", "Invalid argument"),
144 ENTRY(ENFILE
, "ENFILE", "File table overflow"),
147 ENTRY(EMFILE
, "EMFILE", "Too many open files"),
150 ENTRY(ENOTTY
, "ENOTTY", "Not a typewriter"),
152 #if defined (ETXTBSY)
153 ENTRY(ETXTBSY
, "ETXTBSY", "Text file busy"),
156 ENTRY(EFBIG
, "EFBIG", "File too large"),
159 ENTRY(ENOSPC
, "ENOSPC", "No space left on device"),
162 ENTRY(ESPIPE
, "ESPIPE", "Illegal seek"),
165 ENTRY(EROFS
, "EROFS", "Read-only file system"),
168 ENTRY(EMLINK
, "EMLINK", "Too many links"),
171 ENTRY(EPIPE
, "EPIPE", "Broken pipe"),
174 ENTRY(EDOM
, "EDOM", "Math argument out of domain of func"),
177 ENTRY(ERANGE
, "ERANGE", "Math result not representable"),
180 ENTRY(ENOMSG
, "ENOMSG", "No message of desired type"),
183 ENTRY(EIDRM
, "EIDRM", "Identifier removed"),
186 ENTRY(ECHRNG
, "ECHRNG", "Channel number out of range"),
188 #if defined (EL2NSYNC)
189 ENTRY(EL2NSYNC
, "EL2NSYNC", "Level 2 not synchronized"),
192 ENTRY(EL3HLT
, "EL3HLT", "Level 3 halted"),
195 ENTRY(EL3RST
, "EL3RST", "Level 3 reset"),
198 ENTRY(ELNRNG
, "ELNRNG", "Link number out of range"),
200 #if defined (EUNATCH)
201 ENTRY(EUNATCH
, "EUNATCH", "Protocol driver not attached"),
204 ENTRY(ENOCSI
, "ENOCSI", "No CSI structure available"),
207 ENTRY(EL2HLT
, "EL2HLT", "Level 2 halted"),
209 #if defined (EDEADLK)
210 ENTRY(EDEADLK
, "EDEADLK", "Deadlock condition"),
213 ENTRY(ENOLCK
, "ENOLCK", "No record locks available"),
216 ENTRY(EBADE
, "EBADE", "Invalid exchange"),
219 ENTRY(EBADR
, "EBADR", "Invalid request descriptor"),
222 ENTRY(EXFULL
, "EXFULL", "Exchange full"),
225 ENTRY(ENOANO
, "ENOANO", "No anode"),
227 #if defined (EBADRQC)
228 ENTRY(EBADRQC
, "EBADRQC", "Invalid request code"),
230 #if defined (EBADSLT)
231 ENTRY(EBADSLT
, "EBADSLT", "Invalid slot"),
233 #if defined (EDEADLOCK)
234 ENTRY(EDEADLOCK
, "EDEADLOCK", "File locking deadlock error"),
237 ENTRY(EBFONT
, "EBFONT", "Bad font file format"),
240 ENTRY(ENOSTR
, "ENOSTR", "Device not a stream"),
242 #if defined (ENODATA)
243 ENTRY(ENODATA
, "ENODATA", "No data available"),
246 ENTRY(ETIME
, "ETIME", "Timer expired"),
249 ENTRY(ENOSR
, "ENOSR", "Out of streams resources"),
252 ENTRY(ENONET
, "ENONET", "Machine is not on the network"),
255 ENTRY(ENOPKG
, "ENOPKG", "Package not installed"),
257 #if defined (EREMOTE)
258 ENTRY(EREMOTE
, "EREMOTE", "Object is remote"),
260 #if defined (ENOLINK)
261 ENTRY(ENOLINK
, "ENOLINK", "Link has been severed"),
264 ENTRY(EADV
, "EADV", "Advertise error"),
267 ENTRY(ESRMNT
, "ESRMNT", "Srmount error"),
270 ENTRY(ECOMM
, "ECOMM", "Communication error on send"),
273 ENTRY(EPROTO
, "EPROTO", "Protocol error"),
275 #if defined (EMULTIHOP)
276 ENTRY(EMULTIHOP
, "EMULTIHOP", "Multihop attempted"),
278 #if defined (EDOTDOT)
279 ENTRY(EDOTDOT
, "EDOTDOT", "RFS specific error"),
281 #if defined (EBADMSG)
282 ENTRY(EBADMSG
, "EBADMSG", "Not a data message"),
284 #if defined (ENAMETOOLONG)
285 ENTRY(ENAMETOOLONG
, "ENAMETOOLONG", "File name too long"),
287 #if defined (EOVERFLOW)
288 ENTRY(EOVERFLOW
, "EOVERFLOW", "Value too large for defined data type"),
290 #if defined (ENOTUNIQ)
291 ENTRY(ENOTUNIQ
, "ENOTUNIQ", "Name not unique on network"),
294 ENTRY(EBADFD
, "EBADFD", "File descriptor in bad state"),
296 #if defined (EREMCHG)
297 ENTRY(EREMCHG
, "EREMCHG", "Remote address changed"),
299 #if defined (ELIBACC)
300 ENTRY(ELIBACC
, "ELIBACC", "Can not access a needed shared library"),
302 #if defined (ELIBBAD)
303 ENTRY(ELIBBAD
, "ELIBBAD", "Accessing a corrupted shared library"),
305 #if defined (ELIBSCN)
306 ENTRY(ELIBSCN
, "ELIBSCN", ".lib section in a.out corrupted"),
308 #if defined (ELIBMAX)
309 ENTRY(ELIBMAX
, "ELIBMAX", "Attempting to link in too many shared libraries"),
311 #if defined (ELIBEXEC)
312 ENTRY(ELIBEXEC
, "ELIBEXEC", "Cannot exec a shared library directly"),
315 ENTRY(EILSEQ
, "EILSEQ", "Illegal byte sequence"),
318 ENTRY(ENOSYS
, "ENOSYS", "Operation not applicable"),
321 ENTRY(ELOOP
, "ELOOP", "Too many symbolic links encountered"),
323 #if defined (ERESTART)
324 ENTRY(ERESTART
, "ERESTART", "Interrupted system call should be restarted"),
326 #if defined (ESTRPIPE)
327 ENTRY(ESTRPIPE
, "ESTRPIPE", "Streams pipe error"),
329 #if defined (ENOTEMPTY)
330 ENTRY(ENOTEMPTY
, "ENOTEMPTY", "Directory not empty"),
333 ENTRY(EUSERS
, "EUSERS", "Too many users"),
335 #if defined (ENOTSOCK)
336 ENTRY(ENOTSOCK
, "ENOTSOCK", "Socket operation on non-socket"),
338 #if defined (EDESTADDRREQ)
339 ENTRY(EDESTADDRREQ
, "EDESTADDRREQ", "Destination address required"),
341 #if defined (EMSGSIZE)
342 ENTRY(EMSGSIZE
, "EMSGSIZE", "Message too long"),
344 #if defined (EPROTOTYPE)
345 ENTRY(EPROTOTYPE
, "EPROTOTYPE", "Protocol wrong type for socket"),
347 #if defined (ENOPROTOOPT)
348 ENTRY(ENOPROTOOPT
, "ENOPROTOOPT", "Protocol not available"),
350 #if defined (EPROTONOSUPPORT)
351 ENTRY(EPROTONOSUPPORT
, "EPROTONOSUPPORT", "Protocol not supported"),
353 #if defined (ESOCKTNOSUPPORT)
354 ENTRY(ESOCKTNOSUPPORT
, "ESOCKTNOSUPPORT", "Socket type not supported"),
356 #if defined (EOPNOTSUPP)
357 ENTRY(EOPNOTSUPP
, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
359 #if defined (EPFNOSUPPORT)
360 ENTRY(EPFNOSUPPORT
, "EPFNOSUPPORT", "Protocol family not supported"),
362 #if defined (EAFNOSUPPORT)
363 ENTRY(EAFNOSUPPORT
, "EAFNOSUPPORT", "Address family not supported by protocol"),
365 #if defined (EADDRINUSE)
366 ENTRY(EADDRINUSE
, "EADDRINUSE", "Address already in use"),
368 #if defined (EADDRNOTAVAIL)
369 ENTRY(EADDRNOTAVAIL
, "EADDRNOTAVAIL","Cannot assign requested address"),
371 #if defined (ENETDOWN)
372 ENTRY(ENETDOWN
, "ENETDOWN", "Network is down"),
374 #if defined (ENETUNREACH)
375 ENTRY(ENETUNREACH
, "ENETUNREACH", "Network is unreachable"),
377 #if defined (ENETRESET)
378 ENTRY(ENETRESET
, "ENETRESET", "Network dropped connection because of reset"),
380 #if defined (ECONNABORTED)
381 ENTRY(ECONNABORTED
, "ECONNABORTED", "Software caused connection abort"),
383 #if defined (ECONNRESET)
384 ENTRY(ECONNRESET
, "ECONNRESET", "Connection reset by peer"),
386 #if defined (ENOBUFS)
387 ENTRY(ENOBUFS
, "ENOBUFS", "No buffer space available"),
389 #if defined (EISCONN)
390 ENTRY(EISCONN
, "EISCONN", "Transport endpoint is already connected"),
392 #if defined (ENOTCONN)
393 ENTRY(ENOTCONN
, "ENOTCONN", "Transport endpoint is not connected"),
395 #if defined (ESHUTDOWN)
396 ENTRY(ESHUTDOWN
, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
398 #if defined (ETOOMANYREFS)
399 ENTRY(ETOOMANYREFS
, "ETOOMANYREFS", "Too many references: cannot splice"),
401 #if defined (ETIMEDOUT)
402 ENTRY(ETIMEDOUT
, "ETIMEDOUT", "Connection timed out"),
404 #if defined (ECONNREFUSED)
405 ENTRY(ECONNREFUSED
, "ECONNREFUSED", "Connection refused"),
407 #if defined (EHOSTDOWN)
408 ENTRY(EHOSTDOWN
, "EHOSTDOWN", "Host is down"),
410 #if defined (EHOSTUNREACH)
411 ENTRY(EHOSTUNREACH
, "EHOSTUNREACH", "No route to host"),
413 #if defined (EALREADY)
414 ENTRY(EALREADY
, "EALREADY", "Operation already in progress"),
416 #if defined (EINPROGRESS)
417 ENTRY(EINPROGRESS
, "EINPROGRESS", "Operation now in progress"),
420 ENTRY(ESTALE
, "ESTALE", "Stale NFS file handle"),
422 #if defined (EUCLEAN)
423 ENTRY(EUCLEAN
, "EUCLEAN", "Structure needs cleaning"),
425 #if defined (ENOTNAM)
426 ENTRY(ENOTNAM
, "ENOTNAM", "Not a XENIX named type file"),
428 #if defined (ENAVAIL)
429 ENTRY(ENAVAIL
, "ENAVAIL", "No XENIX semaphores available"),
432 ENTRY(EISNAM
, "EISNAM", "Is a named type file"),
434 #if defined (EREMOTEIO)
435 ENTRY(EREMOTEIO
, "EREMOTEIO", "Remote I/O error"),
441 /* This is not in the table, because the numeric value of EVMSERR (32767)
442 lies outside the range of sys_errlist[]. */
443 static struct { int value
; const char *name
, *msg
; }
444 evmserr
= { EVMSERR
, "EVMSERR", "VMS-specific error" };
447 /* Translation table allocated and initialized at runtime. Indexed by the
448 errno value to find the equivalent symbolic value. */
450 static const char **error_names
;
451 static int num_error_names
= 0;
453 /* Translation table allocated and initialized at runtime, if it does not
454 already exist in the host environment. Indexed by the errno value to find
455 the descriptive string.
457 We don't export it for use in other modules because even though it has the
458 same name, it differs from other implementations in that it is dynamically
459 initialized rather than statically initialized. */
461 #ifndef HAVE_SYS_ERRLIST
464 static const char **sys_errlist
;
469 extern char *sys_errlist
[];
478 init_error_tables -- initialize the name and message tables
482 static void init_error_tables ();
486 Using the error_table, which is initialized at compile time, generate
487 the error_names and the sys_errlist (if needed) tables, which are
488 indexed at runtime by a specific errno value.
492 The initialization of the tables may fail under low memory conditions,
493 in which case we don't do anything particularly useful, but we don't
494 bomb either. Who knows, it might succeed at a later point if we free
495 some memory in the meantime. In any case, the other routines know
496 how to deal with lack of a table after trying to initialize it. This
497 may or may not be considered to be a bug, that we don't specifically
498 warn about this particular failure mode.
505 const struct error_info
*eip
;
508 /* If we haven't already scanned the error_table once to find the maximum
509 errno value, then go find it now. */
511 if (num_error_names
== 0)
513 for (eip
= error_table
; eip
-> name
!= NULL
; eip
++)
515 if (eip
-> value
>= num_error_names
)
517 num_error_names
= eip
-> value
+ 1;
522 /* Now attempt to allocate the error_names table, zero it out, and then
523 initialize it from the statically initialized error_table. */
525 if (error_names
== NULL
)
527 nbytes
= num_error_names
* sizeof (char *);
528 if ((error_names
= (const char **) malloc (nbytes
)) != NULL
)
530 memset (error_names
, 0, nbytes
);
531 for (eip
= error_table
; eip
-> name
!= NULL
; eip
++)
533 error_names
[eip
-> value
] = eip
-> name
;
538 #ifndef HAVE_SYS_ERRLIST
540 /* Now attempt to allocate the sys_errlist table, zero it out, and then
541 initialize it from the statically initialized error_table. */
543 if (sys_errlist
== NULL
)
545 nbytes
= num_error_names
* sizeof (char *);
546 if ((sys_errlist
= (const char **) malloc (nbytes
)) != NULL
)
548 memset (sys_errlist
, 0, nbytes
);
549 sys_nerr
= num_error_names
;
550 for (eip
= error_table
; eip
-> name
!= NULL
; eip
++)
552 sys_errlist
[eip
-> value
] = eip
-> msg
;
565 errno_max -- return the max errno value
573 Returns the maximum errno value for which a corresponding symbolic
574 name or message is available. Note that in the case where
575 we use the sys_errlist supplied by the system, it is possible for
576 there to be more symbolic names than messages, or vice versa.
577 In fact, the manual page for perror(3C) explicitly warns that one
578 should check the size of the table (sys_nerr) before indexing it,
579 since new error codes may be added to the system before they are
580 added to the table. Thus sys_nerr might be smaller than value
581 implied by the largest errno value defined in <errno.h>.
583 We return the maximum value that can be used to obtain a meaningful
584 symbolic name or message.
593 if (error_names
== NULL
)
595 init_error_tables ();
597 maxsize
= MAX (sys_nerr
, num_error_names
);
598 return (maxsize
- 1);
601 #ifndef HAVE_STRERROR
607 strerror -- map an error number to an error message string
611 char *strerror (int errnoval)
615 Maps an errno number to an error message string, the contents of
616 which are implementation defined. On systems which have the external
617 variables sys_nerr and sys_errlist, these strings will be the same
618 as the ones used by perror().
620 If the supplied error number is within the valid range of indices
621 for the sys_errlist, but no message is available for the particular
622 error number, then returns the string "Error NUM", where NUM is the
625 If the supplied error number is not a valid index into sys_errlist,
628 The returned string is only guaranteed to be valid only until the
629 next call to strerror.
640 #ifndef HAVE_SYS_ERRLIST
642 if (error_names
== NULL
)
644 init_error_tables ();
649 if ((errnoval
< 0) || (errnoval
>= sys_nerr
))
652 if (errnoval
== evmserr
.value
)
656 /* Out of range, just return NULL */
659 else if ((sys_errlist
== NULL
) || (sys_errlist
[errnoval
] == NULL
))
661 /* In range, but no sys_errlist or no entry at this index. */
662 sprintf (buf
, "Error %d", errnoval
);
667 /* In range, and a valid message. Just return the message. */
668 msg
= (char *) sys_errlist
[errnoval
];
674 #endif /* ! HAVE_STRERROR */
681 strerrno -- map an error number to a symbolic name string
685 const char *strerrno (int errnoval)
689 Given an error number returned from a system call (typically
690 returned in errno), returns a pointer to a string containing the
691 symbolic name of that error number, as found in <errno.h>.
693 If the supplied error number is within the valid range of indices
694 for symbolic names, but no name is available for the particular
695 error number, then returns the string "Error NUM", where NUM is
698 If the supplied error number is not within the range of valid
699 indices, then returns NULL.
703 The contents of the location pointed to are only guaranteed to be
704 valid until the next call to strerrno.
715 if (error_names
== NULL
)
717 init_error_tables ();
720 if ((errnoval
< 0) || (errnoval
>= num_error_names
))
723 if (errnoval
== evmserr
.value
)
727 /* Out of range, just return NULL */
730 else if ((error_names
== NULL
) || (error_names
[errnoval
] == NULL
))
732 /* In range, but no error_names or no entry at this index. */
733 sprintf (buf
, "Error %d", errnoval
);
734 name
= (const char *) buf
;
738 /* In range, and a valid name. Just return the name. */
739 name
= error_names
[errnoval
];
749 strtoerrno -- map a symbolic errno name to a numeric value
753 int strtoerrno (char *name)
757 Given the symbolic name of a error number, map it to an errno value.
758 If no translation is found, returns 0.
770 if (error_names
== NULL
)
772 init_error_tables ();
774 for (errnoval
= 0; errnoval
< num_error_names
; errnoval
++)
776 if ((error_names
[errnoval
] != NULL
) &&
777 (strcmp (name
, error_names
[errnoval
]) == 0))
782 if (errnoval
== num_error_names
)
785 if (strcmp (name
, evmserr
.name
) == 0)
786 errnoval
= evmserr
.value
;
796 /* A simple little main that does nothing but print all the errno translations
797 if MAIN is defined and this file is compiled and linked. */
812 errnmax
= errno_max ();
813 printf ("%d entries in names table.\n", num_error_names
);
814 printf ("%d entries in messages table.\n", sys_nerr
);
815 printf ("%d is max useful index.\n", errnmax
);
817 /* Keep printing values until we get to the end of *both* tables, not
818 *either* table. Note that knowing the maximum useful index does *not*
819 relieve us of the responsibility of testing the return pointer for
822 for (errn
= 0; errn
<= errnmax
; errn
++)
824 name
= strerrno (errn
);
825 name
= (name
== NULL
) ? "<NULL>" : name
;
826 msg
= strerror (errn
);
827 msg
= (msg
== NULL
) ? "<NULL>" : msg
;
828 printf ("%-4d%-18s%s\n", errn
, name
, msg
);