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 const int value
; /* The numeric value from <errno.h> */
62 const char *const name
; /* The equivalent symbolic value */
63 #ifndef HAVE_SYS_ERRLIST
64 const char *const 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
;
566 @deftypefn Extension int errno_max (void)
568 Returns the maximum @code{errno} value for which a corresponding
569 symbolic name or message is available. Note that in the case where we
570 use the @code{sys_errlist} supplied by the system, it is possible for
571 there to be more symbolic names than messages, or vice versa. In
572 fact, the manual page for @code{perror(3C)} explicitly warns that one
573 should check the size of the table (@code{sys_nerr}) before indexing
574 it, since new error codes may be added to the system before they are
575 added to the table. Thus @code{sys_nerr} might be smaller than value
576 implied by the largest @code{errno} value defined in @code{<errno.h>}.
578 We return the maximum value that can be used to obtain a meaningful
579 symbolic name or message.
590 if (error_names
== NULL
)
592 init_error_tables ();
594 maxsize
= MAX (sys_nerr
, num_error_names
);
595 return (maxsize
- 1);
598 #ifndef HAVE_STRERROR
602 @deftypefn Supplemental char* strerror (int @var{errnoval})
604 Maps an @code{errno} number to an error message string, the contents
605 of which are implementation defined. On systems which have the
606 external variables @code{sys_nerr} and @code{sys_errlist}, these
607 strings will be the same as the ones used by @code{perror}.
609 If the supplied error number is within the valid range of indices for
610 the @code{sys_errlist}, but no message is available for the particular
611 error number, then returns the string @samp{Error @var{num}}, where
612 @var{num} is the error number.
614 If the supplied error number is not a valid index into
615 @code{sys_errlist}, returns @code{NULL}.
617 The returned string is only guaranteed to be valid only until the
618 next call to @code{strerror}.
631 #ifndef HAVE_SYS_ERRLIST
633 if (error_names
== NULL
)
635 init_error_tables ();
640 if ((errnoval
< 0) || (errnoval
>= sys_nerr
))
643 if (errnoval
== evmserr
.value
)
647 /* Out of range, just return NULL */
650 else if ((sys_errlist
== NULL
) || (sys_errlist
[errnoval
] == NULL
))
652 /* In range, but no sys_errlist or no entry at this index. */
653 sprintf (buf
, "Error %d", errnoval
);
658 /* In range, and a valid message. Just return the message. */
659 msg
= (char *) sys_errlist
[errnoval
];
665 #endif /* ! HAVE_STRERROR */
670 @deftypefn Replacement {const char*} strerrno (int @var{errnum})
672 Given an error number returned from a system call (typically returned
673 in @code{errno}), returns a pointer to a string containing the
674 symbolic name of that error number, as found in @code{<errno.h>}.
676 If the supplied error number is within the valid range of indices for
677 symbolic names, but no name is available for the particular error
678 number, then returns the string @samp{Error @var{num}}, where @var{num}
681 If the supplied error number is not within the range of valid
682 indices, then returns @code{NULL}.
684 The contents of the location pointed to are only guaranteed to be
685 valid until the next call to @code{strerrno}.
698 if (error_names
== NULL
)
700 init_error_tables ();
703 if ((errnoval
< 0) || (errnoval
>= num_error_names
))
706 if (errnoval
== evmserr
.value
)
710 /* Out of range, just return NULL */
713 else if ((error_names
== NULL
) || (error_names
[errnoval
] == NULL
))
715 /* In range, but no error_names or no entry at this index. */
716 sprintf (buf
, "Error %d", errnoval
);
717 name
= (const char *) buf
;
721 /* In range, and a valid name. Just return the name. */
722 name
= error_names
[errnoval
];
730 @deftypefn Extension int strtoerrno (const char *@var{name})
732 Given the symbolic name of a error number (e.g., @code{EACCES}), map it
733 to an errno value. If no translation is found, returns 0.
747 if (error_names
== NULL
)
749 init_error_tables ();
751 for (errnoval
= 0; errnoval
< num_error_names
; errnoval
++)
753 if ((error_names
[errnoval
] != NULL
) &&
754 (strcmp (name
, error_names
[errnoval
]) == 0))
759 if (errnoval
== num_error_names
)
762 if (strcmp (name
, evmserr
.name
) == 0)
763 errnoval
= evmserr
.value
;
773 /* A simple little main that does nothing but print all the errno translations
774 if MAIN is defined and this file is compiled and linked. */
789 errnmax
= errno_max ();
790 printf ("%d entries in names table.\n", num_error_names
);
791 printf ("%d entries in messages table.\n", sys_nerr
);
792 printf ("%d is max useful index.\n", errnmax
);
794 /* Keep printing values until we get to the end of *both* tables, not
795 *either* table. Note that knowing the maximum useful index does *not*
796 relieve us of the responsibility of testing the return pointer for
799 for (errn
= 0; errn
<= errnmax
; errn
++)
801 name
= strerrno (errn
);
802 name
= (name
== NULL
) ? "<NULL>" : name
;
803 msg
= strerror (errn
);
804 msg
= (msg
== NULL
) ? "<NULL>" : msg
;
805 printf ("%-4d%-18s%s\n", errn
, name
, msg
);