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