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_nerr sys_nerr__
17 #define sys_errlist sys_errlist__
23 #ifdef HAVE_SYS_ERRLIST
28 /* Routines imported from standard C runtime libraries. */
43 # define MAX(a,b) ((a) > (b) ? (a) : (b))
46 static void init_error_tables
PARAMS ((void));
48 /* Translation table for errno values. See intro(2) in most UNIX systems
49 Programmers Reference Manuals.
51 Note that this table is generally only accessed when it is used at runtime
52 to initialize errno name and message tables that are indexed by errno
55 Not all of these errnos will exist on all systems. This table is the only
56 thing that should have to be updated as new error numbers are introduced.
57 It's sort of ugly, but at least its portable. */
61 int value
; /* The numeric value from <errno.h> */
62 const char *name
; /* The equivalent symbolic value */
63 #ifndef HAVE_SYS_ERRLIST
64 const char *msg
; /* Short message about this value */
68 #ifndef HAVE_SYS_ERRLIST
69 # define ENTRY(value, name, msg) {value, name, msg}
71 # define ENTRY(value, name, msg) {value, name}
74 static const struct error_info error_table
[] =
77 ENTRY(EPERM
, "EPERM", "Not owner"),
80 ENTRY(ENOENT
, "ENOENT", "No such file or directory"),
83 ENTRY(ESRCH
, "ESRCH", "No such process"),
86 ENTRY(EINTR
, "EINTR", "Interrupted system call"),
89 ENTRY(EIO
, "EIO", "I/O error"),
92 ENTRY(ENXIO
, "ENXIO", "No such device or address"),
95 ENTRY(E2BIG
, "E2BIG", "Arg list too long"),
98 ENTRY(ENOEXEC
, "ENOEXEC", "Exec format error"),
101 ENTRY(EBADF
, "EBADF", "Bad file number"),
104 ENTRY(ECHILD
, "ECHILD", "No child processes"),
106 #if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
107 ENTRY(EWOULDBLOCK
, "EWOULDBLOCK", "Operation would block"),
110 ENTRY(EAGAIN
, "EAGAIN", "No more processes"),
113 ENTRY(ENOMEM
, "ENOMEM", "Not enough space"),
116 ENTRY(EACCES
, "EACCES", "Permission denied"),
119 ENTRY(EFAULT
, "EFAULT", "Bad address"),
121 #if defined (ENOTBLK)
122 ENTRY(ENOTBLK
, "ENOTBLK", "Block device required"),
125 ENTRY(EBUSY
, "EBUSY", "Device busy"),
128 ENTRY(EEXIST
, "EEXIST", "File exists"),
131 ENTRY(EXDEV
, "EXDEV", "Cross-device link"),
134 ENTRY(ENODEV
, "ENODEV", "No such device"),
136 #if defined (ENOTDIR)
137 ENTRY(ENOTDIR
, "ENOTDIR", "Not a directory"),
140 ENTRY(EISDIR
, "EISDIR", "Is a directory"),
143 ENTRY(EINVAL
, "EINVAL", "Invalid argument"),
146 ENTRY(ENFILE
, "ENFILE", "File table overflow"),
149 ENTRY(EMFILE
, "EMFILE", "Too many open files"),
152 ENTRY(ENOTTY
, "ENOTTY", "Not a typewriter"),
154 #if defined (ETXTBSY)
155 ENTRY(ETXTBSY
, "ETXTBSY", "Text file busy"),
158 ENTRY(EFBIG
, "EFBIG", "File too large"),
161 ENTRY(ENOSPC
, "ENOSPC", "No space left on device"),
164 ENTRY(ESPIPE
, "ESPIPE", "Illegal seek"),
167 ENTRY(EROFS
, "EROFS", "Read-only file system"),
170 ENTRY(EMLINK
, "EMLINK", "Too many links"),
173 ENTRY(EPIPE
, "EPIPE", "Broken pipe"),
176 ENTRY(EDOM
, "EDOM", "Math argument out of domain of func"),
179 ENTRY(ERANGE
, "ERANGE", "Math result not representable"),
182 ENTRY(ENOMSG
, "ENOMSG", "No message of desired type"),
185 ENTRY(EIDRM
, "EIDRM", "Identifier removed"),
188 ENTRY(ECHRNG
, "ECHRNG", "Channel number out of range"),
190 #if defined (EL2NSYNC)
191 ENTRY(EL2NSYNC
, "EL2NSYNC", "Level 2 not synchronized"),
194 ENTRY(EL3HLT
, "EL3HLT", "Level 3 halted"),
197 ENTRY(EL3RST
, "EL3RST", "Level 3 reset"),
200 ENTRY(ELNRNG
, "ELNRNG", "Link number out of range"),
202 #if defined (EUNATCH)
203 ENTRY(EUNATCH
, "EUNATCH", "Protocol driver not attached"),
206 ENTRY(ENOCSI
, "ENOCSI", "No CSI structure available"),
209 ENTRY(EL2HLT
, "EL2HLT", "Level 2 halted"),
211 #if defined (EDEADLK)
212 ENTRY(EDEADLK
, "EDEADLK", "Deadlock condition"),
215 ENTRY(ENOLCK
, "ENOLCK", "No record locks available"),
218 ENTRY(EBADE
, "EBADE", "Invalid exchange"),
221 ENTRY(EBADR
, "EBADR", "Invalid request descriptor"),
224 ENTRY(EXFULL
, "EXFULL", "Exchange full"),
227 ENTRY(ENOANO
, "ENOANO", "No anode"),
229 #if defined (EBADRQC)
230 ENTRY(EBADRQC
, "EBADRQC", "Invalid request code"),
232 #if defined (EBADSLT)
233 ENTRY(EBADSLT
, "EBADSLT", "Invalid slot"),
235 #if defined (EDEADLOCK)
236 ENTRY(EDEADLOCK
, "EDEADLOCK", "File locking deadlock error"),
239 ENTRY(EBFONT
, "EBFONT", "Bad font file format"),
242 ENTRY(ENOSTR
, "ENOSTR", "Device not a stream"),
244 #if defined (ENODATA)
245 ENTRY(ENODATA
, "ENODATA", "No data available"),
248 ENTRY(ETIME
, "ETIME", "Timer expired"),
251 ENTRY(ENOSR
, "ENOSR", "Out of streams resources"),
254 ENTRY(ENONET
, "ENONET", "Machine is not on the network"),
257 ENTRY(ENOPKG
, "ENOPKG", "Package not installed"),
259 #if defined (EREMOTE)
260 ENTRY(EREMOTE
, "EREMOTE", "Object is remote"),
262 #if defined (ENOLINK)
263 ENTRY(ENOLINK
, "ENOLINK", "Link has been severed"),
266 ENTRY(EADV
, "EADV", "Advertise error"),
269 ENTRY(ESRMNT
, "ESRMNT", "Srmount error"),
272 ENTRY(ECOMM
, "ECOMM", "Communication error on send"),
275 ENTRY(EPROTO
, "EPROTO", "Protocol error"),
277 #if defined (EMULTIHOP)
278 ENTRY(EMULTIHOP
, "EMULTIHOP", "Multihop attempted"),
280 #if defined (EDOTDOT)
281 ENTRY(EDOTDOT
, "EDOTDOT", "RFS specific error"),
283 #if defined (EBADMSG)
284 ENTRY(EBADMSG
, "EBADMSG", "Not a data message"),
286 #if defined (ENAMETOOLONG)
287 ENTRY(ENAMETOOLONG
, "ENAMETOOLONG", "File name too long"),
289 #if defined (EOVERFLOW)
290 ENTRY(EOVERFLOW
, "EOVERFLOW", "Value too large for defined data type"),
292 #if defined (ENOTUNIQ)
293 ENTRY(ENOTUNIQ
, "ENOTUNIQ", "Name not unique on network"),
296 ENTRY(EBADFD
, "EBADFD", "File descriptor in bad state"),
298 #if defined (EREMCHG)
299 ENTRY(EREMCHG
, "EREMCHG", "Remote address changed"),
301 #if defined (ELIBACC)
302 ENTRY(ELIBACC
, "ELIBACC", "Can not access a needed shared library"),
304 #if defined (ELIBBAD)
305 ENTRY(ELIBBAD
, "ELIBBAD", "Accessing a corrupted shared library"),
307 #if defined (ELIBSCN)
308 ENTRY(ELIBSCN
, "ELIBSCN", ".lib section in a.out corrupted"),
310 #if defined (ELIBMAX)
311 ENTRY(ELIBMAX
, "ELIBMAX", "Attempting to link in too many shared libraries"),
313 #if defined (ELIBEXEC)
314 ENTRY(ELIBEXEC
, "ELIBEXEC", "Cannot exec a shared library directly"),
317 ENTRY(EILSEQ
, "EILSEQ", "Illegal byte sequence"),
320 ENTRY(ENOSYS
, "ENOSYS", "Operation not applicable"),
323 ENTRY(ELOOP
, "ELOOP", "Too many symbolic links encountered"),
325 #if defined (ERESTART)
326 ENTRY(ERESTART
, "ERESTART", "Interrupted system call should be restarted"),
328 #if defined (ESTRPIPE)
329 ENTRY(ESTRPIPE
, "ESTRPIPE", "Streams pipe error"),
331 #if defined (ENOTEMPTY)
332 ENTRY(ENOTEMPTY
, "ENOTEMPTY", "Directory not empty"),
335 ENTRY(EUSERS
, "EUSERS", "Too many users"),
337 #if defined (ENOTSOCK)
338 ENTRY(ENOTSOCK
, "ENOTSOCK", "Socket operation on non-socket"),
340 #if defined (EDESTADDRREQ)
341 ENTRY(EDESTADDRREQ
, "EDESTADDRREQ", "Destination address required"),
343 #if defined (EMSGSIZE)
344 ENTRY(EMSGSIZE
, "EMSGSIZE", "Message too long"),
346 #if defined (EPROTOTYPE)
347 ENTRY(EPROTOTYPE
, "EPROTOTYPE", "Protocol wrong type for socket"),
349 #if defined (ENOPROTOOPT)
350 ENTRY(ENOPROTOOPT
, "ENOPROTOOPT", "Protocol not available"),
352 #if defined (EPROTONOSUPPORT)
353 ENTRY(EPROTONOSUPPORT
, "EPROTONOSUPPORT", "Protocol not supported"),
355 #if defined (ESOCKTNOSUPPORT)
356 ENTRY(ESOCKTNOSUPPORT
, "ESOCKTNOSUPPORT", "Socket type not supported"),
358 #if defined (EOPNOTSUPP)
359 ENTRY(EOPNOTSUPP
, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
361 #if defined (EPFNOSUPPORT)
362 ENTRY(EPFNOSUPPORT
, "EPFNOSUPPORT", "Protocol family not supported"),
364 #if defined (EAFNOSUPPORT)
365 ENTRY(EAFNOSUPPORT
, "EAFNOSUPPORT", "Address family not supported by protocol"),
367 #if defined (EADDRINUSE)
368 ENTRY(EADDRINUSE
, "EADDRINUSE", "Address already in use"),
370 #if defined (EADDRNOTAVAIL)
371 ENTRY(EADDRNOTAVAIL
, "EADDRNOTAVAIL","Cannot assign requested address"),
373 #if defined (ENETDOWN)
374 ENTRY(ENETDOWN
, "ENETDOWN", "Network is down"),
376 #if defined (ENETUNREACH)
377 ENTRY(ENETUNREACH
, "ENETUNREACH", "Network is unreachable"),
379 #if defined (ENETRESET)
380 ENTRY(ENETRESET
, "ENETRESET", "Network dropped connection because of reset"),
382 #if defined (ECONNABORTED)
383 ENTRY(ECONNABORTED
, "ECONNABORTED", "Software caused connection abort"),
385 #if defined (ECONNRESET)
386 ENTRY(ECONNRESET
, "ECONNRESET", "Connection reset by peer"),
388 #if defined (ENOBUFS)
389 ENTRY(ENOBUFS
, "ENOBUFS", "No buffer space available"),
391 #if defined (EISCONN)
392 ENTRY(EISCONN
, "EISCONN", "Transport endpoint is already connected"),
394 #if defined (ENOTCONN)
395 ENTRY(ENOTCONN
, "ENOTCONN", "Transport endpoint is not connected"),
397 #if defined (ESHUTDOWN)
398 ENTRY(ESHUTDOWN
, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
400 #if defined (ETOOMANYREFS)
401 ENTRY(ETOOMANYREFS
, "ETOOMANYREFS", "Too many references: cannot splice"),
403 #if defined (ETIMEDOUT)
404 ENTRY(ETIMEDOUT
, "ETIMEDOUT", "Connection timed out"),
406 #if defined (ECONNREFUSED)
407 ENTRY(ECONNREFUSED
, "ECONNREFUSED", "Connection refused"),
409 #if defined (EHOSTDOWN)
410 ENTRY(EHOSTDOWN
, "EHOSTDOWN", "Host is down"),
412 #if defined (EHOSTUNREACH)
413 ENTRY(EHOSTUNREACH
, "EHOSTUNREACH", "No route to host"),
415 #if defined (EALREADY)
416 ENTRY(EALREADY
, "EALREADY", "Operation already in progress"),
418 #if defined (EINPROGRESS)
419 ENTRY(EINPROGRESS
, "EINPROGRESS", "Operation now in progress"),
422 ENTRY(ESTALE
, "ESTALE", "Stale NFS file handle"),
424 #if defined (EUCLEAN)
425 ENTRY(EUCLEAN
, "EUCLEAN", "Structure needs cleaning"),
427 #if defined (ENOTNAM)
428 ENTRY(ENOTNAM
, "ENOTNAM", "Not a XENIX named type file"),
430 #if defined (ENAVAIL)
431 ENTRY(ENAVAIL
, "ENAVAIL", "No XENIX semaphores available"),
434 ENTRY(EISNAM
, "EISNAM", "Is a named type file"),
436 #if defined (EREMOTEIO)
437 ENTRY(EREMOTEIO
, "EREMOTEIO", "Remote I/O error"),
443 /* This is not in the table, because the numeric value of EVMSERR (32767)
444 lies outside the range of sys_errlist[]. */
445 static struct { int value
; const char *name
, *msg
; }
446 evmserr
= { EVMSERR
, "EVMSERR", "VMS-specific error" };
449 /* Translation table allocated and initialized at runtime. Indexed by the
450 errno value to find the equivalent symbolic value. */
452 static const char **error_names
;
453 static int num_error_names
= 0;
455 /* Translation table allocated and initialized at runtime, if it does not
456 already exist in the host environment. Indexed by the errno value to find
457 the descriptive string.
459 We don't export it for use in other modules because even though it has the
460 same name, it differs from other implementations in that it is dynamically
461 initialized rather than statically initialized. */
463 #ifndef HAVE_SYS_ERRLIST
466 static const char **sys_errlist
;
471 extern char *sys_errlist
[];
480 init_error_tables -- initialize the name and message tables
484 static void init_error_tables ();
488 Using the error_table, which is initialized at compile time, generate
489 the error_names and the sys_errlist (if needed) tables, which are
490 indexed at runtime by a specific errno value.
494 The initialization of the tables may fail under low memory conditions,
495 in which case we don't do anything particularly useful, but we don't
496 bomb either. Who knows, it might succeed at a later point if we free
497 some memory in the meantime. In any case, the other routines know
498 how to deal with lack of a table after trying to initialize it. This
499 may or may not be considered to be a bug, that we don't specifically
500 warn about this particular failure mode.
507 const struct error_info
*eip
;
510 /* If we haven't already scanned the error_table once to find the maximum
511 errno value, then go find it now. */
513 if (num_error_names
== 0)
515 for (eip
= error_table
; eip
-> name
!= NULL
; eip
++)
517 if (eip
-> value
>= num_error_names
)
519 num_error_names
= eip
-> value
+ 1;
524 /* Now attempt to allocate the error_names table, zero it out, and then
525 initialize it from the statically initialized error_table. */
527 if (error_names
== NULL
)
529 nbytes
= num_error_names
* sizeof (char *);
530 if ((error_names
= (const char **) malloc (nbytes
)) != NULL
)
532 memset (error_names
, 0, nbytes
);
533 for (eip
= error_table
; eip
-> name
!= NULL
; eip
++)
535 error_names
[eip
-> value
] = eip
-> name
;
540 #ifndef HAVE_SYS_ERRLIST
542 /* Now attempt to allocate the sys_errlist table, zero it out, and then
543 initialize it from the statically initialized error_table. */
545 if (sys_errlist
== NULL
)
547 nbytes
= num_error_names
* sizeof (char *);
548 if ((sys_errlist
= (const char **) malloc (nbytes
)) != NULL
)
550 memset (sys_errlist
, 0, nbytes
);
551 sys_nerr
= num_error_names
;
552 for (eip
= error_table
; eip
-> name
!= NULL
; eip
++)
554 sys_errlist
[eip
-> value
] = eip
-> msg
;
567 errno_max -- return the max errno value
575 Returns the maximum errno value for which a corresponding symbolic
576 name or message is available. Note that in the case where
577 we use the sys_errlist supplied by the system, it is possible for
578 there to be more symbolic names than messages, or vice versa.
579 In fact, the manual page for perror(3C) explicitly warns that one
580 should check the size of the table (sys_nerr) before indexing it,
581 since new error codes may be added to the system before they are
582 added to the table. Thus sys_nerr might be smaller than value
583 implied by the largest errno value defined in <errno.h>.
585 We return the maximum value that can be used to obtain a meaningful
586 symbolic name or message.
595 if (error_names
== NULL
)
597 init_error_tables ();
599 maxsize
= MAX (sys_nerr
, num_error_names
);
600 return (maxsize
- 1);
603 #ifndef HAVE_STRERROR
609 strerror -- map an error number to an error message string
613 char *strerror (int errnoval)
617 Maps an errno number to an error message string, the contents of
618 which are implementation defined. On systems which have the external
619 variables sys_nerr and sys_errlist, these strings will be the same
620 as the ones used by perror().
622 If the supplied error number is within the valid range of indices
623 for the sys_errlist, but no message is available for the particular
624 error number, then returns the string "Error NUM", where NUM is the
627 If the supplied error number is not a valid index into sys_errlist,
630 The returned string is only guaranteed to be valid only until the
631 next call to strerror.
642 #ifndef HAVE_SYS_ERRLIST
644 if (error_names
== NULL
)
646 init_error_tables ();
651 if ((errnoval
< 0) || (errnoval
>= sys_nerr
))
654 if (errnoval
== evmserr
.value
)
658 /* Out of range, just return NULL */
661 else if ((sys_errlist
== NULL
) || (sys_errlist
[errnoval
] == NULL
))
663 /* In range, but no sys_errlist or no entry at this index. */
664 sprintf (buf
, "Error %d", errnoval
);
669 /* In range, and a valid message. Just return the message. */
670 msg
= (char *) sys_errlist
[errnoval
];
676 #endif /* ! HAVE_STRERROR */
683 strerrno -- map an error number to a symbolic name string
687 const char *strerrno (int errnoval)
691 Given an error number returned from a system call (typically
692 returned in errno), returns a pointer to a string containing the
693 symbolic name of that error number, as found in <errno.h>.
695 If the supplied error number is within the valid range of indices
696 for symbolic names, but no name is available for the particular
697 error number, then returns the string "Error NUM", where NUM is
700 If the supplied error number is not within the range of valid
701 indices, then returns NULL.
705 The contents of the location pointed to are only guaranteed to be
706 valid until the next call to strerrno.
717 if (error_names
== NULL
)
719 init_error_tables ();
722 if ((errnoval
< 0) || (errnoval
>= num_error_names
))
725 if (errnoval
== evmserr
.value
)
729 /* Out of range, just return NULL */
732 else if ((error_names
== NULL
) || (error_names
[errnoval
] == NULL
))
734 /* In range, but no error_names or no entry at this index. */
735 sprintf (buf
, "Error %d", errnoval
);
736 name
= (const char *) buf
;
740 /* In range, and a valid name. Just return the name. */
741 name
= error_names
[errnoval
];
751 strtoerrno -- map a symbolic errno name to a numeric value
755 int strtoerrno (char *name)
759 Given the symbolic name of a error number, map it to an errno value.
760 If no translation is found, returns 0.
772 if (error_names
== NULL
)
774 init_error_tables ();
776 for (errnoval
= 0; errnoval
< num_error_names
; errnoval
++)
778 if ((error_names
[errnoval
] != NULL
) &&
779 (strcmp (name
, error_names
[errnoval
]) == 0))
784 if (errnoval
== num_error_names
)
787 if (strcmp (name
, evmserr
.name
) == 0)
788 errnoval
= evmserr
.value
;
798 /* A simple little main that does nothing but print all the errno translations
799 if MAIN is defined and this file is compiled and linked. */
814 errnmax
= errno_max ();
815 printf ("%d entries in names table.\n", num_error_names
);
816 printf ("%d entries in messages table.\n", sys_nerr
);
817 printf ("%d is max useful index.\n", errnmax
);
819 /* Keep printing values until we get to the end of *both* tables, not
820 *either* table. Note that knowing the maximum useful index does *not*
821 relieve us of the responsibility of testing the return pointer for
824 for (errn
= 0; errn
<= errnmax
; errn
++)
826 name
= strerrno (errn
);
827 name
= (name
== NULL
) ? "<NULL>" : name
;
828 msg
= strerror (errn
);
829 msg
= (msg
== NULL
) ? "<NULL>" : msg
;
830 printf ("%-4d%-18s%s\n", errn
, name
, msg
);