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