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