bsm_errno.c revision 186545
1/*- 2 * Copyright (c) 2008 Apple Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_errno.c#12 $ 30 */ 31 32#include <sys/types.h> 33 34#include <config/config.h> 35 36#include <bsm/audit_errno.h> 37#include <bsm/libbsm.h> 38 39#include <errno.h> 40#include <string.h> 41 42/* 43 * Different operating systems use different numeric constants for different 44 * error numbers, and sometimes error numbers don't exist in more than one 45 * operating system. These routines convert between BSM and local error 46 * number spaces, subject to the above realities. BSM error numbers are 47 * stored in a single 8-bit character, so don't have a byte order. 48 */ 49 50struct bsm_errors { 51 int be_bsm_error; 52 int be_os_error; 53 const char *be_strerror; 54}; 55 56#define ERRNO_NO_LOCAL_MAPPING -600 57 58/* 59 * Mapping table -- please maintain in numeric sorted order with respect to 60 * the BSM constant. Today we do a linear lookup, but could switch to a 61 * binary search if it makes sense. We only ifdef errors that aren't 62 * generally available, but it does make the table a lot more ugly. 63 * 64 * XXXRW: It would be nice to have a similar ordered table mapping to BSM 65 * constant from local constant, but the order of local constants varies by 66 * OS. Really we need to build that table at compile-time but don't do that 67 * yet. 68 * 69 * XXXRW: We currently embed English-language error strings here, but should 70 * support catalogues; these are only used if the OS doesn't have an error 71 * string using strerror(3). 72 */ 73static const struct bsm_errors bsm_errors[] = { 74 { BSM_ESUCCESS, 0, "Success" }, 75 { BSM_EPERM, EPERM, "Operation not permitted" }, 76 { BSM_ENOENT, ENOENT, "No such file or directory" }, 77 { BSM_ESRCH, ESRCH, "No such process" }, 78 { BSM_EINTR, EINTR, "Interrupted system call" }, 79 { BSM_EIO, EIO, "Input/output error" }, 80 { BSM_ENXIO, ENXIO, "Device not configured" }, 81 { BSM_E2BIG, E2BIG, "Argument list too long" }, 82 { BSM_ENOEXEC, ENOEXEC, "Exec format error" }, 83 { BSM_EBADF, EBADF, "BAd file descriptor" }, 84 { BSM_ECHILD, ECHILD, "No child processes" }, 85 { BSM_EAGAIN, EAGAIN, "Resource temporarily unavailable" }, 86 { BSM_ENOMEM, ENOMEM, "Cannot allocate memory" }, 87 { BSM_EACCES, EACCES, "Permission denied" }, 88 { BSM_EFAULT, EFAULT, "Bad address" }, 89 { BSM_ENOTBLK, ENOTBLK, "Block device required" }, 90 { BSM_EBUSY, EBUSY, "Device busy" }, 91 { BSM_EEXIST, EEXIST, "File exists" }, 92 { BSM_EXDEV, EXDEV, "Cross-device link" }, 93 { BSM_ENODEV, ENODEV, "Operation not supported by device" }, 94 { BSM_ENOTDIR, ENOTDIR, "Not a directory" }, 95 { BSM_EISDIR, EISDIR, "Is a directory" }, 96 { BSM_EINVAL, EINVAL, "Invalid argument" }, 97 { BSM_ENFILE, ENFILE, "Too many open files in system" }, 98 { BSM_EMFILE, EMFILE, "Too many open files" }, 99 { BSM_ENOTTY, ENOTTY, "Inappropriate ioctl for device" }, 100 { BSM_ETXTBSY, ETXTBSY, "Text file busy" }, 101 { BSM_EFBIG, EFBIG, "File too large" }, 102 { BSM_ENOSPC, ENOSPC, "No space left on device" }, 103 { BSM_ESPIPE, ESPIPE, "Illegal seek" }, 104 { BSM_EROFS, EROFS, "Read-only file system" }, 105 { BSM_EMLINK, EMLINK, "Too many links" }, 106 { BSM_EPIPE, EPIPE, "Broken pipe" }, 107 { BSM_EDOM, EDOM, "Numerical argument out of domain" }, 108 { BSM_ERANGE, ERANGE, "Result too large" }, 109 { BSM_ENOMSG, ENOMSG, "No message of desired type" }, 110 { BSM_EIDRM, EIDRM, "Identifier removed" }, 111 { BSM_ECHRNG, 112#ifdef ECHRNG 113 ECHRNG, 114#else 115 ERRNO_NO_LOCAL_MAPPING, 116#endif 117 "Channel number out of range" }, 118 { BSM_EL2NSYNC, 119#ifdef EL2NSYNC 120 EL2NSYNC, 121#else 122 ERRNO_NO_LOCAL_MAPPING, 123#endif 124 "Level 2 not synchronized" }, 125 { BSM_EL3HLT, 126#ifdef EL3HLT 127 EL3HLT, 128#else 129 ERRNO_NO_LOCAL_MAPPING, 130#endif 131 "Level 3 halted" }, 132 { BSM_EL3RST, 133#ifdef EL3RST 134 EL3RST, 135#else 136 ERRNO_NO_LOCAL_MAPPING, 137#endif 138 "Level 3 reset" }, 139 { BSM_ELNRNG, 140#ifdef ELNRNG 141 ELNRNG, 142#else 143 ERRNO_NO_LOCAL_MAPPING, 144#endif 145 "Link number out of range" }, 146 { BSM_EUNATCH, 147#ifdef EUNATCH 148 EUNATCH, 149#else 150 ERRNO_NO_LOCAL_MAPPING, 151#endif 152 "Protocol driver not attached" }, 153 { BSM_ENOCSI, 154#ifdef ENOCSI 155 ENOCSI, 156#else 157 ERRNO_NO_LOCAL_MAPPING, 158#endif 159 "No CSI structure available" }, 160 { BSM_EL2HLT, 161#ifdef EL2HLT 162 EL2HLT, 163#else 164 ERRNO_NO_LOCAL_MAPPING, 165#endif 166 "Level 2 halted" }, 167 { BSM_EDEADLK, EDEADLK, "Resource deadlock avoided" }, 168 { BSM_ENOLCK, ENOLCK, "No locks available" }, 169 { BSM_ECANCELED, ECANCELED, "Operation canceled" }, 170 { BSM_ENOTSUP, ENOTSUP, "Operation not supported" }, 171 { BSM_EDQUOT, EDQUOT, "Disc quota exceeded" }, 172 { BSM_EBADE, 173#ifdef EBADE 174 EBADE, 175#else 176 ERRNO_NO_LOCAL_MAPPING, 177#endif 178 "Invalid exchange" }, 179 { BSM_EBADR, 180#ifdef EBADR 181 EBADR, 182#else 183 ERRNO_NO_LOCAL_MAPPING, 184#endif 185 "Invalid request descriptor" }, 186 { BSM_EXFULL, 187#ifdef EXFULL 188 EXFULL, 189#else 190 ERRNO_NO_LOCAL_MAPPING, 191#endif 192 "Exchange full" }, 193 { BSM_ENOANO, 194#ifdef ENOANO 195 ENOANO, 196#else 197 ERRNO_NO_LOCAL_MAPPING, 198#endif 199 "No anode" }, 200 { BSM_EBADRQC, 201#ifdef EBADRQC 202 EBADRQC, 203#else 204 ERRNO_NO_LOCAL_MAPPING, 205#endif 206 "Invalid request descriptor" }, 207 { BSM_EBADSLT, 208#ifdef EBADSLT 209 EBADSLT, 210#else 211 ERRNO_NO_LOCAL_MAPPING, 212#endif 213 "Invalid slot" }, 214 { BSM_EDEADLOCK, 215#ifdef EDEADLOCK 216 EDEADLOCK, 217#else 218 ERRNO_NO_LOCAL_MAPPING, 219#endif 220 "Resource deadlock avoided" }, 221 { BSM_EBFONT, 222#ifdef EBFONT 223 EBFONT, 224#else 225 ERRNO_NO_LOCAL_MAPPING, 226#endif 227 "Bad font file format" }, 228 { BSM_EOWNERDEAD, 229#ifdef EOWNERDEAD 230 EOWNERDEAD, 231#else 232 ERRNO_NO_LOCAL_MAPPING, 233#endif 234 "Process died with the lock" }, 235 { BSM_ENOTRECOVERABLE, 236#ifdef ENOTRECOVERABLE 237 ENOTRECOVERABLE, 238#else 239 ERRNO_NO_LOCAL_MAPPING, 240#endif 241 "Lock is not recoverable" }, 242 { BSM_ENOSTR, 243#ifdef ENOSTR 244 ENOSTR, 245#else 246 ERRNO_NO_LOCAL_MAPPING, 247#endif 248 "Device not a stream" }, 249 { BSM_ENONET, 250#ifdef ENONET 251 ENONET, 252#else 253 ERRNO_NO_LOCAL_MAPPING, 254#endif 255 "Machine is not on the network" }, 256 { BSM_ENOPKG, 257#ifdef ENOPKG 258 ENOPKG, 259#else 260 ERRNO_NO_LOCAL_MAPPING, 261#endif 262 "Package not installed" }, 263 { BSM_EREMOTE, EREMOTE, "Too many levels of remote in path" }, 264 { BSM_ENOLINK, 265#ifdef ENOLINK 266 ENOLINK, 267#else 268 ERRNO_NO_LOCAL_MAPPING, 269#endif 270 "Link has been severed" }, 271 { BSM_EADV, 272#ifdef EADV 273 EADV, 274#else 275 ERRNO_NO_LOCAL_MAPPING, 276#endif 277 "Advertise error" }, 278 { BSM_ESRMNT, 279#ifdef ESRMNT 280 ESRMNT, 281#else 282 ERRNO_NO_LOCAL_MAPPING, 283#endif 284 "srmount error" }, 285 { BSM_ECOMM, 286#ifdef ECOMM 287 ECOMM, 288#else 289 ERRNO_NO_LOCAL_MAPPING, 290#endif 291 "Communication error on send" }, 292 { BSM_EPROTO, 293#ifdef EPROTO 294 EPROTO, 295#else 296 ERRNO_NO_LOCAL_MAPPING, 297#endif 298 "Protocol error" }, 299 { BSM_ELOCKUNMAPPED, 300#ifdef ELOCKUNMAPPED 301 ELOCKUNMAPPED, 302#else 303 ERRNO_NO_LOCAL_MAPPING, 304#endif 305 "Locked lock was unmapped" }, 306 { BSM_ENOTACTIVE, 307#ifdef ENOTACTIVE 308 ENOTACTIVE, 309#else 310 ERRNO_NO_LOCAL_MAPPING, 311#endif 312 "Facility is not active" }, 313 { BSM_EMULTIHOP, 314#ifdef EMULTIHOP 315 EMULTIHOP, 316#else 317 ERRNO_NO_LOCAL_MAPPING, 318#endif 319 "Multihop attempted" }, 320 { BSM_EBADMSG, 321#ifdef EBADMSG 322 EBADMSG, 323#else 324 ERRNO_NO_LOCAL_MAPPING, 325#endif 326 "Bad message" }, 327 { BSM_ENAMETOOLONG, ENAMETOOLONG, "File name too long" }, 328 { BSM_EOVERFLOW, EOVERFLOW, "Value too large to be stored in data type" }, 329 { BSM_ENOTUNIQ, 330#ifdef ENOTUNIQ 331 ENOTUNIQ, 332#else 333 ERRNO_NO_LOCAL_MAPPING, 334#endif 335 "Given log name not unique" }, 336 { BSM_EBADFD, 337#ifdef EBADFD 338 EBADFD, 339#else 340 ERRNO_NO_LOCAL_MAPPING, 341#endif 342 "Given f.d. invalid for this operation" }, 343 { BSM_EREMCHG, 344#ifdef EREMCHG 345 EREMCHG, 346#else 347 ERRNO_NO_LOCAL_MAPPING, 348#endif 349 "Remote address changed" }, 350 { BSM_ELIBACC, 351#ifdef ELIBACC 352 ELIBACC, 353#else 354 ERRNO_NO_LOCAL_MAPPING, 355#endif 356 "Can't access a needed shared lib" }, 357 { BSM_ELIBBAD, 358#ifdef ELIBBAD 359 ELIBBAD, 360#else 361 ERRNO_NO_LOCAL_MAPPING, 362#endif 363 "Accessing a corrupted shared lib" }, 364 { BSM_ELIBSCN, 365#ifdef ELIBSCN 366 ELIBSCN, 367#else 368 ERRNO_NO_LOCAL_MAPPING, 369#endif 370 ".lib section in a.out corrupted" }, 371 { BSM_ELIBMAX, 372#ifdef ELIBMAX 373 ELIBMAX, 374#else 375 ERRNO_NO_LOCAL_MAPPING, 376#endif 377 "Attempting to link in too many libs" }, 378 { BSM_ELIBEXEC, 379#ifdef ELIBEXEC 380 ELIBEXEC, 381#else 382 ERRNO_NO_LOCAL_MAPPING, 383#endif 384 "Attempting to exec a shared library" }, 385 { BSM_EILSEQ, EILSEQ, "Illegal byte sequence" }, 386 { BSM_ENOSYS, ENOSYS, "Function not implemented" }, 387 { BSM_ELOOP, ELOOP, "Too many levels of symbolic links" }, 388 { BSM_ERESTART, 389#ifdef ERESTART 390 ERESTART, 391#else 392 ERRNO_NO_LOCAL_MAPPING, 393#endif 394 "Restart syscall" }, 395 { BSM_ESTRPIPE, 396#ifdef ESTRPIPE 397 ESTRPIPE, 398#else 399 ERRNO_NO_LOCAL_MAPPING, 400#endif 401 "If pipe/FIFO, don't sleep in stream head" }, 402 { BSM_ENOTEMPTY, ENOTEMPTY, "Directory not empty" }, 403 { BSM_EUSERS, EUSERS, "Too many users" }, 404 { BSM_ENOTSOCK, ENOTSOCK, "Socket operation on non-socket" }, 405 { BSM_EDESTADDRREQ, EDESTADDRREQ, "Destination address required" }, 406 { BSM_EMSGSIZE, EMSGSIZE, "Message too long" }, 407 { BSM_EPROTOTYPE, EPROTOTYPE, "Protocol wrong type for socket" }, 408 { BSM_ENOPROTOOPT, ENOPROTOOPT, "Protocol not available" }, 409 { BSM_EPROTONOSUPPORT, EPROTONOSUPPORT, "Protocol not supported" }, 410 { BSM_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT, "Socket type not supported" }, 411 { BSM_EOPNOTSUPP, EOPNOTSUPP, "Operation not supported" }, 412 { BSM_EPFNOSUPPORT, EPFNOSUPPORT, "Protocol family not supported" }, 413 { BSM_EAFNOSUPPORT, EAFNOSUPPORT, "Address family not supported by protocol family" }, 414 { BSM_EADDRINUSE, EADDRINUSE, "Address already in use" }, 415 { BSM_EADDRNOTAVAIL, EADDRNOTAVAIL, "Can't assign requested address" }, 416 { BSM_ENETDOWN, ENETDOWN, "Network is down" }, 417 { BSM_ENETRESET, ENETRESET, "Network dropped connection on reset" }, 418 { BSM_ECONNABORTED, ECONNABORTED, "Software caused connection abort" }, 419 { BSM_ECONNRESET, ECONNRESET, "Connection reset by peer" }, 420 { BSM_ENOBUFS, ENOBUFS, "No buffer space available" }, 421 { BSM_EISCONN, EISCONN, "Socket is already connected" }, 422 { BSM_ENOTCONN, ENOTCONN, "Socket is not connected" }, 423 { BSM_ESHUTDOWN, ESHUTDOWN, "Can't send after socket shutdown" }, 424 { BSM_ETOOMANYREFS, ETOOMANYREFS, "Too many references: can't splice" }, 425 { BSM_ETIMEDOUT, ETIMEDOUT, "Operation timed out" }, 426 { BSM_ECONNREFUSED, ECONNREFUSED, "Connection refused" }, 427 { BSM_EHOSTDOWN, EHOSTDOWN, "Host is down" }, 428 { BSM_EHOSTUNREACH, EHOSTUNREACH, "No route to host" }, 429 { BSM_EALREADY, EALREADY, "Operation already in progress" }, 430 { BSM_EINPROGRESS, EINPROGRESS, "Operation now in progress" }, 431 { BSM_ESTALE, ESTALE, "Stale NFS file handle" }, 432 { BSM_EPWROFF, 433#ifdef EPWROFF 434 EPWROFF, 435#else 436 ERRNO_NO_LOCAL_MAPPING, 437#endif 438 "Device power is off" }, 439 { BSM_EDEVERR, 440#ifdef EDEVERR 441 EDEVERR, 442#else 443 ERRNO_NO_LOCAL_MAPPING, 444#endif 445 "Device error" }, 446 { BSM_EBADEXEC, 447#ifdef EBADEXEC 448 EBADEXEC, 449#else 450 ERRNO_NO_LOCAL_MAPPING, 451#endif 452 "Bad executable" }, 453 { BSM_EBADARCH, 454#ifdef EBADARCH 455 EBADARCH, 456#else 457 ERRNO_NO_LOCAL_MAPPING, 458#endif 459 "Bad CPU type in executable" }, 460 { BSM_ESHLIBVERS, 461#ifdef ESHLIBVERS 462 ESHLIBVERS, 463#else 464 ERRNO_NO_LOCAL_MAPPING, 465#endif 466 "Shared library version mismatch" }, 467 { BSM_EBADMACHO, 468#ifdef EBADMACHO 469 EBADMACHO, 470#else 471 ERRNO_NO_LOCAL_MAPPING, 472#endif 473 "Malfored Macho file" }, 474 { BSM_EPOLICY, 475#ifdef EPOLICY 476 EPOLICY, 477#else 478 ERRNO_NO_LOCAL_MAPPING, 479#endif 480 "Operation failed by policy" }, 481 { BSM_EDOTDOT, 482#ifdef EDOTDOT 483 EDOTDOT, 484#else 485 ERRNO_NO_LOCAL_MAPPING, 486#endif 487 "RFS specific error" }, 488 { BSM_EUCLEAN, 489#ifdef EUCLEAN 490 EUCLEAN, 491#else 492 ERRNO_NO_LOCAL_MAPPING, 493#endif 494 "Structure needs cleaning" }, 495 { BSM_ENOTNAM, 496#ifdef ENOTNAM 497 ENOTNAM, 498#else 499 ERRNO_NO_LOCAL_MAPPING, 500#endif 501 "Not a XENIX named type file" }, 502 { BSM_ENAVAIL, 503#ifdef ENAVAIL 504 ENAVAIL, 505#else 506 ERRNO_NO_LOCAL_MAPPING, 507#endif 508 "No XENIX semaphores available" }, 509 { BSM_EISNAM, 510#ifdef EISNAM 511 EISNAM, 512#else 513 ERRNO_NO_LOCAL_MAPPING, 514#endif 515 "Is a named type file" }, 516 { BSM_EREMOTEIO, 517#ifdef EREMOTEIO 518 EREMOTEIO, 519#else 520 ERRNO_NO_LOCAL_MAPPING, 521#endif 522 "Remote I/O error" }, 523 { BSM_ENOMEDIUM, 524#ifdef ENOMEDIUM 525 ENOMEDIUM, 526#else 527 ERRNO_NO_LOCAL_MAPPING, 528#endif 529 "No medium found" }, 530 { BSM_EMEDIUMTYPE, 531#ifdef EMEDIUMTYPE 532 EMEDIUMTYPE, 533#else 534 ERRNO_NO_LOCAL_MAPPING, 535#endif 536 "Wrong medium type" }, 537 { BSM_ENOKEY, 538#ifdef ENOKEY 539 ENOKEY, 540#else 541 ERRNO_NO_LOCAL_MAPPING, 542#endif 543 "Required key not available" }, 544 { BSM_EKEYEXPIRED, 545#ifdef EKEEXPIRED 546 EKEYEXPIRED, 547#else 548 ERRNO_NO_LOCAL_MAPPING, 549#endif 550 "Key has expired" }, 551 { BSM_EKEYREVOKED, 552#ifdef EKEYREVOKED 553 EKEYREVOKED, 554#else 555 ERRNO_NO_LOCAL_MAPPING, 556#endif 557 "Key has been revoked" }, 558 { BSM_EKEYREJECTED, 559#ifdef EKEREJECTED 560 EKEYREJECTED, 561#else 562 ERRNO_NO_LOCAL_MAPPING, 563#endif 564 "Key was rejected by service" }, 565}; 566static const int bsm_errors_count = sizeof(bsm_errors) / sizeof(bsm_errors[0]); 567 568static const struct bsm_errors * 569au_bsm_error_lookup_errno(int error) 570{ 571 int i; 572 573 if (error == ERRNO_NO_LOCAL_MAPPING) 574 return (NULL); 575 for (i = 0; i < bsm_errors_count; i++) { 576 if (bsm_errors[i].be_os_error == error) 577 return (&bsm_errors[i]); 578 } 579 return (NULL); 580} 581 582static const struct bsm_errors * 583au_bsm_error_lookup_bsm(u_char bsm_error) 584{ 585 int i; 586 587 for (i = 0; i < bsm_errors_count; i++) { 588 if (bsm_errors[i].be_bsm_error == bsm_error) 589 return (&bsm_errors[i]); 590 } 591 return (NULL); 592} 593 594/* 595 * Converstion from a BSM error to a local error number may fail if either 596 * OpenBSM doesn't recognize the error on the wire, or because there is no 597 * appropriate local mapping. However, we don't allow conversion to BSM to 598 * fail, we just convert to BSM_UKNOWNERR. 599 */ 600int 601au_bsm_to_errno(u_char bsm_error, int *errorp) 602{ 603 const struct bsm_errors *bsme; 604 605 bsme = au_bsm_error_lookup_bsm(bsm_error); 606 if (bsme == NULL || bsme->be_os_error == ERRNO_NO_LOCAL_MAPPING) 607 return (-1); 608 *errorp = bsme->be_os_error; 609 return (0); 610} 611 612u_char 613au_errno_to_bsm(int error) 614{ 615 const struct bsm_errors *bsme; 616 617 /* 618 * We should never be passed this libbsm-internal constant, and 619 * because it is ambiguous we just return an error. 620 */ 621 if (error == ERRNO_NO_LOCAL_MAPPING) 622 return (BSM_UNKNOWNERR); 623 bsme = au_bsm_error_lookup_errno(error); 624 if (bsme == NULL) 625 return (BSM_UNKNOWNERR); 626 return (bsme->be_bsm_error); 627} 628 629#if !defined(KERNEL) && !defined(_KERNEL) 630const char * 631au_strerror(u_char bsm_error) 632{ 633 const struct bsm_errors *bsme; 634 635 bsme = au_bsm_error_lookup_bsm(bsm_error); 636 if (bsme == NULL) 637 return ("Unrecognized BSM error"); 638 if (bsme->be_os_error != ERRNO_NO_LOCAL_MAPPING) 639 return (strerror(bsme->be_os_error)); 640 return (bsme->be_strerror); 641} 642#endif 643