2 * Copyright (c) 2008 Apple Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_errno.c#12 $
32 #include <sys/types.h>
34 #include <config/config.h>
36 #include <bsm/audit_errno.h>
37 #include <bsm/libbsm.h>
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.
53 const char *be_strerror;
56 #define ERRNO_NO_LOCAL_MAPPING -600
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.
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
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).
73 static 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" },
115 ERRNO_NO_LOCAL_MAPPING,
117 "Channel number out of range" },
122 ERRNO_NO_LOCAL_MAPPING,
124 "Level 2 not synchronized" },
129 ERRNO_NO_LOCAL_MAPPING,
136 ERRNO_NO_LOCAL_MAPPING,
143 ERRNO_NO_LOCAL_MAPPING,
145 "Link number out of range" },
150 ERRNO_NO_LOCAL_MAPPING,
152 "Protocol driver not attached" },
157 ERRNO_NO_LOCAL_MAPPING,
159 "No CSI structure available" },
164 ERRNO_NO_LOCAL_MAPPING,
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" },
176 ERRNO_NO_LOCAL_MAPPING,
178 "Invalid exchange" },
183 ERRNO_NO_LOCAL_MAPPING,
185 "Invalid request descriptor" },
190 ERRNO_NO_LOCAL_MAPPING,
197 ERRNO_NO_LOCAL_MAPPING,
204 ERRNO_NO_LOCAL_MAPPING,
206 "Invalid request descriptor" },
211 ERRNO_NO_LOCAL_MAPPING,
218 ERRNO_NO_LOCAL_MAPPING,
220 "Resource deadlock avoided" },
225 ERRNO_NO_LOCAL_MAPPING,
227 "Bad font file format" },
232 ERRNO_NO_LOCAL_MAPPING,
234 "Process died with the lock" },
235 { BSM_ENOTRECOVERABLE,
236 #ifdef ENOTRECOVERABLE
239 ERRNO_NO_LOCAL_MAPPING,
241 "Lock is not recoverable" },
246 ERRNO_NO_LOCAL_MAPPING,
248 "Device not a stream" },
253 ERRNO_NO_LOCAL_MAPPING,
255 "Machine is not on the network" },
260 ERRNO_NO_LOCAL_MAPPING,
262 "Package not installed" },
263 { BSM_EREMOTE, EREMOTE, "Too many levels of remote in path" },
268 ERRNO_NO_LOCAL_MAPPING,
270 "Link has been severed" },
275 ERRNO_NO_LOCAL_MAPPING,
282 ERRNO_NO_LOCAL_MAPPING,
289 ERRNO_NO_LOCAL_MAPPING,
291 "Communication error on send" },
296 ERRNO_NO_LOCAL_MAPPING,
303 ERRNO_NO_LOCAL_MAPPING,
305 "Locked lock was unmapped" },
310 ERRNO_NO_LOCAL_MAPPING,
312 "Facility is not active" },
317 ERRNO_NO_LOCAL_MAPPING,
319 "Multihop attempted" },
324 ERRNO_NO_LOCAL_MAPPING,
327 { BSM_ENAMETOOLONG, ENAMETOOLONG, "File name too long" },
328 { BSM_EOVERFLOW, EOVERFLOW, "Value too large to be stored in data type" },
333 ERRNO_NO_LOCAL_MAPPING,
335 "Given log name not unique" },
340 ERRNO_NO_LOCAL_MAPPING,
342 "Given f.d. invalid for this operation" },
347 ERRNO_NO_LOCAL_MAPPING,
349 "Remote address changed" },
354 ERRNO_NO_LOCAL_MAPPING,
356 "Can't access a needed shared lib" },
361 ERRNO_NO_LOCAL_MAPPING,
363 "Accessing a corrupted shared lib" },
368 ERRNO_NO_LOCAL_MAPPING,
370 ".lib section in a.out corrupted" },
375 ERRNO_NO_LOCAL_MAPPING,
377 "Attempting to link in too many libs" },
382 ERRNO_NO_LOCAL_MAPPING,
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" },
392 ERRNO_NO_LOCAL_MAPPING,
399 ERRNO_NO_LOCAL_MAPPING,
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" },
436 ERRNO_NO_LOCAL_MAPPING,
438 "Device power is off" },
443 ERRNO_NO_LOCAL_MAPPING,
450 ERRNO_NO_LOCAL_MAPPING,
457 ERRNO_NO_LOCAL_MAPPING,
459 "Bad CPU type in executable" },
464 ERRNO_NO_LOCAL_MAPPING,
466 "Shared library version mismatch" },
471 ERRNO_NO_LOCAL_MAPPING,
473 "Malfored Macho file" },
478 ERRNO_NO_LOCAL_MAPPING,
480 "Operation failed by policy" },
485 ERRNO_NO_LOCAL_MAPPING,
487 "RFS specific error" },
492 ERRNO_NO_LOCAL_MAPPING,
494 "Structure needs cleaning" },
499 ERRNO_NO_LOCAL_MAPPING,
501 "Not a XENIX named type file" },
506 ERRNO_NO_LOCAL_MAPPING,
508 "No XENIX semaphores available" },
513 ERRNO_NO_LOCAL_MAPPING,
515 "Is a named type file" },
520 ERRNO_NO_LOCAL_MAPPING,
522 "Remote I/O error" },
527 ERRNO_NO_LOCAL_MAPPING,
534 ERRNO_NO_LOCAL_MAPPING,
536 "Wrong medium type" },
541 ERRNO_NO_LOCAL_MAPPING,
543 "Required key not available" },
548 ERRNO_NO_LOCAL_MAPPING,
555 ERRNO_NO_LOCAL_MAPPING,
557 "Key has been revoked" },
562 ERRNO_NO_LOCAL_MAPPING,
564 "Key was rejected by service" },
566 static const int bsm_errors_count = sizeof(bsm_errors) / sizeof(bsm_errors[0]);
568 static const struct bsm_errors *
569 au_bsm_error_lookup_errno(int error)
573 if (error == ERRNO_NO_LOCAL_MAPPING)
575 for (i = 0; i < bsm_errors_count; i++) {
576 if (bsm_errors[i].be_os_error == error)
577 return (&bsm_errors[i]);
582 static const struct bsm_errors *
583 au_bsm_error_lookup_bsm(u_char bsm_error)
587 for (i = 0; i < bsm_errors_count; i++) {
588 if (bsm_errors[i].be_bsm_error == bsm_error)
589 return (&bsm_errors[i]);
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.
601 au_bsm_to_errno(u_char bsm_error, int *errorp)
603 const struct bsm_errors *bsme;
605 bsme = au_bsm_error_lookup_bsm(bsm_error);
606 if (bsme == NULL || bsme->be_os_error == ERRNO_NO_LOCAL_MAPPING)
608 *errorp = bsme->be_os_error;
613 au_errno_to_bsm(int error)
615 const struct bsm_errors *bsme;
618 * We should never be passed this libbsm-internal constant, and
619 * because it is ambiguous we just return an error.
621 if (error == ERRNO_NO_LOCAL_MAPPING)
622 return (BSM_UNKNOWNERR);
623 bsme = au_bsm_error_lookup_errno(error);
625 return (BSM_UNKNOWNERR);
626 return (bsme->be_bsm_error);
629 #if !defined(KERNEL) && !defined(_KERNEL)
631 au_strerror(u_char bsm_error)
633 const struct bsm_errors *bsme;
635 bsme = au_bsm_error_lookup_bsm(bsm_error);
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);