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