1 /* Extended support for using errno values. 2 Copyright (C) 1992 Free Software Foundation, Inc. 3 Written by Fred Fish. fnf@cygnus.com 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 notdef 458 #ifdef NEED_sys_errlist 459 460 static int sys_nerr; 461 static char **sys_errlist; 462 463 #else 464 465 extern int sys_nerr; 466 extern char *sys_errlist[]; 467 468 #endif 469 #endif 470 471 472 /* 473 474 NAME 475 476 init_error_tables -- initialize the name and message tables 477 478 SYNOPSIS 479 480 static void init_error_tables (); 481 482 DESCRIPTION 483 484 Using the error_table, which is initialized at compile time, generate 485 the error_names and the sys_errlist (if needed) tables, which are 486 indexed at runtime by a specific errno value. 487 488 BUGS 489 490 The initialization of the tables may fail under low memory conditions, 491 in which case we don't do anything particularly useful, but we don't 492 bomb either. Who knows, it might succeed at a later point if we free 493 some memory in the meantime. In any case, the other routines know 494 how to deal with lack of a table after trying to initialize it. This 495 may or may not be considered to be a bug, that we don't specifically 496 warn about this particular failure mode. 497 498 */ 499 500 static void 501 init_error_tables () 502 { 503 struct error_info *eip; 504 int nbytes; 505 506 /* If we haven't already scanned the error_table once to find the maximum 507 errno value, then go find it now. */ 508 509 if (num_error_names == 0) 510 { 511 for (eip = error_table; eip -> name != NULL; eip++) 512 { 513 if (eip -> value >= num_error_names) 514 { 515 num_error_names = eip -> value + 1; 516 } 517 } 518 } 519 520 /* Now attempt to allocate the error_names table, zero it out, and then 521 initialize it from the statically initialized error_table. */ 522 523 if (error_names == NULL) 524 { 525 nbytes = num_error_names * sizeof (char *); 526 if ((error_names = (char **) malloc (nbytes)) != NULL) 527 { 528 memset (error_names, 0, nbytes); 529 for (eip = error_table; eip -> name != NULL; eip++) 530 { 531 error_names[eip -> value] = eip -> name; 532 } 533 } 534 } 535 536 #ifdef NEED_sys_errlist 537 538 /* Now attempt to allocate the sys_errlist table, zero it out, and then 539 initialize it from the statically initialized error_table. */ 540 541 if (sys_errlist == NULL) 542 { 543 nbytes = num_error_names * sizeof (char *); 544 if ((sys_errlist = (char **) malloc (nbytes)) != NULL) 545 { 546 memset (sys_errlist, 0, nbytes); 547 sys_nerr = num_error_names; 548 for (eip = error_table; eip -> name != NULL; eip++) 549 { 550 sys_errlist[eip -> value] = eip -> msg; 551 } 552 } 553 } 554 555 #endif 556 557 } 558 559 /* 560 561 NAME 562 563 errno_max -- return the max errno value 564 565 SYNOPSIS 566 567 int errno_max (); 568 569 DESCRIPTION 570 571 Returns the maximum errno value for which a corresponding symbolic 572 name or message is available. Note that in the case where 573 we use the sys_errlist supplied by the system, it is possible for 574 there to be more symbolic names than messages, or vice versa. 575 In fact, the manual page for perror(3C) explicitly warns that one 576 should check the size of the table (sys_nerr) before indexing it, 577 since new error codes may be added to the system before they are 578 added to the table. Thus sys_nerr might be smaller than value 579 implied by the largest errno value defined in <errno.h>. 580 581 We return the maximum value that can be used to obtain a meaningful 582 symbolic name or message. 583 584 */ 585 586 int 587 errno_max () 588 { 589 int maxsize; 590 591 if (error_names == NULL) 592 { 593 init_error_tables (); 594 } 595 maxsize = MAX (sys_nerr, num_error_names); 596 return (maxsize - 1); 597 } 598 599 #ifdef NEED_strerror 600 601 /* 602 603 NAME 604 605 strerror -- map an error number to an error message string 606 607 SYNOPSIS 608 609 char *strerror (int errnoval) 610 611 DESCRIPTION 612 613 Maps an errno number to an error message string, the contents of 614 which are implementation defined. On systems which have the external 615 variables sys_nerr and sys_errlist, these strings will be the same 616 as the ones used by perror(). 617 618 If the supplied error number is within the valid range of indices 619 for the sys_errlist, but no message is available for the particular 620 error number, then returns the string "Error NUM", where NUM is the 621 error number. 622 623 If the supplied error number is not a valid index into sys_errlist, 624 returns NULL. 625 626 The returned string is only guaranteed to be valid only until the 627 next call to strerror. 628 629 */ 630 631 char * 632 strerror (errnoval) 633 int errnoval; 634 { 635 char *msg; 636 static char buf[32]; 637 638 #ifdef NEED_sys_errlist 639 640 if (error_names == NULL) 641 { 642 init_error_tables (); 643 } 644 645 #endif 646 647 if ((errnoval < 0) || (errnoval >= sys_nerr)) 648 { 649 /* Out of range, just return NULL */ 650 msg = NULL; 651 } 652 else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL)) 653 { 654 /* In range, but no sys_errlist or no entry at this index. */ 655 sprintf (buf, "Error %d", errnoval); 656 msg = buf; 657 } 658 else 659 { 660 /* In range, and a valid message. Just return the message. */ 661 msg = sys_errlist[errnoval]; 662 } 663 664 return (msg); 665 } 666 667 #endif /* NEED_strerror */ 668 669 670 /* 671 672 NAME 673 674 strerrno -- map an error number to a symbolic name string 675 676 SYNOPSIS 677 678 char *strerrno (int errnoval) 679 680 DESCRIPTION 681 682 Given an error number returned from a system call (typically 683 returned in errno), returns a pointer to a string containing the 684 symbolic name of that error number, as found in <errno.h>. 685 686 If the supplied error number is within the valid range of indices 687 for symbolic names, but no name is available for the particular 688 error number, then returns the string "Error NUM", where NUM is 689 the error number. 690 691 If the supplied error number is not within the range of valid 692 indices, then returns NULL. 693 694 BUGS 695 696 The contents of the location pointed to are only guaranteed to be 697 valid until the next call to strerrno. 698 699 */ 700 701 char * 702 strerrno (errnoval) 703 int errnoval; 704 { 705 char *name; 706 static char buf[32]; 707 708 if (error_names == NULL) 709 { 710 init_error_tables (); 711 } 712 713 if ((errnoval < 0) || (errnoval >= num_error_names)) 714 { 715 /* Out of range, just return NULL */ 716 name = NULL; 717 } 718 else if ((error_names == NULL) || (error_names[errnoval] == NULL)) 719 { 720 /* In range, but no error_names or no entry at this index. */ 721 sprintf (buf, "Error %d", errnoval); 722 name = buf; 723 } 724 else 725 { 726 /* In range, and a valid name. Just return the name. */ 727 name = error_names[errnoval]; 728 } 729 730 return (name); 731 } 732 733 /* 734 735 NAME 736 737 strtoerrno -- map a symbolic errno name to a numeric value 738 739 SYNOPSIS 740 741 int strtoerrno (char *name) 742 743 DESCRIPTION 744 745 Given the symbolic name of a error number, map it to an errno value. 746 If no translation is found, returns 0. 747 748 */ 749 750 int 751 strtoerrno (name) 752 char *name; 753 { 754 int errnoval = 0; 755 756 if (name != NULL) 757 { 758 if (error_names == NULL) 759 { 760 init_error_tables (); 761 } 762 for (errnoval = 0; errnoval < num_error_names; errnoval++) 763 { 764 if ((error_names[errnoval] != NULL) && 765 (strcmp (name, error_names[errnoval]) == 0)) 766 { 767 break; 768 } 769 } 770 if (errnoval == num_error_names) 771 { 772 errnoval = 0; 773 } 774 } 775 return (errnoval); 776 } 777 778 779 /* A simple little main that does nothing but print all the errno translations 780 if MAIN is defined and this file is compiled and linked. */ 781 782 #ifdef MAIN 783 784 main () 785 { 786 int errn; 787 int errnmax; 788 char *name; 789 char *msg; 790 char *strerrno (); 791 char *strerror (); 792 793 errnmax = errno_max (); 794 printf ("%d entries in names table.\n", num_error_names); 795 printf ("%d entries in messages table.\n", sys_nerr); 796 printf ("%d is max useful index.\n", errnmax); 797 798 /* Keep printing values until we get to the end of *both* tables, not 799 *either* table. Note that knowing the maximum useful index does *not* 800 relieve us of the responsibility of testing the return pointer for 801 NULL. */ 802 803 for (errn = 0; errn <= errnmax; errn++) 804 { 805 name = strerrno (errn); 806 name = (name == NULL) ? "<NULL>" : name; 807 msg = strerror (errn); 808 msg = (msg == NULL) ? "<NULL>" : msg; 809 printf ("%-4d%-18s%s\n", errn, name, msg); 810 } 811 } 812 813 #endif 814