xref: /openbsd-src/gnu/lib/libiberty/src/strerror.c (revision c404a2006c955289d4e7aa31e6e6f26d6da180a3)
100bf4279Sespie /* Extended support for using errno values.
200bf4279Sespie    Written by Fred Fish.  fnf@cygnus.com
300bf4279Sespie    This file is in the public domain.  --Per Bothner.  */
400bf4279Sespie 
500bf4279Sespie #include "config.h"
600bf4279Sespie 
700bf4279Sespie #ifdef HAVE_SYS_ERRLIST
800bf4279Sespie /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
900bf4279Sespie    might declare sys_errlist in a way that the compiler might consider
1000bf4279Sespie    incompatible with our later declaration, perhaps by using const
1100bf4279Sespie    attributes.  So we hide the declaration in errno.h (if any) using a
1200bf4279Sespie    macro. */
1337c53322Sespie #define sys_nerr sys_nerr__
1400bf4279Sespie #define sys_errlist sys_errlist__
1500bf4279Sespie #endif
1600bf4279Sespie 
17150b7e42Smiod #include "ansidecl.h"
18150b7e42Smiod #include "libiberty.h"
19150b7e42Smiod 
2000bf4279Sespie #include <stdio.h>
2100bf4279Sespie #include <errno.h>
2200bf4279Sespie 
2300bf4279Sespie #ifdef HAVE_SYS_ERRLIST
2437c53322Sespie #undef sys_nerr
2500bf4279Sespie #undef sys_errlist
2600bf4279Sespie #endif
2700bf4279Sespie 
2800bf4279Sespie /*  Routines imported from standard C runtime libraries. */
2900bf4279Sespie 
30f5dd06f4Sespie #ifdef HAVE_STDLIB_H
31f5dd06f4Sespie #include <stdlib.h>
32f5dd06f4Sespie #else
33f5dd06f4Sespie extern PTR malloc ();
34f5dd06f4Sespie #endif
35f5dd06f4Sespie 
36f5dd06f4Sespie #ifdef HAVE_STRING_H
37f5dd06f4Sespie #include <string.h>
38f5dd06f4Sespie #else
39f5dd06f4Sespie extern PTR memset ();
40f5dd06f4Sespie #endif
4100bf4279Sespie 
4200bf4279Sespie #ifndef MAX
4300bf4279Sespie #  define MAX(a,b) ((a) > (b) ? (a) : (b))
4400bf4279Sespie #endif
4500bf4279Sespie 
46150b7e42Smiod static void init_error_tables (void);
4700bf4279Sespie 
4800bf4279Sespie /* Translation table for errno values.  See intro(2) in most UNIX systems
4900bf4279Sespie    Programmers Reference Manuals.
5000bf4279Sespie 
5100bf4279Sespie    Note that this table is generally only accessed when it is used at runtime
5200bf4279Sespie    to initialize errno name and message tables that are indexed by errno
5300bf4279Sespie    value.
5400bf4279Sespie 
5500bf4279Sespie    Not all of these errnos will exist on all systems.  This table is the only
5600bf4279Sespie    thing that should have to be updated as new error numbers are introduced.
5700bf4279Sespie    It's sort of ugly, but at least its portable. */
5800bf4279Sespie 
5900bf4279Sespie struct error_info
6000bf4279Sespie {
6137c53322Sespie   const int value;		/* The numeric value from <errno.h> */
6237c53322Sespie   const char *const name;	/* The equivalent symbolic value */
6300bf4279Sespie #ifndef HAVE_SYS_ERRLIST
6437c53322Sespie   const char *const msg;	/* Short message about this value */
6500bf4279Sespie #endif
6600bf4279Sespie };
6700bf4279Sespie 
6800bf4279Sespie #ifndef HAVE_SYS_ERRLIST
6900bf4279Sespie #   define ENTRY(value, name, msg)	{value, name, msg}
7000bf4279Sespie #else
7100bf4279Sespie #   define ENTRY(value, name, msg)	{value, name}
7200bf4279Sespie #endif
7300bf4279Sespie 
7400bf4279Sespie static const struct error_info error_table[] =
7500bf4279Sespie {
7600bf4279Sespie #if defined (EPERM)
7700bf4279Sespie   ENTRY(EPERM, "EPERM", "Not owner"),
7800bf4279Sespie #endif
7900bf4279Sespie #if defined (ENOENT)
8000bf4279Sespie   ENTRY(ENOENT, "ENOENT", "No such file or directory"),
8100bf4279Sespie #endif
8200bf4279Sespie #if defined (ESRCH)
8300bf4279Sespie   ENTRY(ESRCH, "ESRCH", "No such process"),
8400bf4279Sespie #endif
8500bf4279Sespie #if defined (EINTR)
8600bf4279Sespie   ENTRY(EINTR, "EINTR", "Interrupted system call"),
8700bf4279Sespie #endif
8800bf4279Sespie #if defined (EIO)
8900bf4279Sespie   ENTRY(EIO, "EIO", "I/O error"),
9000bf4279Sespie #endif
9100bf4279Sespie #if defined (ENXIO)
9200bf4279Sespie   ENTRY(ENXIO, "ENXIO", "No such device or address"),
9300bf4279Sespie #endif
9400bf4279Sespie #if defined (E2BIG)
9500bf4279Sespie   ENTRY(E2BIG, "E2BIG", "Arg list too long"),
9600bf4279Sespie #endif
9700bf4279Sespie #if defined (ENOEXEC)
9800bf4279Sespie   ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
9900bf4279Sespie #endif
10000bf4279Sespie #if defined (EBADF)
10100bf4279Sespie   ENTRY(EBADF, "EBADF", "Bad file number"),
10200bf4279Sespie #endif
10300bf4279Sespie #if defined (ECHILD)
10400bf4279Sespie   ENTRY(ECHILD, "ECHILD", "No child processes"),
10500bf4279Sespie #endif
10600bf4279Sespie #if defined (EWOULDBLOCK)	/* Put before EAGAIN, sometimes aliased */
10700bf4279Sespie   ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
10800bf4279Sespie #endif
10900bf4279Sespie #if defined (EAGAIN)
11000bf4279Sespie   ENTRY(EAGAIN, "EAGAIN", "No more processes"),
11100bf4279Sespie #endif
11200bf4279Sespie #if defined (ENOMEM)
11300bf4279Sespie   ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
11400bf4279Sespie #endif
11500bf4279Sespie #if defined (EACCES)
11600bf4279Sespie   ENTRY(EACCES, "EACCES", "Permission denied"),
11700bf4279Sespie #endif
11800bf4279Sespie #if defined (EFAULT)
11900bf4279Sespie   ENTRY(EFAULT, "EFAULT", "Bad address"),
12000bf4279Sespie #endif
12100bf4279Sespie #if defined (ENOTBLK)
12200bf4279Sespie   ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
12300bf4279Sespie #endif
12400bf4279Sespie #if defined (EBUSY)
12500bf4279Sespie   ENTRY(EBUSY, "EBUSY", "Device busy"),
12600bf4279Sespie #endif
12700bf4279Sespie #if defined (EEXIST)
12800bf4279Sespie   ENTRY(EEXIST, "EEXIST", "File exists"),
12900bf4279Sespie #endif
13000bf4279Sespie #if defined (EXDEV)
13100bf4279Sespie   ENTRY(EXDEV, "EXDEV", "Cross-device link"),
13200bf4279Sespie #endif
13300bf4279Sespie #if defined (ENODEV)
13400bf4279Sespie   ENTRY(ENODEV, "ENODEV", "No such device"),
13500bf4279Sespie #endif
13600bf4279Sespie #if defined (ENOTDIR)
13700bf4279Sespie   ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
13800bf4279Sespie #endif
13900bf4279Sespie #if defined (EISDIR)
14000bf4279Sespie   ENTRY(EISDIR, "EISDIR", "Is a directory"),
14100bf4279Sespie #endif
14200bf4279Sespie #if defined (EINVAL)
14300bf4279Sespie   ENTRY(EINVAL, "EINVAL", "Invalid argument"),
14400bf4279Sespie #endif
14500bf4279Sespie #if defined (ENFILE)
14600bf4279Sespie   ENTRY(ENFILE, "ENFILE", "File table overflow"),
14700bf4279Sespie #endif
14800bf4279Sespie #if defined (EMFILE)
14900bf4279Sespie   ENTRY(EMFILE, "EMFILE", "Too many open files"),
15000bf4279Sespie #endif
15100bf4279Sespie #if defined (ENOTTY)
15200bf4279Sespie   ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
15300bf4279Sespie #endif
15400bf4279Sespie #if defined (ETXTBSY)
15500bf4279Sespie   ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
15600bf4279Sespie #endif
15700bf4279Sespie #if defined (EFBIG)
15800bf4279Sespie   ENTRY(EFBIG, "EFBIG", "File too large"),
15900bf4279Sespie #endif
16000bf4279Sespie #if defined (ENOSPC)
16100bf4279Sespie   ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
16200bf4279Sespie #endif
16300bf4279Sespie #if defined (ESPIPE)
16400bf4279Sespie   ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
16500bf4279Sespie #endif
16600bf4279Sespie #if defined (EROFS)
16700bf4279Sespie   ENTRY(EROFS, "EROFS", "Read-only file system"),
16800bf4279Sespie #endif
16900bf4279Sespie #if defined (EMLINK)
17000bf4279Sespie   ENTRY(EMLINK, "EMLINK", "Too many links"),
17100bf4279Sespie #endif
17200bf4279Sespie #if defined (EPIPE)
17300bf4279Sespie   ENTRY(EPIPE, "EPIPE", "Broken pipe"),
17400bf4279Sespie #endif
17500bf4279Sespie #if defined (EDOM)
17600bf4279Sespie   ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
17700bf4279Sespie #endif
17800bf4279Sespie #if defined (ERANGE)
17900bf4279Sespie   ENTRY(ERANGE, "ERANGE", "Math result not representable"),
18000bf4279Sespie #endif
18100bf4279Sespie #if defined (ENOMSG)
18200bf4279Sespie   ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
18300bf4279Sespie #endif
18400bf4279Sespie #if defined (EIDRM)
18500bf4279Sespie   ENTRY(EIDRM, "EIDRM", "Identifier removed"),
18600bf4279Sespie #endif
18700bf4279Sespie #if defined (ECHRNG)
18800bf4279Sespie   ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
18900bf4279Sespie #endif
19000bf4279Sespie #if defined (EL2NSYNC)
19100bf4279Sespie   ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
19200bf4279Sespie #endif
19300bf4279Sespie #if defined (EL3HLT)
19400bf4279Sespie   ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
19500bf4279Sespie #endif
19600bf4279Sespie #if defined (EL3RST)
19700bf4279Sespie   ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
19800bf4279Sespie #endif
19900bf4279Sespie #if defined (ELNRNG)
20000bf4279Sespie   ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
20100bf4279Sespie #endif
20200bf4279Sespie #if defined (EUNATCH)
20300bf4279Sespie   ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
20400bf4279Sespie #endif
20500bf4279Sespie #if defined (ENOCSI)
20600bf4279Sespie   ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
20700bf4279Sespie #endif
20800bf4279Sespie #if defined (EL2HLT)
20900bf4279Sespie   ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
21000bf4279Sespie #endif
21100bf4279Sespie #if defined (EDEADLK)
21200bf4279Sespie   ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
21300bf4279Sespie #endif
21400bf4279Sespie #if defined (ENOLCK)
21500bf4279Sespie   ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
21600bf4279Sespie #endif
21700bf4279Sespie #if defined (EBADE)
21800bf4279Sespie   ENTRY(EBADE, "EBADE", "Invalid exchange"),
21900bf4279Sespie #endif
22000bf4279Sespie #if defined (EBADR)
22100bf4279Sespie   ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
22200bf4279Sespie #endif
22300bf4279Sespie #if defined (EXFULL)
22400bf4279Sespie   ENTRY(EXFULL, "EXFULL", "Exchange full"),
22500bf4279Sespie #endif
22600bf4279Sespie #if defined (ENOANO)
22700bf4279Sespie   ENTRY(ENOANO, "ENOANO", "No anode"),
22800bf4279Sespie #endif
22900bf4279Sespie #if defined (EBADRQC)
23000bf4279Sespie   ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
23100bf4279Sespie #endif
23200bf4279Sespie #if defined (EBADSLT)
23300bf4279Sespie   ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
23400bf4279Sespie #endif
23500bf4279Sespie #if defined (EDEADLOCK)
23600bf4279Sespie   ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
23700bf4279Sespie #endif
23800bf4279Sespie #if defined (EBFONT)
23900bf4279Sespie   ENTRY(EBFONT, "EBFONT", "Bad font file format"),
24000bf4279Sespie #endif
24100bf4279Sespie #if defined (ENOSTR)
24200bf4279Sespie   ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
24300bf4279Sespie #endif
24400bf4279Sespie #if defined (ENODATA)
24500bf4279Sespie   ENTRY(ENODATA, "ENODATA", "No data available"),
24600bf4279Sespie #endif
24700bf4279Sespie #if defined (ETIME)
24800bf4279Sespie   ENTRY(ETIME, "ETIME", "Timer expired"),
24900bf4279Sespie #endif
25000bf4279Sespie #if defined (ENOSR)
25100bf4279Sespie   ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
25200bf4279Sespie #endif
25300bf4279Sespie #if defined (ENONET)
25400bf4279Sespie   ENTRY(ENONET, "ENONET", "Machine is not on the network"),
25500bf4279Sespie #endif
25600bf4279Sespie #if defined (ENOPKG)
25700bf4279Sespie   ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
25800bf4279Sespie #endif
25900bf4279Sespie #if defined (EREMOTE)
26000bf4279Sespie   ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
26100bf4279Sespie #endif
26200bf4279Sespie #if defined (ENOLINK)
26300bf4279Sespie   ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
26400bf4279Sespie #endif
26500bf4279Sespie #if defined (EADV)
26600bf4279Sespie   ENTRY(EADV, "EADV", "Advertise error"),
26700bf4279Sespie #endif
26800bf4279Sespie #if defined (ESRMNT)
26900bf4279Sespie   ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
27000bf4279Sespie #endif
27100bf4279Sespie #if defined (ECOMM)
27200bf4279Sespie   ENTRY(ECOMM, "ECOMM", "Communication error on send"),
27300bf4279Sespie #endif
27400bf4279Sespie #if defined (EPROTO)
27500bf4279Sespie   ENTRY(EPROTO, "EPROTO", "Protocol error"),
27600bf4279Sespie #endif
27700bf4279Sespie #if defined (EMULTIHOP)
27800bf4279Sespie   ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
27900bf4279Sespie #endif
28000bf4279Sespie #if defined (EDOTDOT)
28100bf4279Sespie   ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
28200bf4279Sespie #endif
28300bf4279Sespie #if defined (EBADMSG)
28400bf4279Sespie   ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
28500bf4279Sespie #endif
28600bf4279Sespie #if defined (ENAMETOOLONG)
28700bf4279Sespie   ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
28800bf4279Sespie #endif
28900bf4279Sespie #if defined (EOVERFLOW)
29000bf4279Sespie   ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
29100bf4279Sespie #endif
29200bf4279Sespie #if defined (ENOTUNIQ)
29300bf4279Sespie   ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
29400bf4279Sespie #endif
29500bf4279Sespie #if defined (EBADFD)
29600bf4279Sespie   ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
29700bf4279Sespie #endif
29800bf4279Sespie #if defined (EREMCHG)
29900bf4279Sespie   ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
30000bf4279Sespie #endif
30100bf4279Sespie #if defined (ELIBACC)
30200bf4279Sespie   ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"),
30300bf4279Sespie #endif
30400bf4279Sespie #if defined (ELIBBAD)
30500bf4279Sespie   ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
30600bf4279Sespie #endif
30700bf4279Sespie #if defined (ELIBSCN)
30800bf4279Sespie   ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
30900bf4279Sespie #endif
31000bf4279Sespie #if defined (ELIBMAX)
31100bf4279Sespie   ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
31200bf4279Sespie #endif
31300bf4279Sespie #if defined (ELIBEXEC)
31400bf4279Sespie   ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
31500bf4279Sespie #endif
31600bf4279Sespie #if defined (EILSEQ)
31700bf4279Sespie   ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
31800bf4279Sespie #endif
31900bf4279Sespie #if defined (ENOSYS)
32000bf4279Sespie   ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
32100bf4279Sespie #endif
32200bf4279Sespie #if defined (ELOOP)
32300bf4279Sespie   ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
32400bf4279Sespie #endif
32500bf4279Sespie #if defined (ERESTART)
32600bf4279Sespie   ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
32700bf4279Sespie #endif
32800bf4279Sespie #if defined (ESTRPIPE)
32900bf4279Sespie   ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
33000bf4279Sespie #endif
33100bf4279Sespie #if defined (ENOTEMPTY)
33200bf4279Sespie   ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
33300bf4279Sespie #endif
33400bf4279Sespie #if defined (EUSERS)
33500bf4279Sespie   ENTRY(EUSERS, "EUSERS", "Too many users"),
33600bf4279Sespie #endif
33700bf4279Sespie #if defined (ENOTSOCK)
33800bf4279Sespie   ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
33900bf4279Sespie #endif
34000bf4279Sespie #if defined (EDESTADDRREQ)
34100bf4279Sespie   ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
34200bf4279Sespie #endif
34300bf4279Sespie #if defined (EMSGSIZE)
34400bf4279Sespie   ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
34500bf4279Sespie #endif
34600bf4279Sespie #if defined (EPROTOTYPE)
34700bf4279Sespie   ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
34800bf4279Sespie #endif
34900bf4279Sespie #if defined (ENOPROTOOPT)
35000bf4279Sespie   ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"),
35100bf4279Sespie #endif
35200bf4279Sespie #if defined (EPROTONOSUPPORT)
35300bf4279Sespie   ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
35400bf4279Sespie #endif
35500bf4279Sespie #if defined (ESOCKTNOSUPPORT)
35600bf4279Sespie   ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
35700bf4279Sespie #endif
35800bf4279Sespie #if defined (EOPNOTSUPP)
35900bf4279Sespie   ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
36000bf4279Sespie #endif
36100bf4279Sespie #if defined (EPFNOSUPPORT)
36200bf4279Sespie   ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
36300bf4279Sespie #endif
36400bf4279Sespie #if defined (EAFNOSUPPORT)
36500bf4279Sespie   ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
36600bf4279Sespie #endif
36700bf4279Sespie #if defined (EADDRINUSE)
36800bf4279Sespie   ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
36900bf4279Sespie #endif
37000bf4279Sespie #if defined (EADDRNOTAVAIL)
37100bf4279Sespie   ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
37200bf4279Sespie #endif
37300bf4279Sespie #if defined (ENETDOWN)
37400bf4279Sespie   ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
37500bf4279Sespie #endif
37600bf4279Sespie #if defined (ENETUNREACH)
37700bf4279Sespie   ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
37800bf4279Sespie #endif
37900bf4279Sespie #if defined (ENETRESET)
38000bf4279Sespie   ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
38100bf4279Sespie #endif
38200bf4279Sespie #if defined (ECONNABORTED)
38300bf4279Sespie   ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
38400bf4279Sespie #endif
38500bf4279Sespie #if defined (ECONNRESET)
38600bf4279Sespie   ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
38700bf4279Sespie #endif
38800bf4279Sespie #if defined (ENOBUFS)
38900bf4279Sespie   ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
39000bf4279Sespie #endif
39100bf4279Sespie #if defined (EISCONN)
39200bf4279Sespie   ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
39300bf4279Sespie #endif
39400bf4279Sespie #if defined (ENOTCONN)
39500bf4279Sespie   ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
39600bf4279Sespie #endif
39700bf4279Sespie #if defined (ESHUTDOWN)
39800bf4279Sespie   ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
39900bf4279Sespie #endif
40000bf4279Sespie #if defined (ETOOMANYREFS)
40100bf4279Sespie   ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
40200bf4279Sespie #endif
40300bf4279Sespie #if defined (ETIMEDOUT)
40400bf4279Sespie   ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
40500bf4279Sespie #endif
40600bf4279Sespie #if defined (ECONNREFUSED)
40700bf4279Sespie   ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
40800bf4279Sespie #endif
40900bf4279Sespie #if defined (EHOSTDOWN)
41000bf4279Sespie   ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
41100bf4279Sespie #endif
41200bf4279Sespie #if defined (EHOSTUNREACH)
41300bf4279Sespie   ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
41400bf4279Sespie #endif
41500bf4279Sespie #if defined (EALREADY)
41600bf4279Sespie   ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
41700bf4279Sespie #endif
41800bf4279Sespie #if defined (EINPROGRESS)
41900bf4279Sespie   ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
42000bf4279Sespie #endif
42100bf4279Sespie #if defined (ESTALE)
42200bf4279Sespie   ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
42300bf4279Sespie #endif
42400bf4279Sespie #if defined (EUCLEAN)
42500bf4279Sespie   ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
42600bf4279Sespie #endif
42700bf4279Sespie #if defined (ENOTNAM)
42800bf4279Sespie   ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
42900bf4279Sespie #endif
43000bf4279Sespie #if defined (ENAVAIL)
43100bf4279Sespie   ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
43200bf4279Sespie #endif
43300bf4279Sespie #if defined (EISNAM)
43400bf4279Sespie   ENTRY(EISNAM, "EISNAM", "Is a named type file"),
43500bf4279Sespie #endif
43600bf4279Sespie #if defined (EREMOTEIO)
43700bf4279Sespie   ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
43800bf4279Sespie #endif
43900bf4279Sespie   ENTRY(0, NULL, NULL)
44000bf4279Sespie };
44100bf4279Sespie 
44200bf4279Sespie #ifdef EVMSERR
44300bf4279Sespie /* This is not in the table, because the numeric value of EVMSERR (32767)
44400bf4279Sespie    lies outside the range of sys_errlist[].  */
44500bf4279Sespie static struct { int value; const char *name, *msg; }
44600bf4279Sespie   evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" };
44700bf4279Sespie #endif
44800bf4279Sespie 
44900bf4279Sespie /* Translation table allocated and initialized at runtime.  Indexed by the
45000bf4279Sespie    errno value to find the equivalent symbolic value. */
45100bf4279Sespie 
45200bf4279Sespie static const char **error_names;
45300bf4279Sespie static int num_error_names = 0;
45400bf4279Sespie 
45500bf4279Sespie /* Translation table allocated and initialized at runtime, if it does not
45600bf4279Sespie    already exist in the host environment.  Indexed by the errno value to find
45700bf4279Sespie    the descriptive string.
45800bf4279Sespie 
45900bf4279Sespie    We don't export it for use in other modules because even though it has the
46000bf4279Sespie    same name, it differs from other implementations in that it is dynamically
46100bf4279Sespie    initialized rather than statically initialized. */
46200bf4279Sespie 
46300bf4279Sespie #ifndef HAVE_SYS_ERRLIST
46400bf4279Sespie 
465150b7e42Smiod #define sys_nerr sys_nerr__
466150b7e42Smiod #define sys_errlist sys_errlist__
46700bf4279Sespie static int sys_nerr;
46800bf4279Sespie static const char **sys_errlist;
46900bf4279Sespie 
47000bf4279Sespie #else
47100bf4279Sespie 
47200bf4279Sespie extern int sys_nerr;
47300bf4279Sespie extern char *sys_errlist[];
47400bf4279Sespie 
47500bf4279Sespie #endif
47600bf4279Sespie 
47700bf4279Sespie /*
47800bf4279Sespie 
47900bf4279Sespie NAME
48000bf4279Sespie 
48100bf4279Sespie 	init_error_tables -- initialize the name and message tables
48200bf4279Sespie 
48300bf4279Sespie SYNOPSIS
48400bf4279Sespie 
48500bf4279Sespie 	static void init_error_tables ();
48600bf4279Sespie 
48700bf4279Sespie DESCRIPTION
48800bf4279Sespie 
48900bf4279Sespie 	Using the error_table, which is initialized at compile time, generate
49000bf4279Sespie 	the error_names and the sys_errlist (if needed) tables, which are
49100bf4279Sespie 	indexed at runtime by a specific errno value.
49200bf4279Sespie 
49300bf4279Sespie BUGS
49400bf4279Sespie 
49500bf4279Sespie 	The initialization of the tables may fail under low memory conditions,
49600bf4279Sespie 	in which case we don't do anything particularly useful, but we don't
49700bf4279Sespie 	bomb either.  Who knows, it might succeed at a later point if we free
49800bf4279Sespie 	some memory in the meantime.  In any case, the other routines know
49900bf4279Sespie 	how to deal with lack of a table after trying to initialize it.  This
50000bf4279Sespie 	may or may not be considered to be a bug, that we don't specifically
50100bf4279Sespie 	warn about this particular failure mode.
50200bf4279Sespie 
50300bf4279Sespie */
50400bf4279Sespie 
50500bf4279Sespie static void
init_error_tables(void)506150b7e42Smiod init_error_tables (void)
50700bf4279Sespie {
50800bf4279Sespie   const struct error_info *eip;
50900bf4279Sespie   int nbytes;
51000bf4279Sespie 
51100bf4279Sespie   /* If we haven't already scanned the error_table once to find the maximum
51200bf4279Sespie      errno value, then go find it now. */
51300bf4279Sespie 
51400bf4279Sespie   if (num_error_names == 0)
51500bf4279Sespie     {
51600bf4279Sespie       for (eip = error_table; eip -> name != NULL; eip++)
51700bf4279Sespie 	{
51800bf4279Sespie 	  if (eip -> value >= num_error_names)
51900bf4279Sespie 	    {
52000bf4279Sespie 	      num_error_names = eip -> value + 1;
52100bf4279Sespie 	    }
52200bf4279Sespie 	}
52300bf4279Sespie     }
52400bf4279Sespie 
52500bf4279Sespie   /* Now attempt to allocate the error_names table, zero it out, and then
52600bf4279Sespie      initialize it from the statically initialized error_table. */
52700bf4279Sespie 
52800bf4279Sespie   if (error_names == NULL)
52900bf4279Sespie     {
53000bf4279Sespie       nbytes = num_error_names * sizeof (char *);
53100bf4279Sespie       if ((error_names = (const char **) malloc (nbytes)) != NULL)
53200bf4279Sespie 	{
53300bf4279Sespie 	  memset (error_names, 0, nbytes);
53400bf4279Sespie 	  for (eip = error_table; eip -> name != NULL; eip++)
53500bf4279Sespie 	    {
53600bf4279Sespie 	      error_names[eip -> value] = eip -> name;
53700bf4279Sespie 	    }
53800bf4279Sespie 	}
53900bf4279Sespie     }
54000bf4279Sespie 
54100bf4279Sespie #ifndef HAVE_SYS_ERRLIST
54200bf4279Sespie 
54300bf4279Sespie   /* Now attempt to allocate the sys_errlist table, zero it out, and then
54400bf4279Sespie      initialize it from the statically initialized error_table. */
54500bf4279Sespie 
54600bf4279Sespie   if (sys_errlist == NULL)
54700bf4279Sespie     {
54800bf4279Sespie       nbytes = num_error_names * sizeof (char *);
54900bf4279Sespie       if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
55000bf4279Sespie 	{
55100bf4279Sespie 	  memset (sys_errlist, 0, nbytes);
55200bf4279Sespie 	  sys_nerr = num_error_names;
55300bf4279Sespie 	  for (eip = error_table; eip -> name != NULL; eip++)
55400bf4279Sespie 	    {
55500bf4279Sespie 	      sys_errlist[eip -> value] = eip -> msg;
55600bf4279Sespie 	    }
55700bf4279Sespie 	}
55800bf4279Sespie     }
55900bf4279Sespie 
56000bf4279Sespie #endif
56100bf4279Sespie 
56200bf4279Sespie }
56300bf4279Sespie 
56400bf4279Sespie /*
56500bf4279Sespie 
56600bf4279Sespie 
56737c53322Sespie @deftypefn Extension int errno_max (void)
56800bf4279Sespie 
56937c53322Sespie Returns the maximum @code{errno} value for which a corresponding
57037c53322Sespie symbolic name or message is available.  Note that in the case where we
57137c53322Sespie use the @code{sys_errlist} supplied by the system, it is possible for
57237c53322Sespie there to be more symbolic names than messages, or vice versa.  In
57337c53322Sespie fact, the manual page for @code{perror(3C)} explicitly warns that one
57437c53322Sespie should check the size of the table (@code{sys_nerr}) before indexing
57537c53322Sespie it, since new error codes may be added to the system before they are
57637c53322Sespie added to the table.  Thus @code{sys_nerr} might be smaller than value
57737c53322Sespie implied by the largest @code{errno} value defined in @code{<errno.h>}.
57800bf4279Sespie 
57900bf4279Sespie We return the maximum value that can be used to obtain a meaningful
58000bf4279Sespie symbolic name or message.
58100bf4279Sespie 
58237c53322Sespie @end deftypefn
58337c53322Sespie 
58400bf4279Sespie */
58500bf4279Sespie 
58600bf4279Sespie int
errno_max(void)587150b7e42Smiod errno_max (void)
58800bf4279Sespie {
58900bf4279Sespie   int maxsize;
59000bf4279Sespie 
59100bf4279Sespie   if (error_names == NULL)
59200bf4279Sespie     {
59300bf4279Sespie       init_error_tables ();
59400bf4279Sespie     }
59500bf4279Sespie   maxsize = MAX (sys_nerr, num_error_names);
59600bf4279Sespie   return (maxsize - 1);
59700bf4279Sespie }
59800bf4279Sespie 
59900bf4279Sespie #ifndef HAVE_STRERROR
60000bf4279Sespie 
60100bf4279Sespie /*
60200bf4279Sespie 
60337c53322Sespie @deftypefn Supplemental char* strerror (int @var{errnoval})
60400bf4279Sespie 
60537c53322Sespie Maps an @code{errno} number to an error message string, the contents
60637c53322Sespie of which are implementation defined.  On systems which have the
60737c53322Sespie external variables @code{sys_nerr} and @code{sys_errlist}, these
60837c53322Sespie strings will be the same as the ones used by @code{perror}.
60900bf4279Sespie 
61037c53322Sespie If the supplied error number is within the valid range of indices for
61137c53322Sespie the @code{sys_errlist}, but no message is available for the particular
61237c53322Sespie error number, then returns the string @samp{Error @var{num}}, where
61337c53322Sespie @var{num} is the error number.
61400bf4279Sespie 
61537c53322Sespie If the supplied error number is not a valid index into
61637c53322Sespie @code{sys_errlist}, returns @code{NULL}.
61700bf4279Sespie 
61800bf4279Sespie The returned string is only guaranteed to be valid only until the
61937c53322Sespie next call to @code{strerror}.
62037c53322Sespie 
62137c53322Sespie @end deftypefn
62200bf4279Sespie 
62300bf4279Sespie */
62400bf4279Sespie 
62500bf4279Sespie char *
strerror(int errnoval)626150b7e42Smiod strerror (int errnoval)
62700bf4279Sespie {
62837c53322Sespie   const char *msg;
62900bf4279Sespie   static char buf[32];
63000bf4279Sespie 
63100bf4279Sespie #ifndef HAVE_SYS_ERRLIST
63200bf4279Sespie 
63300bf4279Sespie   if (error_names == NULL)
63400bf4279Sespie     {
63500bf4279Sespie       init_error_tables ();
63600bf4279Sespie     }
63700bf4279Sespie 
63800bf4279Sespie #endif
63900bf4279Sespie 
64000bf4279Sespie   if ((errnoval < 0) || (errnoval >= sys_nerr))
64100bf4279Sespie     {
64200bf4279Sespie #ifdef EVMSERR
64300bf4279Sespie       if (errnoval == evmserr.value)
64400bf4279Sespie 	msg = evmserr.msg;
64500bf4279Sespie       else
64600bf4279Sespie #endif
64700bf4279Sespie       /* Out of range, just return NULL */
64800bf4279Sespie       msg = NULL;
64900bf4279Sespie     }
65000bf4279Sespie   else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
65100bf4279Sespie     {
65200bf4279Sespie       /* In range, but no sys_errlist or no entry at this index. */
653*c404a200Smiod       snprintf (buf, sizeof buf, "Error %d", errnoval);
65400bf4279Sespie       msg = buf;
65500bf4279Sespie     }
65600bf4279Sespie   else
65700bf4279Sespie     {
65800bf4279Sespie       /* In range, and a valid message.  Just return the message. */
65900bf4279Sespie       msg = (char *) sys_errlist[errnoval];
66000bf4279Sespie     }
66100bf4279Sespie 
66200bf4279Sespie   return (msg);
66300bf4279Sespie }
66400bf4279Sespie 
66500bf4279Sespie #endif	/* ! HAVE_STRERROR */
66600bf4279Sespie 
66700bf4279Sespie 
66800bf4279Sespie /*
66900bf4279Sespie 
67037c53322Sespie @deftypefn Replacement {const char*} strerrno (int @var{errnum})
67100bf4279Sespie 
67237c53322Sespie Given an error number returned from a system call (typically returned
67337c53322Sespie in @code{errno}), returns a pointer to a string containing the
67437c53322Sespie symbolic name of that error number, as found in @code{<errno.h>}.
67500bf4279Sespie 
67637c53322Sespie If the supplied error number is within the valid range of indices for
67737c53322Sespie symbolic names, but no name is available for the particular error
67837c53322Sespie number, then returns the string @samp{Error @var{num}}, where @var{num}
67937c53322Sespie is the error number.
68000bf4279Sespie 
68100bf4279Sespie If the supplied error number is not within the range of valid
68237c53322Sespie indices, then returns @code{NULL}.
68300bf4279Sespie 
68400bf4279Sespie The contents of the location pointed to are only guaranteed to be
68537c53322Sespie valid until the next call to @code{strerrno}.
68637c53322Sespie 
68737c53322Sespie @end deftypefn
68800bf4279Sespie 
68900bf4279Sespie */
69000bf4279Sespie 
69100bf4279Sespie const char *
strerrno(int errnoval)692150b7e42Smiod strerrno (int errnoval)
69300bf4279Sespie {
69400bf4279Sespie   const char *name;
69500bf4279Sespie   static char buf[32];
69600bf4279Sespie 
69700bf4279Sespie   if (error_names == NULL)
69800bf4279Sespie     {
69900bf4279Sespie       init_error_tables ();
70000bf4279Sespie     }
70100bf4279Sespie 
70200bf4279Sespie   if ((errnoval < 0) || (errnoval >= num_error_names))
70300bf4279Sespie     {
70400bf4279Sespie #ifdef EVMSERR
70500bf4279Sespie       if (errnoval == evmserr.value)
70600bf4279Sespie 	name = evmserr.name;
70700bf4279Sespie       else
70800bf4279Sespie #endif
70900bf4279Sespie       /* Out of range, just return NULL */
71000bf4279Sespie       name = NULL;
71100bf4279Sespie     }
71200bf4279Sespie   else if ((error_names == NULL) || (error_names[errnoval] == NULL))
71300bf4279Sespie     {
71400bf4279Sespie       /* In range, but no error_names or no entry at this index. */
715*c404a200Smiod       snprintf (buf, sizeof buf, "Error %d", errnoval);
71600bf4279Sespie       name = (const char *) buf;
71700bf4279Sespie     }
71800bf4279Sespie   else
71900bf4279Sespie     {
72000bf4279Sespie       /* In range, and a valid name.  Just return the name. */
72100bf4279Sespie       name = error_names[errnoval];
72200bf4279Sespie     }
72300bf4279Sespie 
72400bf4279Sespie   return (name);
72500bf4279Sespie }
72600bf4279Sespie 
72700bf4279Sespie /*
72800bf4279Sespie 
72937c53322Sespie @deftypefn Extension int strtoerrno (const char *@var{name})
73000bf4279Sespie 
73137c53322Sespie Given the symbolic name of a error number (e.g., @code{EACCES}), map it
73237c53322Sespie to an errno value.  If no translation is found, returns 0.
73300bf4279Sespie 
73437c53322Sespie @end deftypefn
73500bf4279Sespie 
73600bf4279Sespie */
73700bf4279Sespie 
73800bf4279Sespie int
strtoerrno(const char * name)739150b7e42Smiod strtoerrno (const char *name)
74000bf4279Sespie {
74100bf4279Sespie   int errnoval = 0;
74200bf4279Sespie 
74300bf4279Sespie   if (name != NULL)
74400bf4279Sespie     {
74500bf4279Sespie       if (error_names == NULL)
74600bf4279Sespie 	{
74700bf4279Sespie 	  init_error_tables ();
74800bf4279Sespie 	}
74900bf4279Sespie       for (errnoval = 0; errnoval < num_error_names; errnoval++)
75000bf4279Sespie 	{
75100bf4279Sespie 	  if ((error_names[errnoval] != NULL) &&
75200bf4279Sespie 	      (strcmp (name, error_names[errnoval]) == 0))
75300bf4279Sespie 	    {
75400bf4279Sespie 	      break;
75500bf4279Sespie 	    }
75600bf4279Sespie 	}
75700bf4279Sespie       if (errnoval == num_error_names)
75800bf4279Sespie 	{
75900bf4279Sespie #ifdef EVMSERR
76000bf4279Sespie 	  if (strcmp (name, evmserr.name) == 0)
76100bf4279Sespie 	    errnoval = evmserr.value;
76200bf4279Sespie 	  else
76300bf4279Sespie #endif
76400bf4279Sespie 	  errnoval = 0;
76500bf4279Sespie 	}
76600bf4279Sespie     }
76700bf4279Sespie   return (errnoval);
76800bf4279Sespie }
76900bf4279Sespie 
77000bf4279Sespie 
77100bf4279Sespie /* A simple little main that does nothing but print all the errno translations
77200bf4279Sespie    if MAIN is defined and this file is compiled and linked. */
77300bf4279Sespie 
77400bf4279Sespie #ifdef MAIN
77500bf4279Sespie 
77600bf4279Sespie #include <stdio.h>
77700bf4279Sespie 
77800bf4279Sespie int
main(void)779150b7e42Smiod main (void)
78000bf4279Sespie {
78100bf4279Sespie   int errn;
78200bf4279Sespie   int errnmax;
78300bf4279Sespie   const char *name;
78437c53322Sespie   const char *msg;
78500bf4279Sespie   char *strerror ();
78600bf4279Sespie 
78700bf4279Sespie   errnmax = errno_max ();
78800bf4279Sespie   printf ("%d entries in names table.\n", num_error_names);
78900bf4279Sespie   printf ("%d entries in messages table.\n", sys_nerr);
79000bf4279Sespie   printf ("%d is max useful index.\n", errnmax);
79100bf4279Sespie 
79200bf4279Sespie   /* Keep printing values until we get to the end of *both* tables, not
79300bf4279Sespie      *either* table.  Note that knowing the maximum useful index does *not*
79400bf4279Sespie      relieve us of the responsibility of testing the return pointer for
79500bf4279Sespie      NULL. */
79600bf4279Sespie 
79700bf4279Sespie   for (errn = 0; errn <= errnmax; errn++)
79800bf4279Sespie     {
79900bf4279Sespie       name = strerrno (errn);
80000bf4279Sespie       name = (name == NULL) ? "<NULL>" : name;
80100bf4279Sespie       msg = strerror (errn);
80200bf4279Sespie       msg = (msg == NULL) ? "<NULL>" : msg;
80300bf4279Sespie       printf ("%-4d%-18s%s\n", errn, name, msg);
80400bf4279Sespie     }
80500bf4279Sespie 
80600bf4279Sespie   return 0;
80700bf4279Sespie }
80800bf4279Sespie 
80900bf4279Sespie #endif
810