Home | History | Annotate | Line # | Download | only in libiberty
strerror.c revision 1.6
      1  1.1  christos /* Extended support for using errno values.
      2  1.1  christos    Written by Fred Fish.  fnf (at) cygnus.com
      3  1.1  christos    This file is in the public domain.  --Per Bothner.  */
      4  1.1  christos 
      5  1.1  christos #include "config.h"
      6  1.1  christos 
      7  1.1  christos #ifdef HAVE_SYS_ERRLIST
      8  1.1  christos /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
      9  1.1  christos    might declare sys_errlist in a way that the compiler might consider
     10  1.1  christos    incompatible with our later declaration, perhaps by using const
     11  1.1  christos    attributes.  So we hide the declaration in errno.h (if any) using a
     12  1.1  christos    macro. */
     13  1.1  christos #define sys_nerr sys_nerr__
     14  1.1  christos #define sys_errlist sys_errlist__
     15  1.1  christos #endif
     16  1.1  christos 
     17  1.1  christos #include "ansidecl.h"
     18  1.1  christos #include "libiberty.h"
     19  1.1  christos 
     20  1.1  christos #include <stdio.h>
     21  1.1  christos #include <errno.h>
     22  1.1  christos 
     23  1.1  christos #ifdef HAVE_SYS_ERRLIST
     24  1.1  christos #undef sys_nerr
     25  1.1  christos #undef sys_errlist
     26  1.1  christos #endif
     27  1.1  christos 
     28  1.1  christos /*  Routines imported from standard C runtime libraries. */
     29  1.1  christos 
     30  1.1  christos #ifdef HAVE_STDLIB_H
     31  1.1  christos #include <stdlib.h>
     32  1.1  christos #else
     33  1.1  christos extern PTR malloc ();
     34  1.1  christos #endif
     35  1.1  christos 
     36  1.1  christos #ifdef HAVE_STRING_H
     37  1.1  christos #include <string.h>
     38  1.1  christos #else
     39  1.1  christos extern PTR memset ();
     40  1.1  christos #endif
     41  1.1  christos 
     42  1.1  christos #ifndef MAX
     43  1.1  christos #  define MAX(a,b) ((a) > (b) ? (a) : (b))
     44  1.1  christos #endif
     45  1.1  christos 
     46  1.1  christos static void init_error_tables (void);
     47  1.1  christos 
     48  1.1  christos /* Translation table for errno values.  See intro(2) in most UNIX systems
     49  1.1  christos    Programmers Reference Manuals.
     50  1.1  christos 
     51  1.1  christos    Note that this table is generally only accessed when it is used at runtime
     52  1.1  christos    to initialize errno name and message tables that are indexed by errno
     53  1.1  christos    value.
     54  1.1  christos 
     55  1.1  christos    Not all of these errnos will exist on all systems.  This table is the only
     56  1.1  christos    thing that should have to be updated as new error numbers are introduced.
     57  1.1  christos    It's sort of ugly, but at least its portable. */
     58  1.1  christos 
     59  1.1  christos struct error_info
     60  1.1  christos {
     61  1.1  christos   const int value;		/* The numeric value from <errno.h> */
     62  1.1  christos   const char *const name;	/* The equivalent symbolic value */
     63  1.1  christos #ifndef HAVE_SYS_ERRLIST
     64  1.1  christos   const char *const msg;	/* Short message about this value */
     65  1.1  christos #endif
     66  1.1  christos };
     67  1.1  christos 
     68  1.1  christos #ifndef HAVE_SYS_ERRLIST
     69  1.1  christos #   define ENTRY(value, name, msg)	{value, name, msg}
     70  1.1  christos #else
     71  1.1  christos #   define ENTRY(value, name, msg)	{value, name}
     72  1.1  christos #endif
     73  1.1  christos 
     74  1.1  christos static const struct error_info error_table[] =
     75  1.1  christos {
     76  1.1  christos #if defined (EPERM)
     77  1.1  christos   ENTRY(EPERM, "EPERM", "Not owner"),
     78  1.1  christos #endif
     79  1.1  christos #if defined (ENOENT)
     80  1.1  christos   ENTRY(ENOENT, "ENOENT", "No such file or directory"),
     81  1.1  christos #endif
     82  1.1  christos #if defined (ESRCH)
     83  1.1  christos   ENTRY(ESRCH, "ESRCH", "No such process"),
     84  1.1  christos #endif
     85  1.1  christos #if defined (EINTR)
     86  1.1  christos   ENTRY(EINTR, "EINTR", "Interrupted system call"),
     87  1.1  christos #endif
     88  1.1  christos #if defined (EIO)
     89  1.1  christos   ENTRY(EIO, "EIO", "I/O error"),
     90  1.1  christos #endif
     91  1.1  christos #if defined (ENXIO)
     92  1.1  christos   ENTRY(ENXIO, "ENXIO", "No such device or address"),
     93  1.1  christos #endif
     94  1.1  christos #if defined (E2BIG)
     95  1.1  christos   ENTRY(E2BIG, "E2BIG", "Arg list too long"),
     96  1.1  christos #endif
     97  1.1  christos #if defined (ENOEXEC)
     98  1.1  christos   ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
     99  1.1  christos #endif
    100  1.1  christos #if defined (EBADF)
    101  1.1  christos   ENTRY(EBADF, "EBADF", "Bad file number"),
    102  1.1  christos #endif
    103  1.1  christos #if defined (ECHILD)
    104  1.1  christos   ENTRY(ECHILD, "ECHILD", "No child processes"),
    105  1.1  christos #endif
    106  1.1  christos #if defined (EWOULDBLOCK)	/* Put before EAGAIN, sometimes aliased */
    107  1.1  christos   ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
    108  1.1  christos #endif
    109  1.1  christos #if defined (EAGAIN)
    110  1.1  christos   ENTRY(EAGAIN, "EAGAIN", "No more processes"),
    111  1.1  christos #endif
    112  1.1  christos #if defined (ENOMEM)
    113  1.1  christos   ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
    114  1.1  christos #endif
    115  1.1  christos #if defined (EACCES)
    116  1.1  christos   ENTRY(EACCES, "EACCES", "Permission denied"),
    117  1.1  christos #endif
    118  1.1  christos #if defined (EFAULT)
    119  1.1  christos   ENTRY(EFAULT, "EFAULT", "Bad address"),
    120  1.1  christos #endif
    121  1.1  christos #if defined (ENOTBLK)
    122  1.1  christos   ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
    123  1.1  christos #endif
    124  1.1  christos #if defined (EBUSY)
    125  1.1  christos   ENTRY(EBUSY, "EBUSY", "Device busy"),
    126  1.1  christos #endif
    127  1.1  christos #if defined (EEXIST)
    128  1.1  christos   ENTRY(EEXIST, "EEXIST", "File exists"),
    129  1.1  christos #endif
    130  1.1  christos #if defined (EXDEV)
    131  1.1  christos   ENTRY(EXDEV, "EXDEV", "Cross-device link"),
    132  1.1  christos #endif
    133  1.1  christos #if defined (ENODEV)
    134  1.1  christos   ENTRY(ENODEV, "ENODEV", "No such device"),
    135  1.1  christos #endif
    136  1.1  christos #if defined (ENOTDIR)
    137  1.1  christos   ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
    138  1.1  christos #endif
    139  1.1  christos #if defined (EISDIR)
    140  1.1  christos   ENTRY(EISDIR, "EISDIR", "Is a directory"),
    141  1.1  christos #endif
    142  1.1  christos #if defined (EINVAL)
    143  1.1  christos   ENTRY(EINVAL, "EINVAL", "Invalid argument"),
    144  1.1  christos #endif
    145  1.1  christos #if defined (ENFILE)
    146  1.1  christos   ENTRY(ENFILE, "ENFILE", "File table overflow"),
    147  1.1  christos #endif
    148  1.1  christos #if defined (EMFILE)
    149  1.1  christos   ENTRY(EMFILE, "EMFILE", "Too many open files"),
    150  1.1  christos #endif
    151  1.1  christos #if defined (ENOTTY)
    152  1.1  christos   ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
    153  1.1  christos #endif
    154  1.1  christos #if defined (ETXTBSY)
    155  1.1  christos   ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
    156  1.1  christos #endif
    157  1.1  christos #if defined (EFBIG)
    158  1.1  christos   ENTRY(EFBIG, "EFBIG", "File too large"),
    159  1.1  christos #endif
    160  1.1  christos #if defined (ENOSPC)
    161  1.1  christos   ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
    162  1.1  christos #endif
    163  1.1  christos #if defined (ESPIPE)
    164  1.1  christos   ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
    165  1.1  christos #endif
    166  1.1  christos #if defined (EROFS)
    167  1.1  christos   ENTRY(EROFS, "EROFS", "Read-only file system"),
    168  1.1  christos #endif
    169  1.1  christos #if defined (EMLINK)
    170  1.1  christos   ENTRY(EMLINK, "EMLINK", "Too many links"),
    171  1.1  christos #endif
    172  1.1  christos #if defined (EPIPE)
    173  1.1  christos   ENTRY(EPIPE, "EPIPE", "Broken pipe"),
    174  1.1  christos #endif
    175  1.1  christos #if defined (EDOM)
    176  1.1  christos   ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
    177  1.1  christos #endif
    178  1.1  christos #if defined (ERANGE)
    179  1.1  christos   ENTRY(ERANGE, "ERANGE", "Math result not representable"),
    180  1.1  christos #endif
    181  1.1  christos #if defined (ENOMSG)
    182  1.1  christos   ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
    183  1.1  christos #endif
    184  1.1  christos #if defined (EIDRM)
    185  1.1  christos   ENTRY(EIDRM, "EIDRM", "Identifier removed"),
    186  1.1  christos #endif
    187  1.1  christos #if defined (ECHRNG)
    188  1.1  christos   ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
    189  1.1  christos #endif
    190  1.1  christos #if defined (EL2NSYNC)
    191  1.1  christos   ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
    192  1.1  christos #endif
    193  1.1  christos #if defined (EL3HLT)
    194  1.1  christos   ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
    195  1.1  christos #endif
    196  1.1  christos #if defined (EL3RST)
    197  1.1  christos   ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
    198  1.1  christos #endif
    199  1.1  christos #if defined (ELNRNG)
    200  1.1  christos   ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
    201  1.1  christos #endif
    202  1.1  christos #if defined (EUNATCH)
    203  1.1  christos   ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
    204  1.1  christos #endif
    205  1.1  christos #if defined (ENOCSI)
    206  1.1  christos   ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
    207  1.1  christos #endif
    208  1.1  christos #if defined (EL2HLT)
    209  1.1  christos   ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
    210  1.1  christos #endif
    211  1.1  christos #if defined (EDEADLK)
    212  1.1  christos   ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
    213  1.1  christos #endif
    214  1.1  christos #if defined (ENOLCK)
    215  1.1  christos   ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
    216  1.1  christos #endif
    217  1.1  christos #if defined (EBADE)
    218  1.1  christos   ENTRY(EBADE, "EBADE", "Invalid exchange"),
    219  1.1  christos #endif
    220  1.1  christos #if defined (EBADR)
    221  1.1  christos   ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
    222  1.1  christos #endif
    223  1.1  christos #if defined (EXFULL)
    224  1.1  christos   ENTRY(EXFULL, "EXFULL", "Exchange full"),
    225  1.1  christos #endif
    226  1.1  christos #if defined (ENOANO)
    227  1.1  christos   ENTRY(ENOANO, "ENOANO", "No anode"),
    228  1.1  christos #endif
    229  1.1  christos #if defined (EBADRQC)
    230  1.1  christos   ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
    231  1.1  christos #endif
    232  1.1  christos #if defined (EBADSLT)
    233  1.1  christos   ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
    234  1.1  christos #endif
    235  1.1  christos #if defined (EDEADLOCK)
    236  1.1  christos   ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
    237  1.1  christos #endif
    238  1.1  christos #if defined (EBFONT)
    239  1.1  christos   ENTRY(EBFONT, "EBFONT", "Bad font file format"),
    240  1.1  christos #endif
    241  1.1  christos #if defined (ENOSTR)
    242  1.1  christos   ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
    243  1.1  christos #endif
    244  1.1  christos #if defined (ENODATA)
    245  1.1  christos   ENTRY(ENODATA, "ENODATA", "No data available"),
    246  1.1  christos #endif
    247  1.1  christos #if defined (ETIME)
    248  1.1  christos   ENTRY(ETIME, "ETIME", "Timer expired"),
    249  1.1  christos #endif
    250  1.1  christos #if defined (ENOSR)
    251  1.1  christos   ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
    252  1.1  christos #endif
    253  1.1  christos #if defined (ENONET)
    254  1.1  christos   ENTRY(ENONET, "ENONET", "Machine is not on the network"),
    255  1.1  christos #endif
    256  1.1  christos #if defined (ENOPKG)
    257  1.1  christos   ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
    258  1.1  christos #endif
    259  1.1  christos #if defined (EREMOTE)
    260  1.1  christos   ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
    261  1.1  christos #endif
    262  1.1  christos #if defined (ENOLINK)
    263  1.1  christos   ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
    264  1.1  christos #endif
    265  1.1  christos #if defined (EADV)
    266  1.1  christos   ENTRY(EADV, "EADV", "Advertise error"),
    267  1.1  christos #endif
    268  1.1  christos #if defined (ESRMNT)
    269  1.1  christos   ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
    270  1.1  christos #endif
    271  1.1  christos #if defined (ECOMM)
    272  1.1  christos   ENTRY(ECOMM, "ECOMM", "Communication error on send"),
    273  1.1  christos #endif
    274  1.1  christos #if defined (EPROTO)
    275  1.1  christos   ENTRY(EPROTO, "EPROTO", "Protocol error"),
    276  1.1  christos #endif
    277  1.1  christos #if defined (EMULTIHOP)
    278  1.1  christos   ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
    279  1.1  christos #endif
    280  1.1  christos #if defined (EDOTDOT)
    281  1.1  christos   ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
    282  1.1  christos #endif
    283  1.1  christos #if defined (EBADMSG)
    284  1.1  christos   ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
    285  1.1  christos #endif
    286  1.1  christos #if defined (ENAMETOOLONG)
    287  1.1  christos   ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
    288  1.1  christos #endif
    289  1.1  christos #if defined (EOVERFLOW)
    290  1.1  christos   ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
    291  1.1  christos #endif
    292  1.1  christos #if defined (ENOTUNIQ)
    293  1.1  christos   ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
    294  1.1  christos #endif
    295  1.1  christos #if defined (EBADFD)
    296  1.1  christos   ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
    297  1.1  christos #endif
    298  1.1  christos #if defined (EREMCHG)
    299  1.1  christos   ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
    300  1.1  christos #endif
    301  1.1  christos #if defined (ELIBACC)
    302  1.6  christos   ENTRY(ELIBACC, "ELIBACC", "Cannot access a needed shared library"),
    303  1.1  christos #endif
    304  1.1  christos #if defined (ELIBBAD)
    305  1.1  christos   ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
    306  1.1  christos #endif
    307  1.1  christos #if defined (ELIBSCN)
    308  1.1  christos   ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
    309  1.1  christos #endif
    310  1.1  christos #if defined (ELIBMAX)
    311  1.1  christos   ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
    312  1.1  christos #endif
    313  1.1  christos #if defined (ELIBEXEC)
    314  1.1  christos   ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
    315  1.1  christos #endif
    316  1.1  christos #if defined (EILSEQ)
    317  1.1  christos   ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
    318  1.1  christos #endif
    319  1.1  christos #if defined (ENOSYS)
    320  1.1  christos   ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
    321  1.1  christos #endif
    322  1.1  christos #if defined (ELOOP)
    323  1.1  christos   ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
    324  1.1  christos #endif
    325  1.1  christos #if defined (ERESTART)
    326  1.1  christos   ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
    327  1.1  christos #endif
    328  1.1  christos #if defined (ESTRPIPE)
    329  1.1  christos   ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
    330  1.1  christos #endif
    331  1.1  christos #if defined (ENOTEMPTY)
    332  1.1  christos   ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
    333  1.1  christos #endif
    334  1.1  christos #if defined (EUSERS)
    335  1.1  christos   ENTRY(EUSERS, "EUSERS", "Too many users"),
    336  1.1  christos #endif
    337  1.1  christos #if defined (ENOTSOCK)
    338  1.1  christos   ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
    339  1.1  christos #endif
    340  1.1  christos #if defined (EDESTADDRREQ)
    341  1.1  christos   ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
    342  1.1  christos #endif
    343  1.1  christos #if defined (EMSGSIZE)
    344  1.1  christos   ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
    345  1.1  christos #endif
    346  1.1  christos #if defined (EPROTOTYPE)
    347  1.1  christos   ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
    348  1.1  christos #endif
    349  1.1  christos #if defined (ENOPROTOOPT)
    350  1.1  christos   ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol option not available"),
    351  1.1  christos #endif
    352  1.1  christos #if defined (EPROTONOSUPPORT)
    353  1.1  christos   ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
    354  1.1  christos #endif
    355  1.1  christos #if defined (ESOCKTNOSUPPORT)
    356  1.1  christos   ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
    357  1.1  christos #endif
    358  1.1  christos #if defined (EOPNOTSUPP)
    359  1.1  christos   ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
    360  1.1  christos #endif
    361  1.1  christos #if defined (EPFNOSUPPORT)
    362  1.1  christos   ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
    363  1.1  christos #endif
    364  1.1  christos #if defined (EAFNOSUPPORT)
    365  1.1  christos   ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
    366  1.1  christos #endif
    367  1.1  christos #if defined (EADDRINUSE)
    368  1.1  christos   ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
    369  1.1  christos #endif
    370  1.1  christos #if defined (EADDRNOTAVAIL)
    371  1.1  christos   ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
    372  1.1  christos #endif
    373  1.1  christos #if defined (ENETDOWN)
    374  1.1  christos   ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
    375  1.1  christos #endif
    376  1.1  christos #if defined (ENETUNREACH)
    377  1.1  christos   ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
    378  1.1  christos #endif
    379  1.1  christos #if defined (ENETRESET)
    380  1.1  christos   ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
    381  1.1  christos #endif
    382  1.1  christos #if defined (ECONNABORTED)
    383  1.1  christos   ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
    384  1.1  christos #endif
    385  1.1  christos #if defined (ECONNRESET)
    386  1.1  christos   ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
    387  1.1  christos #endif
    388  1.1  christos #if defined (ENOBUFS)
    389  1.1  christos   ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
    390  1.1  christos #endif
    391  1.1  christos #if defined (EISCONN)
    392  1.1  christos   ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
    393  1.1  christos #endif
    394  1.1  christos #if defined (ENOTCONN)
    395  1.1  christos   ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
    396  1.1  christos #endif
    397  1.1  christos #if defined (ESHUTDOWN)
    398  1.1  christos   ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
    399  1.1  christos #endif
    400  1.1  christos #if defined (ETOOMANYREFS)
    401  1.1  christos   ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
    402  1.1  christos #endif
    403  1.1  christos #if defined (ETIMEDOUT)
    404  1.1  christos   ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
    405  1.1  christos #endif
    406  1.1  christos #if defined (ECONNREFUSED)
    407  1.1  christos   ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
    408  1.1  christos #endif
    409  1.1  christos #if defined (EHOSTDOWN)
    410  1.1  christos   ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
    411  1.1  christos #endif
    412  1.1  christos #if defined (EHOSTUNREACH)
    413  1.1  christos   ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
    414  1.1  christos #endif
    415  1.1  christos #if defined (EALREADY)
    416  1.1  christos   ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
    417  1.1  christos #endif
    418  1.1  christos #if defined (EINPROGRESS)
    419  1.1  christos   ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
    420  1.1  christos #endif
    421  1.1  christos #if defined (ESTALE)
    422  1.1  christos   ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
    423  1.1  christos #endif
    424  1.1  christos #if defined (EUCLEAN)
    425  1.1  christos   ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
    426  1.1  christos #endif
    427  1.1  christos #if defined (ENOTNAM)
    428  1.1  christos   ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
    429  1.1  christos #endif
    430  1.1  christos #if defined (ENAVAIL)
    431  1.1  christos   ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
    432  1.1  christos #endif
    433  1.1  christos #if defined (EISNAM)
    434  1.1  christos   ENTRY(EISNAM, "EISNAM", "Is a named type file"),
    435  1.1  christos #endif
    436  1.1  christos #if defined (EREMOTEIO)
    437  1.1  christos   ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
    438  1.1  christos #endif
    439  1.1  christos   ENTRY(0, NULL, NULL)
    440  1.1  christos };
    441  1.1  christos 
    442  1.1  christos #ifdef EVMSERR
    443  1.1  christos /* This is not in the table, because the numeric value of EVMSERR (32767)
    444  1.1  christos    lies outside the range of sys_errlist[].  */
    445  1.1  christos static struct { int value; const char *name, *msg; }
    446  1.1  christos   evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" };
    447  1.1  christos #endif
    448  1.1  christos 
    449  1.1  christos /* Translation table allocated and initialized at runtime.  Indexed by the
    450  1.1  christos    errno value to find the equivalent symbolic value. */
    451  1.1  christos 
    452  1.1  christos static const char **error_names;
    453  1.1  christos static int num_error_names = 0;
    454  1.1  christos 
    455  1.1  christos /* Translation table allocated and initialized at runtime, if it does not
    456  1.1  christos    already exist in the host environment.  Indexed by the errno value to find
    457  1.1  christos    the descriptive string.
    458  1.1  christos 
    459  1.1  christos    We don't export it for use in other modules because even though it has the
    460  1.1  christos    same name, it differs from other implementations in that it is dynamically
    461  1.1  christos    initialized rather than statically initialized. */
    462  1.1  christos 
    463  1.1  christos #ifndef HAVE_SYS_ERRLIST
    464  1.1  christos 
    465  1.1  christos #define sys_nerr sys_nerr__
    466  1.1  christos #define sys_errlist sys_errlist__
    467  1.1  christos static int sys_nerr;
    468  1.1  christos static const char **sys_errlist;
    469  1.1  christos 
    470  1.1  christos #else
    471  1.1  christos 
    472  1.3  christos 
    473  1.3  christos #ifndef sys_nerr
    474  1.1  christos extern int sys_nerr;
    475  1.3  christos #endif
    476  1.3  christos #ifndef sys_errlist
    477  1.1  christos extern char *sys_errlist[];
    478  1.3  christos #endif
    479  1.1  christos 
    480  1.1  christos #endif
    481  1.1  christos 
    482  1.1  christos /*
    483  1.1  christos 
    484  1.1  christos NAME
    485  1.1  christos 
    486  1.1  christos 	init_error_tables -- initialize the name and message tables
    487  1.1  christos 
    488  1.1  christos SYNOPSIS
    489  1.1  christos 
    490  1.1  christos 	static void init_error_tables ();
    491  1.1  christos 
    492  1.1  christos DESCRIPTION
    493  1.1  christos 
    494  1.1  christos 	Using the error_table, which is initialized at compile time, generate
    495  1.1  christos 	the error_names and the sys_errlist (if needed) tables, which are
    496  1.1  christos 	indexed at runtime by a specific errno value.
    497  1.1  christos 
    498  1.1  christos BUGS
    499  1.1  christos 
    500  1.1  christos 	The initialization of the tables may fail under low memory conditions,
    501  1.1  christos 	in which case we don't do anything particularly useful, but we don't
    502  1.1  christos 	bomb either.  Who knows, it might succeed at a later point if we free
    503  1.1  christos 	some memory in the meantime.  In any case, the other routines know
    504  1.1  christos 	how to deal with lack of a table after trying to initialize it.  This
    505  1.1  christos 	may or may not be considered to be a bug, that we don't specifically
    506  1.1  christos 	warn about this particular failure mode.
    507  1.1  christos 
    508  1.1  christos */
    509  1.1  christos 
    510  1.1  christos static void
    511  1.1  christos init_error_tables (void)
    512  1.1  christos {
    513  1.1  christos   const struct error_info *eip;
    514  1.1  christos   int nbytes;
    515  1.1  christos 
    516  1.1  christos   /* If we haven't already scanned the error_table once to find the maximum
    517  1.1  christos      errno value, then go find it now. */
    518  1.1  christos 
    519  1.1  christos   if (num_error_names == 0)
    520  1.1  christos     {
    521  1.1  christos       for (eip = error_table; eip -> name != NULL; eip++)
    522  1.1  christos 	{
    523  1.1  christos 	  if (eip -> value >= num_error_names)
    524  1.1  christos 	    {
    525  1.1  christos 	      num_error_names = eip -> value + 1;
    526  1.1  christos 	    }
    527  1.1  christos 	}
    528  1.1  christos     }
    529  1.1  christos 
    530  1.1  christos   /* Now attempt to allocate the error_names table, zero it out, and then
    531  1.1  christos      initialize it from the statically initialized error_table. */
    532  1.1  christos 
    533  1.1  christos   if (error_names == NULL)
    534  1.1  christos     {
    535  1.1  christos       nbytes = num_error_names * sizeof (char *);
    536  1.1  christos       if ((error_names = (const char **) malloc (nbytes)) != NULL)
    537  1.1  christos 	{
    538  1.1  christos 	  memset (error_names, 0, nbytes);
    539  1.1  christos 	  for (eip = error_table; eip -> name != NULL; eip++)
    540  1.1  christos 	    {
    541  1.1  christos 	      error_names[eip -> value] = eip -> name;
    542  1.1  christos 	    }
    543  1.1  christos 	}
    544  1.1  christos     }
    545  1.1  christos 
    546  1.1  christos #ifndef HAVE_SYS_ERRLIST
    547  1.1  christos 
    548  1.1  christos   /* Now attempt to allocate the sys_errlist table, zero it out, and then
    549  1.1  christos      initialize it from the statically initialized error_table. */
    550  1.1  christos 
    551  1.1  christos   if (sys_errlist == NULL)
    552  1.1  christos     {
    553  1.1  christos       nbytes = num_error_names * sizeof (char *);
    554  1.1  christos       if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
    555  1.1  christos 	{
    556  1.1  christos 	  memset (sys_errlist, 0, nbytes);
    557  1.1  christos 	  sys_nerr = num_error_names;
    558  1.1  christos 	  for (eip = error_table; eip -> name != NULL; eip++)
    559  1.1  christos 	    {
    560  1.1  christos 	      sys_errlist[eip -> value] = eip -> msg;
    561  1.1  christos 	    }
    562  1.1  christos 	}
    563  1.1  christos     }
    564  1.1  christos 
    565  1.1  christos #endif
    566  1.1  christos 
    567  1.1  christos }
    568  1.1  christos 
    569  1.1  christos /*
    570  1.1  christos 
    571  1.1  christos 
    572  1.1  christos @deftypefn Extension int errno_max (void)
    573  1.1  christos 
    574  1.1  christos Returns the maximum @code{errno} value for which a corresponding
    575  1.1  christos symbolic name or message is available.  Note that in the case where we
    576  1.1  christos use the @code{sys_errlist} supplied by the system, it is possible for
    577  1.1  christos there to be more symbolic names than messages, or vice versa.  In
    578  1.1  christos fact, the manual page for @code{perror(3C)} explicitly warns that one
    579  1.1  christos should check the size of the table (@code{sys_nerr}) before indexing
    580  1.1  christos it, since new error codes may be added to the system before they are
    581  1.1  christos added to the table.  Thus @code{sys_nerr} might be smaller than value
    582  1.1  christos implied by the largest @code{errno} value defined in @code{<errno.h>}.
    583  1.1  christos 
    584  1.1  christos We return the maximum value that can be used to obtain a meaningful
    585  1.1  christos symbolic name or message.
    586  1.1  christos 
    587  1.1  christos @end deftypefn
    588  1.1  christos 
    589  1.1  christos */
    590  1.1  christos 
    591  1.1  christos int
    592  1.1  christos errno_max (void)
    593  1.1  christos {
    594  1.1  christos   int maxsize;
    595  1.1  christos 
    596  1.1  christos   if (error_names == NULL)
    597  1.1  christos     {
    598  1.1  christos       init_error_tables ();
    599  1.1  christos     }
    600  1.1  christos   maxsize = MAX (sys_nerr, num_error_names);
    601  1.1  christos   return (maxsize - 1);
    602  1.1  christos }
    603  1.1  christos 
    604  1.1  christos #ifndef HAVE_STRERROR
    605  1.1  christos 
    606  1.1  christos /*
    607  1.1  christos 
    608  1.1  christos @deftypefn Supplemental char* strerror (int @var{errnoval})
    609  1.1  christos 
    610  1.1  christos Maps an @code{errno} number to an error message string, the contents
    611  1.1  christos of which are implementation defined.  On systems which have the
    612  1.1  christos external variables @code{sys_nerr} and @code{sys_errlist}, these
    613  1.1  christos strings will be the same as the ones used by @code{perror}.
    614  1.1  christos 
    615  1.1  christos If the supplied error number is within the valid range of indices for
    616  1.1  christos the @code{sys_errlist}, but no message is available for the particular
    617  1.1  christos error number, then returns the string @samp{Error @var{num}}, where
    618  1.1  christos @var{num} is the error number.
    619  1.1  christos 
    620  1.1  christos If the supplied error number is not a valid index into
    621  1.1  christos @code{sys_errlist}, returns @code{NULL}.
    622  1.1  christos 
    623  1.1  christos The returned string is only guaranteed to be valid only until the
    624  1.1  christos next call to @code{strerror}.
    625  1.1  christos 
    626  1.1  christos @end deftypefn
    627  1.1  christos 
    628  1.1  christos */
    629  1.1  christos 
    630  1.1  christos char *
    631  1.1  christos strerror (int errnoval)
    632  1.1  christos {
    633  1.1  christos   const char *msg;
    634  1.1  christos   static char buf[32];
    635  1.1  christos 
    636  1.1  christos #ifndef HAVE_SYS_ERRLIST
    637  1.1  christos 
    638  1.1  christos   if (error_names == NULL)
    639  1.1  christos     {
    640  1.1  christos       init_error_tables ();
    641  1.1  christos     }
    642  1.1  christos 
    643  1.1  christos #endif
    644  1.1  christos 
    645  1.1  christos   if ((errnoval < 0) || (errnoval >= sys_nerr))
    646  1.1  christos     {
    647  1.1  christos #ifdef EVMSERR
    648  1.1  christos       if (errnoval == evmserr.value)
    649  1.1  christos 	msg = evmserr.msg;
    650  1.1  christos       else
    651  1.1  christos #endif
    652  1.1  christos       /* Out of range, just return NULL */
    653  1.1  christos       msg = NULL;
    654  1.1  christos     }
    655  1.1  christos   else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
    656  1.1  christos     {
    657  1.1  christos       /* In range, but no sys_errlist or no entry at this index. */
    658  1.1  christos       sprintf (buf, "Error %d", errnoval);
    659  1.1  christos       msg = buf;
    660  1.1  christos     }
    661  1.1  christos   else
    662  1.1  christos     {
    663  1.1  christos       /* In range, and a valid message.  Just return the message. */
    664  1.1  christos       msg = (char *) sys_errlist[errnoval];
    665  1.1  christos     }
    666  1.1  christos 
    667  1.1  christos   return (msg);
    668  1.1  christos }
    669  1.1  christos 
    670  1.1  christos #endif	/* ! HAVE_STRERROR */
    671  1.1  christos 
    672  1.1  christos 
    673  1.1  christos /*
    674  1.1  christos 
    675  1.1  christos @deftypefn Replacement {const char*} strerrno (int @var{errnum})
    676  1.1  christos 
    677  1.1  christos Given an error number returned from a system call (typically returned
    678  1.1  christos in @code{errno}), returns a pointer to a string containing the
    679  1.1  christos symbolic name of that error number, as found in @code{<errno.h>}.
    680  1.1  christos 
    681  1.1  christos If the supplied error number is within the valid range of indices for
    682  1.1  christos symbolic names, but no name is available for the particular error
    683  1.1  christos number, then returns the string @samp{Error @var{num}}, where @var{num}
    684  1.1  christos is the error number.
    685  1.1  christos 
    686  1.1  christos If the supplied error number is not within the range of valid
    687  1.1  christos indices, then returns @code{NULL}.
    688  1.1  christos 
    689  1.1  christos The contents of the location pointed to are only guaranteed to be
    690  1.1  christos valid until the next call to @code{strerrno}.
    691  1.1  christos 
    692  1.1  christos @end deftypefn
    693  1.1  christos 
    694  1.1  christos */
    695  1.1  christos 
    696  1.1  christos const char *
    697  1.1  christos strerrno (int errnoval)
    698  1.1  christos {
    699  1.1  christos   const char *name;
    700  1.1  christos   static char buf[32];
    701  1.1  christos 
    702  1.1  christos   if (error_names == NULL)
    703  1.1  christos     {
    704  1.1  christos       init_error_tables ();
    705  1.1  christos     }
    706  1.1  christos 
    707  1.1  christos   if ((errnoval < 0) || (errnoval >= num_error_names))
    708  1.1  christos     {
    709  1.1  christos #ifdef EVMSERR
    710  1.1  christos       if (errnoval == evmserr.value)
    711  1.1  christos 	name = evmserr.name;
    712  1.1  christos       else
    713  1.1  christos #endif
    714  1.1  christos       /* Out of range, just return NULL */
    715  1.1  christos       name = NULL;
    716  1.1  christos     }
    717  1.1  christos   else if ((error_names == NULL) || (error_names[errnoval] == NULL))
    718  1.1  christos     {
    719  1.1  christos       /* In range, but no error_names or no entry at this index. */
    720  1.1  christos       sprintf (buf, "Error %d", errnoval);
    721  1.1  christos       name = (const char *) buf;
    722  1.1  christos     }
    723  1.1  christos   else
    724  1.1  christos     {
    725  1.1  christos       /* In range, and a valid name.  Just return the name. */
    726  1.1  christos       name = error_names[errnoval];
    727  1.1  christos     }
    728  1.1  christos 
    729  1.1  christos   return (name);
    730  1.1  christos }
    731  1.1  christos 
    732  1.1  christos /*
    733  1.1  christos 
    734  1.1  christos @deftypefn Extension int strtoerrno (const char *@var{name})
    735  1.1  christos 
    736  1.1  christos Given the symbolic name of a error number (e.g., @code{EACCES}), map it
    737  1.1  christos to an errno value.  If no translation is found, returns 0.
    738  1.1  christos 
    739  1.1  christos @end deftypefn
    740  1.1  christos 
    741  1.1  christos */
    742  1.1  christos 
    743  1.1  christos int
    744  1.1  christos strtoerrno (const char *name)
    745  1.1  christos {
    746  1.1  christos   int errnoval = 0;
    747  1.1  christos 
    748  1.1  christos   if (name != NULL)
    749  1.1  christos     {
    750  1.1  christos       if (error_names == NULL)
    751  1.1  christos 	{
    752  1.1  christos 	  init_error_tables ();
    753  1.1  christos 	}
    754  1.1  christos       for (errnoval = 0; errnoval < num_error_names; errnoval++)
    755  1.1  christos 	{
    756  1.1  christos 	  if ((error_names[errnoval] != NULL) &&
    757  1.1  christos 	      (strcmp (name, error_names[errnoval]) == 0))
    758  1.1  christos 	    {
    759  1.1  christos 	      break;
    760  1.1  christos 	    }
    761  1.1  christos 	}
    762  1.1  christos       if (errnoval == num_error_names)
    763  1.1  christos 	{
    764  1.1  christos #ifdef EVMSERR
    765  1.1  christos 	  if (strcmp (name, evmserr.name) == 0)
    766  1.1  christos 	    errnoval = evmserr.value;
    767  1.1  christos 	  else
    768  1.1  christos #endif
    769  1.1  christos 	  errnoval = 0;
    770  1.1  christos 	}
    771  1.1  christos     }
    772  1.1  christos   return (errnoval);
    773  1.1  christos }
    774  1.1  christos 
    775  1.1  christos 
    776  1.1  christos /* A simple little main that does nothing but print all the errno translations
    777  1.1  christos    if MAIN is defined and this file is compiled and linked. */
    778  1.1  christos 
    779  1.1  christos #ifdef MAIN
    780  1.1  christos 
    781  1.1  christos #include <stdio.h>
    782  1.1  christos 
    783  1.1  christos int
    784  1.1  christos main (void)
    785  1.1  christos {
    786  1.1  christos   int errn;
    787  1.1  christos   int errnmax;
    788  1.1  christos   const char *name;
    789  1.1  christos   const char *msg;
    790  1.1  christos   char *strerror ();
    791  1.1  christos 
    792  1.1  christos   errnmax = errno_max ();
    793  1.1  christos   printf ("%d entries in names table.\n", num_error_names);
    794  1.1  christos   printf ("%d entries in messages table.\n", sys_nerr);
    795  1.1  christos   printf ("%d is max useful index.\n", errnmax);
    796  1.1  christos 
    797  1.1  christos   /* Keep printing values until we get to the end of *both* tables, not
    798  1.1  christos      *either* table.  Note that knowing the maximum useful index does *not*
    799  1.1  christos      relieve us of the responsibility of testing the return pointer for
    800  1.1  christos      NULL. */
    801  1.1  christos 
    802  1.1  christos   for (errn = 0; errn <= errnmax; errn++)
    803  1.1  christos     {
    804  1.1  christos       name = strerrno (errn);
    805  1.1  christos       name = (name == NULL) ? "<NULL>" : name;
    806  1.1  christos       msg = strerror (errn);
    807  1.1  christos       msg = (msg == NULL) ? "<NULL>" : msg;
    808  1.1  christos       printf ("%-4d%-18s%s\n", errn, name, msg);
    809  1.1  christos     }
    810  1.1  christos 
    811  1.1  christos   return 0;
    812  1.1  christos }
    813  1.1  christos 
    814  1.1  christos #endif
    815