diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/VBox/Runtime/common/err | |
parent | Initial commit. (diff) | |
download | virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.tar.xz virtualbox-16f504a9dca3fe3b70568f67b7d41241ae485288.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Runtime/common/err')
-rw-r--r-- | src/VBox/Runtime/common/err/Makefile.kup | 0 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp | 467 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp | 465 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errinfo-alloc.cpp | 80 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errinfo.cpp | 137 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errinfolog.cpp | 215 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errmsg-sorter.cpp | 483 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errmsg.cpp | 338 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errmsg.sed | 98 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errmsgcom.sed | 76 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/errmsgxpcom.cpp | 170 | ||||
-rw-r--r-- | src/VBox/Runtime/common/err/nocrt-strerror.cpp | 464 |
12 files changed, 2993 insertions, 0 deletions
diff --git a/src/VBox/Runtime/common/err/Makefile.kup b/src/VBox/Runtime/common/err/Makefile.kup new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/VBox/Runtime/common/err/Makefile.kup diff --git a/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp b/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp new file mode 100644 index 00000000..ff9c9af4 --- /dev/null +++ b/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp @@ -0,0 +1,467 @@ +/* $Id: RTErrConvertFromErrno.cpp $ */ +/** @file + * IPRT - Convert errno to iprt status codes. + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/err.h> +#include "internal/iprt.h" + +#include <iprt/log.h> +#include <iprt/assert.h> +#include <iprt/errno.h> + + +RTDECL(int) RTErrConvertFromErrno(int iNativeCode) +{ + /* very fast check for no error. */ + if (iNativeCode == 0) + return VINF_SUCCESS; + + /* + * Process error codes. + * + * (Use a switch and not a table since the numbers vary among compilers + * and OSes. So we let the compiler switch optimizer handle speed issues.) + * + * This switch is arranged like the Linux i386 errno.h! This switch is mirrored + * by RTErrConvertToErrno. + */ + switch (iNativeCode) + { /* Linux number */ +#ifdef EPERM + case EPERM: return VERR_ACCESS_DENIED; /* 1 */ +#endif +#ifdef ENOENT + case ENOENT: return VERR_FILE_NOT_FOUND; +#endif +#ifdef ESRCH + case ESRCH: return VERR_PROCESS_NOT_FOUND; +#endif +#ifdef EINTR + case EINTR: return VERR_INTERRUPTED; +#endif +#ifdef EIO + case EIO: return VERR_DEV_IO_ERROR; +#endif +#ifdef ENXIO + case ENXIO: return VERR_DEV_IO_ERROR; /** @todo fix this duplicate error */ +#endif +#ifdef E2BIG + case E2BIG: return VERR_TOO_MUCH_DATA; +#endif +#ifdef ENOEXEC + case ENOEXEC: return VERR_BAD_EXE_FORMAT; +#endif +#ifdef EBADF + case EBADF: return VERR_INVALID_HANDLE; +#endif +#ifdef ECHILD + case ECHILD: return VERR_PROCESS_NOT_FOUND; /* 10 */ /** @todo fix duplicate error */ +#endif +#ifdef EAGAIN + case EAGAIN: return VERR_TRY_AGAIN; +#endif +#ifdef ENOMEM + case ENOMEM: return VERR_NO_MEMORY; +#endif +#ifdef EACCES + case EACCES: return VERR_ACCESS_DENIED; /** @todo fix duplicate error */ +#endif +#ifdef EFAULT + case EFAULT: return VERR_INVALID_POINTER; +#endif +#ifdef ENOTBLK + //case ENOTBLK: return VERR_; +#endif +#ifdef EBUSY + case EBUSY: return VERR_RESOURCE_BUSY; +#endif +#ifdef EEXIST + case EEXIST: return VERR_ALREADY_EXISTS; +#endif +#ifdef EXDEV + case EXDEV: return VERR_NOT_SAME_DEVICE; +#endif +#ifdef ENODEV + case ENODEV: return VERR_NOT_SUPPORTED; /** @todo fix duplicate error */ +#endif +#ifdef ENOTDIR + case ENOTDIR: return VERR_PATH_NOT_FOUND; /* 20 */ +#endif +#ifdef EISDIR + case EISDIR: return VERR_IS_A_DIRECTORY; +#endif +#ifdef EINVAL + case EINVAL: return VERR_INVALID_PARAMETER; +#endif +#ifdef ENFILE + case ENFILE: return VERR_TOO_MANY_OPEN_FILES; /** @todo fix duplicate error */ +#endif +#ifdef EMFILE + case EMFILE: return VERR_TOO_MANY_OPEN_FILES; +#endif +#ifdef ENOTTY + case ENOTTY: return VERR_INVALID_FUNCTION; +#endif +#ifdef ETXTBSY + case ETXTBSY: return VERR_SHARING_VIOLATION; +#endif +#ifdef EFBIG + case EFBIG: return VERR_FILE_TOO_BIG; +#endif +#ifdef ENOSPC + case ENOSPC: return VERR_DISK_FULL; +#endif +#ifdef ESPIPE + case ESPIPE: return VERR_SEEK_ON_DEVICE; +#endif +#ifdef EROFS + case EROFS: return VERR_WRITE_PROTECT; /* 30 */ +#endif +#ifdef EMLINK + //case EMLINK: +#endif +#ifdef EPIPE + case EPIPE: return VERR_BROKEN_PIPE; +#endif +#ifdef EDOM + case EDOM: return VERR_INVALID_PARAMETER; /** @todo fix duplicate error */ +#endif +#ifdef ERANGE + case ERANGE: return VERR_OUT_OF_RANGE; +#endif +#ifdef EDEADLK + case EDEADLK: return VERR_DEADLOCK; +#endif +#ifdef ENAMETOOLONG + case ENAMETOOLONG: return VERR_FILENAME_TOO_LONG; +#endif +#ifdef ENOLCK + case ENOLCK: return VERR_FILE_LOCK_FAILED; +#endif +#ifdef ENOSYS /** @todo map this differently on solaris. */ + case ENOSYS: return VERR_NOT_SUPPORTED; +#endif +#ifdef ENOTEMPTY + case ENOTEMPTY: return VERR_DIR_NOT_EMPTY; +#endif +#ifdef ELOOP + case ELOOP: return VERR_TOO_MANY_SYMLINKS; /* 40 */ +#endif + //41?? +#ifdef ENOMSG + //case ENOMSG 42 /* No message of desired type */ +#endif +#ifdef EIDRM + //case EIDRM 43 /* Identifier removed */ +#endif +#ifdef ECHRNG + //case ECHRNG 44 /* Channel number out of range */ +#endif +#ifdef EL2NSYNC + //case EL2NSYNC 45 /* Level 2 not synchronized */ +#endif +#ifdef EL3HLT + //case EL3HLT 46 /* Level 3 halted */ +#endif +#ifdef EL3RST + //case EL3RST 47 /* Level 3 reset */ +#endif +#ifdef ELNRNG + //case ELNRNG 48 /* Link number out of range */ +#endif +#ifdef EUNATCH + //case EUNATCH 49 /* Protocol driver not attached */ +#endif +#ifdef ENOCSI + //case ENOCSI 50 /* No CSI structure available */ +#endif +#ifdef EL2HLT + //case EL2HLT 51 /* Level 2 halted */ +#endif +#ifdef EBADE + //case EBADE 52 /* Invalid exchange */ +#endif +#ifdef EBADR + //case EBADR 53 /* Invalid request descriptor */ +#endif +#ifdef EXFULL + //case EXFULL 54 /* Exchange full */ +#endif +#ifdef ENOANO + //case ENOANO 55 /* No anode */ +#endif +#ifdef EBADRQC + //case EBADRQC 56 /* Invalid request code */ +#endif +#ifdef EBADSLT + //case EBADSLT 57 /* Invalid slot */ +#endif + //case 58: +#ifdef EBFONT + //case EBFONT 59 /* Bad font file format */ +#endif +#ifdef ENOSTR + //case ENOSTR 60 /* Device not a stream */ +#endif +#ifdef ENODATA + case ENODATA: return VERR_NO_DATA; +#endif +#ifdef ETIME + //case ETIME 62 /* Timer expired */ +#endif +#ifdef ENOSR + //case ENOSR 63 /* Out of streams resources */ +#endif +#ifdef ENONET + case ENONET: return VERR_NET_NO_NETWORK; +#endif +#ifdef ENOPKG + //case ENOPKG 65 /* Package not installed */ +#endif +#ifdef EREMOTE + //case EREMOTE 66 /* Object is remote */ +#endif +#ifdef ENOLINK + //case ENOLINK 67 /* Link has been severed */ +#endif +#ifdef EADV + //case EADV 68 /* Advertise error */ +#endif +#ifdef ESRMNT + //case ESRMNT 69 /* Srmount error */ +#endif +#ifdef ECOMM + //case ECOMM 70 /* Communication error on send */ +#endif +#ifdef EPROTO + case EPROTO: return VERR_NET_PROTOCOL_ERROR; +#endif +#ifdef EMULTIHOP + //case EMULTIHOP 72 /* Multihop attempted */ +#endif +#ifdef EDOTDOT + //case EDOTDOT 73 /* RFS specific error */ +#endif +#ifdef EBADMSG + //case EBADMSG 74 /* Not a data message */ +#endif +#ifdef EOVERFLOW + case EOVERFLOW: return VERR_TOO_MUCH_DATA; /** @todo fix duplicate error */ +#endif +#ifdef ENOTUNIQ + case ENOTUNIQ: return VERR_NET_NOT_UNIQUE_NAME; +#endif +#ifdef EBADFD + case EBADFD: return VERR_INVALID_HANDLE; /** @todo fix duplicate error? */ +#endif +#ifdef EREMCHG + //case EREMCHG 78 /* Remote address changed */ +#endif +#ifdef ELIBACC + //case ELIBACC 79 /* Can not access a needed shared library */ +#endif +#ifdef ELIBBAD + //case ELIBBAD 80 /* Accessing a corrupted shared library */ +#endif +#ifdef ELIBSCN + //case ELIBSCN 81 /* .lib section in a.out corrupted */ +#endif +#ifdef ELIBMAX + //case ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#endif +#ifdef ELIBEXEC + //case ELIBEXEC 83 /* Cannot exec a shared library directly */ +#endif +#ifdef EILSEQ + case EILSEQ: return VERR_NO_TRANSLATION; +#endif +#ifdef ERESTART + case ERESTART: return VERR_INTERRUPTED;/** @todo fix duplicate error?*/ +#endif +#ifdef ESTRPIPE + //case ESTRPIPE 86 /* Streams pipe error */ +#endif +#ifdef EUSERS + //case EUSERS 87 /* Too many users */ +#endif +#ifdef ENOTSOCK + case ENOTSOCK: return VERR_NET_NOT_SOCKET; +#endif +#ifdef EDESTADDRREQ + case EDESTADDRREQ: return VERR_NET_DEST_ADDRESS_REQUIRED; +#endif +#ifdef EMSGSIZE + case EMSGSIZE: return VERR_NET_MSG_SIZE; +#endif +#ifdef EPROTOTYPE + case EPROTOTYPE: return VERR_NET_PROTOCOL_TYPE; +#endif +#ifdef ENOPROTOOPT + case ENOPROTOOPT: return VERR_NET_PROTOCOL_NOT_AVAILABLE; +#endif +#ifdef EPROTONOSUPPORT + case EPROTONOSUPPORT: return VERR_NET_PROTOCOL_NOT_SUPPORTED; +#endif +#ifdef ESOCKTNOSUPPORT + case ESOCKTNOSUPPORT: return VERR_NET_SOCKET_TYPE_NOT_SUPPORTED; +#endif +#ifdef EOPNOTSUPP /** @todo map this differently on solaris. */ + case EOPNOTSUPP: return VERR_NET_OPERATION_NOT_SUPPORTED; +#endif +#ifdef EPFNOSUPPORT + case EPFNOSUPPORT: return VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED; +#endif +#ifdef EAFNOSUPPORT + case EAFNOSUPPORT: return VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED; +#endif +#ifdef EADDRINUSE + case EADDRINUSE: return VERR_NET_ADDRESS_IN_USE; +#endif +#ifdef EADDRNOTAVAIL + case EADDRNOTAVAIL: return VERR_NET_ADDRESS_NOT_AVAILABLE; +#endif +#ifdef ENETDOWN + case ENETDOWN: return VERR_NET_DOWN; +#endif +#ifdef ENETUNREACH + case ENETUNREACH: return VERR_NET_UNREACHABLE; +#endif +#ifdef ENETRESET + case ENETRESET: return VERR_NET_CONNECTION_RESET; +#endif +#ifdef ECONNABORTED + case ECONNABORTED: return VERR_NET_CONNECTION_ABORTED; +#endif +#ifdef ECONNRESET + case ECONNRESET: return VERR_NET_CONNECTION_RESET_BY_PEER; +#endif +#ifdef ENOBUFS + case ENOBUFS: return VERR_NET_NO_BUFFER_SPACE; +#endif +#ifdef EISCONN + case EISCONN: return VERR_NET_ALREADY_CONNECTED; +#endif +#ifdef ENOTCONN + case ENOTCONN: return VERR_NET_NOT_CONNECTED; +#endif +#ifdef ESHUTDOWN + case ESHUTDOWN: return VERR_NET_SHUTDOWN; +#endif +#ifdef ETOOMANYREFS + case ETOOMANYREFS: return VERR_NET_TOO_MANY_REFERENCES; +#endif +#ifdef ETIMEDOUT + case ETIMEDOUT: return VERR_TIMEOUT; +#endif +#ifdef ECONNREFUSED + case ECONNREFUSED: return VERR_NET_CONNECTION_REFUSED; +#endif +#ifdef EHOSTDOWN + case EHOSTDOWN: return VERR_NET_HOST_DOWN; +#endif +#ifdef EHOSTUNREACH + case EHOSTUNREACH: return VERR_NET_HOST_UNREACHABLE; +#endif +#ifdef EALREADY +# if !defined(ENOLCK) || (EALREADY != ENOLCK) + case EALREADY: return VERR_NET_ALREADY_IN_PROGRESS; +# endif +#endif +#ifdef EINPROGRESS +# if !defined(ENODEV) || (EINPROGRESS != ENODEV) + case EINPROGRESS: return VERR_NET_IN_PROGRESS; +# endif +#endif +#ifdef ESTALE + case ESTALE: return VERR_STALE_FILE_HANDLE; /* 116: Stale NFS file handle */ +#endif +#ifdef EUCLEAN + //case EUCLEAN 117 /* Structure needs cleaning */ +#endif +#ifdef ENOTNAM + //case ENOTNAM 118 /* Not a XENIX named type file */ +#endif +#ifdef ENAVAIL + //case ENAVAIL 119 /* No XENIX semaphores available */ +#endif +#ifdef EISNAM + //case EISNAM 120 /* Is a named type file */ +#endif +#ifdef EREMOTEIO + //case EREMOTEIO 121 /* Remote I/O error */ +#endif +#ifdef EDQUOT + case EDQUOT: return VERR_DISK_FULL; /** @todo fix duplicate error */ +#endif +#ifdef ENOMEDIUM + case ENOMEDIUM: return VERR_MEDIA_NOT_PRESENT; +#endif +#ifdef EMEDIUMTYPE + case EMEDIUMTYPE: return VERR_MEDIA_NOT_RECOGNIZED; +#endif +#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) + case EWOULDBLOCK: return VERR_TRY_AGAIN; +#endif + + /* Non-linux */ + +#ifdef EPROCLIM + case EPROCLIM: return VERR_MAX_PROCS_REACHED; +#endif +#ifdef EDOOFUS +# if EDOOFUS != EINVAL + case EDOOFUS: return VERR_INTERNAL_ERROR; +# endif +#endif +#ifdef ENOTSUP +# ifndef EOPNOTSUPP + case ENOTSUP: return VERR_NOT_SUPPORTED; +# else +# if ENOTSUP != EOPNOTSUPP + case ENOTSUP: return VERR_NOT_SUPPORTED; +# endif +# endif +#endif + default: + AssertLogRelMsgFailed(("Unhandled error code %d\n", iNativeCode)); + return VERR_UNRESOLVED_ERROR; + } +} +RT_EXPORT_SYMBOL(RTErrConvertFromErrno); + diff --git a/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp b/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp new file mode 100644 index 00000000..e97c2ca9 --- /dev/null +++ b/src/VBox/Runtime/common/err/RTErrConvertToErrno.cpp @@ -0,0 +1,465 @@ +/* $Id: RTErrConvertToErrno.cpp $ */ +/** @file + * IPRT - Convert iprt status codes to errno. + */ + +/* + * Copyright (C) 2007-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/err.h> +#include "internal/iprt.h" + +#include <iprt/assert.h> +#include <iprt/err.h> +#include <iprt/errno.h> + + +RTDECL(int) RTErrConvertToErrno(int iErr) +{ + /* very fast check for no error. */ + if (RT_SUCCESS(iErr)) + return 0; + + /* + * Process error codes. + * + * (Use a switch and not a table since the numbers vary among compilers + * and OSes. So we let the compiler switch optimizer handle speed issues.) + * + * This switch is arranged like the Linux i386 errno.h! It also mirrors the + * conversions performed by RTErrConvertFromErrno with a few extra case since + * there are far more IPRT status codes than Unix ones. + */ + switch (iErr) + { +#ifdef EPERM + case VERR_ACCESS_DENIED: return EPERM; +#endif +#ifdef ENOENT + case VERR_FILE_NOT_FOUND: return ENOENT; +#endif +#ifdef ESRCH + case VERR_PROCESS_NOT_FOUND: return ESRCH; +#endif +#ifdef EINTR + case VERR_INTERRUPTED: return EINTR; +#endif +#ifdef EIO + case VERR_DEV_IO_ERROR: return EIO; +#endif +#ifdef ENXIO + //case VERR_DEV_IO_ERROR: return ENXIO; +#endif +#ifdef E2BIG + case VERR_TOO_MUCH_DATA: return E2BIG; +#endif +#ifdef ENOEXEC + case VERR_BAD_EXE_FORMAT: return ENOEXEC; +#endif +#ifdef EBADF + case VERR_INVALID_HANDLE: return EBADF; +#endif +#ifdef ECHILD + //case VERR_PROCESS_NOT_FOUND: return ECHILD; +#endif +#ifdef EAGAIN + case VERR_TRY_AGAIN: return EAGAIN; +#endif +#ifdef ENOMEM + case VERR_NO_MEMORY: return ENOMEM; +#endif +#ifdef EACCES + //case VERR_ACCESS_DENIED: return EACCES; +#endif +#ifdef EFAULT + case VERR_INVALID_POINTER: return EFAULT; +#endif +#ifdef ENOTBLK + //case ENOTBLK: return VERR_; +#endif +#ifdef EBUSY + case VERR_RESOURCE_BUSY: return EBUSY; +#endif +#ifdef EEXIST + case VERR_ALREADY_EXISTS: return EEXIST; +#endif +#ifdef EXDEV + case VERR_NOT_SAME_DEVICE: return EXDEV; +#endif +#ifdef ENODEV + //case VERR_NOT_SUPPORTED: return ENODEV; +#endif +#ifdef ENOTDIR + case VERR_NOT_A_DIRECTORY: + case VERR_PATH_NOT_FOUND: return ENOTDIR; +#endif +#ifdef EISDIR + case VERR_IS_A_DIRECTORY: return EISDIR; +#endif +#ifdef EINVAL + case VERR_INVALID_PARAMETER: return EINVAL; +#endif +#ifdef ENFILE + case VERR_TOO_MANY_OPEN_FILES: return ENFILE; +#endif +#ifdef EMFILE + //case VERR_TOO_MANY_OPEN_FILES: return EMFILE; +#endif +#ifdef ENOTTY + case VERR_INVALID_FUNCTION: return ENOTTY; +#endif +#ifdef ETXTBSY + case VERR_SHARING_VIOLATION: return ETXTBSY; +#endif +#ifdef EFBIG + case VERR_FILE_TOO_BIG: return EFBIG; +#endif +#ifdef ENOSPC + case VERR_DISK_FULL: return ENOSPC; +#endif +#ifdef ESPIPE + case VERR_SEEK_ON_DEVICE: return ESPIPE; +#endif +#ifdef EROFS + case VERR_WRITE_PROTECT: return EROFS; +#endif +#ifdef EMLINK + //case EMLINK: +#endif +#ifdef EPIPE + case VERR_BROKEN_PIPE: return EPIPE; +#endif +#ifdef EDOM + //case VERR_INVALID_PARAMETER: return EDOM; +#endif +#ifdef ERANGE + case VERR_OUT_OF_RANGE: return ERANGE; + case VERR_FLOAT_UNDERFLOW: return ERANGE; + case VWRN_FLOAT_UNDERFLOW: return ERANGE; + case VERR_FLOAT_OVERFLOW: return ERANGE; + case VWRN_FLOAT_OVERFLOW: return ERANGE; +#endif +#ifdef EDEADLK + case VERR_DEADLOCK: return EDEADLK; +#endif +#ifdef ENAMETOOLONG + case VERR_FILENAME_TOO_LONG: return ENAMETOOLONG; +#endif +#ifdef ENOLCK + case VERR_FILE_LOCK_FAILED: return ENOLCK; +#endif +#ifdef ENOSYS + case VERR_NOT_IMPLEMENTED: + case VERR_NOT_SUPPORTED: return ENOSYS; +#endif +#ifdef ENOTEMPTY + case VERR_DIR_NOT_EMPTY: return ENOTEMPTY; +#endif +#ifdef ELOOP + case VERR_TOO_MANY_SYMLINKS: return ELOOP; +#endif + //41?? +#ifdef ENOMSG + //case ENOMSG 42 /* No message of desired type */ +#endif +#ifdef EIDRM + //case EIDRM 43 /* Identifier removed */ +#endif +#ifdef ECHRNG + //case ECHRNG 44 /* Channel number out of range */ +#endif +#ifdef EL2NSYNC + //case EL2NSYNC 45 /* Level 2 not synchronized */ +#endif +#ifdef EL3HLT + //case EL3HLT 46 /* Level 3 halted */ +#endif +#ifdef EL3RST + //case EL3RST 47 /* Level 3 reset */ +#endif +#ifdef ELNRNG + //case ELNRNG 48 /* Link number out of range */ +#endif +#ifdef EUNATCH + //case EUNATCH 49 /* Protocol driver not attached */ +#endif +#ifdef ENOCSI + //case ENOCSI 50 /* No CSI structure available */ +#endif +#ifdef EL2HLT + //case EL2HLT 51 /* Level 2 halted */ +#endif +#ifdef EBADE + //case EBADE 52 /* Invalid exchange */ +#endif +#ifdef EBADR + //case EBADR 53 /* Invalid request descriptor */ +#endif +#ifdef EXFULL + //case EXFULL 54 /* Exchange full */ +#endif +#ifdef ENOANO + //case ENOANO 55 /* No anode */ +#endif +#ifdef EBADRQC + //case EBADRQC 56 /* Invalid request code */ +#endif +#ifdef EBADSLT + //case EBADSLT 57 /* Invalid slot */ +#endif + //case 58: +#ifdef EBFONT + //case EBFONT 59 /* Bad font file format */ +#endif +#ifdef ENOSTR + //case ENOSTR 60 /* Device not a stream */ +#endif +#ifdef ENODATA + case VERR_NO_DATA: return ENODATA; +#endif +#ifdef ETIME + //case ETIME 62 /* Timer expired */ +#endif +#ifdef ENOSR + //case ENOSR 63 /* Out of streams resources */ +#endif +#ifdef ENONET + case VERR_NET_NO_NETWORK: return ENONET; +#endif +#ifdef ENOPKG + //case ENOPKG 65 /* Package not installed */ +#endif +#ifdef EREMOTE + //case EREMOTE 66 /* Object is remote */ +#endif +#ifdef ENOLINK + //case ENOLINK 67 /* Link has been severed */ +#endif +#ifdef EADV + //case EADV 68 /* Advertise error */ +#endif +#ifdef ESRMNT + //case ESRMNT 69 /* Srmount error */ +#endif +#ifdef ECOMM + //case ECOMM 70 /* Communication error on send */ +#endif +#ifdef EPROTO + //case EPROTO 71 /* Protocol error */ +#endif +#ifdef EMULTIHOP + //case EMULTIHOP 72 /* Multihop attempted */ +#endif +#ifdef EDOTDOT + //case EDOTDOT 73 /* RFS specific error */ +#endif +#ifdef EBADMSG + //case EBADMSG 74 /* Not a data message */ +#endif +#ifdef EOVERFLOW + //case VERR_TOO_MUCH_DATA: return EOVERFLOW; +#endif +#ifdef ENOTUNIQ + case VERR_NET_NOT_UNIQUE_NAME: return ENOTUNIQ; +#endif +#ifdef EBADFD + //case VERR_INVALID_HANDLE: return EBADFD; +#endif +#ifdef EREMCHG + //case EREMCHG 78 /* Remote address changed */ +#endif +#ifdef ELIBACC + //case ELIBACC 79 /* Can not access a needed shared library */ +#endif +#ifdef ELIBBAD + //case ELIBBAD 80 /* Accessing a corrupted shared library */ +#endif +#ifdef ELIBSCN + //case ELIBSCN 81 /* .lib section in a.out corrupted */ +#endif +#ifdef ELIBMAX + //case ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#endif +#ifdef ELIBEXEC + //case ELIBEXEC 83 /* Cannot exec a shared library directly */ +#endif +#ifdef EILSEQ + case VERR_NO_TRANSLATION: return EILSEQ; +#endif +#ifdef ERESTART + //case VERR_INTERRUPTED: return ERESTART; +#endif +#ifdef ESTRPIPE + //case ESTRPIPE 86 /* Streams pipe error */ +#endif +#ifdef EUSERS + //case EUSERS 87 /* Too many users */ +#endif +#ifdef ENOTSOCK + case VERR_NET_NOT_SOCKET: return ENOTSOCK; +#endif +#ifdef EDESTADDRREQ + case VERR_NET_DEST_ADDRESS_REQUIRED: return EDESTADDRREQ; +#endif +#ifdef EMSGSIZE + case VERR_NET_MSG_SIZE: return EMSGSIZE; +#endif +#ifdef EPROTOTYPE + case VERR_NET_PROTOCOL_TYPE: return EPROTOTYPE; +#endif +#ifdef ENOPROTOOPT + case VERR_NET_PROTOCOL_NOT_AVAILABLE: return ENOPROTOOPT; +#endif +#ifdef EPROTONOSUPPORT + case VERR_NET_PROTOCOL_NOT_SUPPORTED: return EPROTONOSUPPORT; +#endif +#ifdef ESOCKTNOSUPPORT + case VERR_NET_SOCKET_TYPE_NOT_SUPPORTED: return ESOCKTNOSUPPORT; +#endif +#ifdef EOPNOTSUPP + case VERR_NET_OPERATION_NOT_SUPPORTED: return EOPNOTSUPP; +#endif +#ifdef EPFNOSUPPORT + case VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED: return EPFNOSUPPORT; +#endif +#ifdef EAFNOSUPPORT + case VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED: return EAFNOSUPPORT; +#endif +#ifdef EADDRINUSE + case VERR_NET_ADDRESS_IN_USE: return EADDRINUSE; +#endif +#ifdef EADDRNOTAVAIL + case VERR_NET_ADDRESS_NOT_AVAILABLE: return EADDRNOTAVAIL; +#endif +#ifdef ENETDOWN + case VERR_NET_DOWN: return ENETDOWN; +#endif +#ifdef ENETUNREACH + case VERR_NET_UNREACHABLE: return ENETUNREACH; +#endif +#ifdef ENETRESET + case VERR_NET_CONNECTION_RESET: return ENETRESET; +#endif +#ifdef ECONNABORTED + case VERR_NET_CONNECTION_ABORTED: return ECONNABORTED; +#endif +#ifdef ECONNRESET + case VERR_NET_CONNECTION_RESET_BY_PEER: return ECONNRESET; +#endif +#ifdef ENOBUFS + case VERR_NET_NO_BUFFER_SPACE: return ENOBUFS; +#endif +#ifdef EISCONN + case VERR_NET_ALREADY_CONNECTED: return EISCONN; +#endif +#ifdef ENOTCONN + case VERR_NET_NOT_CONNECTED: return ENOTCONN; +#endif +#ifdef ESHUTDOWN + case VERR_NET_SHUTDOWN: return ESHUTDOWN; +#endif +#ifdef ETOOMANYREFS + case VERR_NET_TOO_MANY_REFERENCES: return ETOOMANYREFS; +#endif +#ifdef ETIMEDOUT + case VERR_TIMEOUT: return ETIMEDOUT; +#endif +#ifdef ECONNREFUSED + case VERR_NET_CONNECTION_REFUSED: return ECONNREFUSED; +#endif +#ifdef EHOSTDOWN + case VERR_NET_HOST_DOWN: return EHOSTDOWN; +#endif +#ifdef EHOSTUNREACH + case VERR_NET_HOST_UNREACHABLE: return EHOSTUNREACH; +#endif +#ifdef EALREADY + case VERR_NET_ALREADY_IN_PROGRESS: return EALREADY; +#endif +#ifdef EINPROGRESS + case VERR_NET_IN_PROGRESS: return EINPROGRESS; +#endif +#ifdef ESTALE + //case ESTALE 116 /* Stale NFS file handle */ +#endif +#ifdef EUCLEAN + //case EUCLEAN 117 /* Structure needs cleaning */ +#endif +#ifdef ENOTNAM + //case ENOTNAM 118 /* Not a XENIX named type file */ +#endif +#ifdef ENAVAIL + //case ENAVAIL 119 /* No XENIX semaphores available */ +#endif +#ifdef EISNAM + //case EISNAM 120 /* Is a named type file */ +#endif +#ifdef EREMOTEIO + //case EREMOTEIO 121 /* Remote I/O error */ +#endif +#ifdef EDQUOT + //case VERR_DISK_FULL: return EDQUOT; +#endif +#ifdef ENOMEDIUM + case VERR_MEDIA_NOT_PRESENT: return ENOMEDIUM; +#endif +#ifdef EMEDIUMTYPE + case VERR_MEDIA_NOT_RECOGNIZED: return EMEDIUMTYPE; +#endif + + /* Non-linux */ + +#ifdef EPROCLIM + case VERR_MAX_PROCS_REACHED: return EPROCLIM; +#endif +#ifdef EDOOFUS + case VERR_INTERNAL_ERROR: + case VERR_INTERNAL_ERROR_2: + case VERR_INTERNAL_ERROR_3: return EDOOFUS; +#endif + + default: + /* The idea here is that if you hit this, you will have to + translate the status code yourself. */ + AssertMsgFailed(("Unhandled error code %Rrc\n", iErr)); +#ifdef EPROTO + return EPROTO; +#else + return EINVAL; +#endif + } +} +RT_EXPORT_SYMBOL(RTErrConvertToErrno); + diff --git a/src/VBox/Runtime/common/err/errinfo-alloc.cpp b/src/VBox/Runtime/common/err/errinfo-alloc.cpp new file mode 100644 index 00000000..9dbefcbe --- /dev/null +++ b/src/VBox/Runtime/common/err/errinfo-alloc.cpp @@ -0,0 +1,80 @@ +/* $Id: errinfo-alloc.cpp $ */ +/** @file + * IPRT - Error Info, Allocators. + */ + +/* + * Copyright (C) 2010-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "internal/iprt.h" +#include <iprt/err.h> + +#include <iprt/assert.h> +#include <iprt/mem.h> +#include <iprt/string.h> + + + +RTDECL(PRTERRINFO) RTErrInfoAlloc(size_t cbMsg) +{ + PRTERRINFO pErrInfo; + RTErrInfoAllocEx(cbMsg, &pErrInfo); + return pErrInfo; +} + + +RTDECL(int) RTErrInfoAllocEx(size_t cbMsg, PRTERRINFO *ppErrInfo) +{ + if (cbMsg == 0) + cbMsg = _4K; + else + cbMsg = RT_ALIGN_Z(cbMsg, 256); + + PRTERRINFO pErrInfo; + *ppErrInfo = pErrInfo = (PRTERRINFO)RTMemTmpAlloc(sizeof(*pErrInfo) + cbMsg); + if (RT_UNLIKELY(!pErrInfo)) + return VERR_NO_TMP_MEMORY; + + RTErrInfoInit(pErrInfo, (char *)(pErrInfo + 1), cbMsg); + pErrInfo->fFlags = RTERRINFO_FLAGS_T_ALLOC | RTERRINFO_FLAGS_MAGIC; + return VINF_SUCCESS; +} + + +RTDECL(void) RTErrInfoFree(PRTERRINFO pErrInfo) +{ + RTMemTmpFree(pErrInfo); +} + diff --git a/src/VBox/Runtime/common/err/errinfo.cpp b/src/VBox/Runtime/common/err/errinfo.cpp new file mode 100644 index 00000000..c36e83fc --- /dev/null +++ b/src/VBox/Runtime/common/err/errinfo.cpp @@ -0,0 +1,137 @@ +/* $Id: errinfo.cpp $ */ +/** @file + * IPRT - Error Info, Setters. + */ + +/* + * Copyright (C) 2010-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "internal/iprt.h" +#include <iprt/errcore.h> + +#include <iprt/assert.h> +#include <iprt/string.h> + + +RTDECL(int) RTErrInfoSet(PRTERRINFO pErrInfo, int rc, const char *pszMsg) +{ + if (pErrInfo) + { + AssertPtr(pErrInfo); + Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); + + RTStrCopy(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg); + pErrInfo->rc = rc; + pErrInfo->fFlags |= RTERRINFO_FLAGS_SET; + } + return rc; +} + + +RTDECL(int) RTErrInfoSetF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + RTErrInfoSetV(pErrInfo, rc, pszFormat, va); + va_end(va); + return rc; +} + + +RTDECL(int) RTErrInfoSetV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va) +{ + if (pErrInfo) + { + AssertPtr(pErrInfo); + Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); + + RTStrPrintfV(pErrInfo->pszMsg, pErrInfo->cbMsg, pszFormat, va); + pErrInfo->rc = rc; + pErrInfo->fFlags |= RTERRINFO_FLAGS_SET; + } + return rc; +} + + +RTDECL(int) RTErrInfoAdd(PRTERRINFO pErrInfo, int rc, const char *pszMsg) +{ + if (pErrInfo) + { + AssertPtr(pErrInfo); + if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET) + RTStrCat(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg); + else + { + while (*pszMsg == ' ') + pszMsg++; + return RTErrInfoSet(pErrInfo, rc, pszMsg); + } + } + return rc; +} + + +RTDECL(int) RTErrInfoAddF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + RTErrInfoAddV(pErrInfo, rc, pszFormat, va); + va_end(va); + return rc; +} + + +RTDECL(int) RTErrInfoAddV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va) +{ + if (pErrInfo) + { + AssertPtr(pErrInfo); + Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); + if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET) + { + char *pszOut = (char *)memchr(pErrInfo->pszMsg, '\0', pErrInfo->cbMsg - 2); + if (pszOut) + RTStrPrintfV(pszOut, &pErrInfo->pszMsg[pErrInfo->cbMsg] - pszOut, pszFormat, va); + } + else + { + while (*pszFormat == ' ') + pszFormat++; + return RTErrInfoSetV(pErrInfo, rc, pszFormat, va); + } + } + return rc; +} + diff --git a/src/VBox/Runtime/common/err/errinfolog.cpp b/src/VBox/Runtime/common/err/errinfolog.cpp new file mode 100644 index 00000000..78bb5e22 --- /dev/null +++ b/src/VBox/Runtime/common/err/errinfolog.cpp @@ -0,0 +1,215 @@ +/* $Id: errinfolog.cpp $ */ +/** @file + * IPRT - Error Info, Setters with logging. + */ + +/* + * Copyright (C) 2010-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "internal/iprt.h" +#include <iprt/errcore.h> + +#include <iprt/assert.h> +#include <iprt/string.h> +#include <iprt/log.h> + + +RTDECL(int) RTErrInfoLogAndSet(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszMsg) +{ + /* The logging: */ + if (fFlags & RTERRINFO_LOG_F_RELEASE) + { + PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %s\n", rc, pszMsg); + } + + PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %s\n", rc, pszMsg); + + /* The setting: */ + if (pErrInfo) + { + AssertPtr(pErrInfo); + Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); + + RTStrCopy(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg); + pErrInfo->rc = rc; + pErrInfo->fFlags |= RTERRINFO_FLAGS_SET; + } + return rc; +} + + +RTDECL(int) RTErrInfoLogAndSetF(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + RTErrInfoLogAndSetV(pErrInfo, rc, iLogGroup, fFlags, pszFormat, va); + va_end(va); + return rc; +} + + +RTDECL(int) RTErrInfoLogAndSetV(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, va_list va) +{ + /* The logging: */ + if (fFlags & RTERRINFO_LOG_F_RELEASE) + { + PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + { + va_list va2; + va_copy(va2, va); + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %N\n", rc, pszFormat, &va2); + va_end(va2); + } + } + + PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + { + va_list va2; + va_copy(va2, va); + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoSet(%Rrc): %N\n", rc, pszFormat, &va2); + va_end(va2); + } + + /* The setting: */ + if (pErrInfo) + { + AssertPtr(pErrInfo); + Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); + + RTStrPrintfV(pErrInfo->pszMsg, pErrInfo->cbMsg, pszFormat, va); + pErrInfo->rc = rc; + pErrInfo->fFlags |= RTERRINFO_FLAGS_SET; + } + return rc; +} + + +RTDECL(int) RTErrInfoLogAndAdd(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszMsg) +{ + if (pErrInfo) + { + AssertPtr(pErrInfo); + if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET) + RTStrCat(pErrInfo->pszMsg, pErrInfo->cbMsg, pszMsg); + else + { + while (*pszMsg == ' ') + pszMsg++; + return RTErrInfoSet(pErrInfo, rc, pszMsg); + } + } + + /* The logging: */ + if (fFlags & RTERRINFO_LOG_F_RELEASE) + { + PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %s\n", rc, pszMsg); + } + + PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %s\n", rc, pszMsg); + + return rc; +} + + +RTDECL(int) RTErrInfoLogAndAddF(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + RTErrInfoLogAndAddV(pErrInfo, rc, iLogGroup, fFlags, pszFormat, va); + va_end(va); + return rc; +} + + +RTDECL(int) RTErrInfoLogAndAddV(PRTERRINFO pErrInfo, int rc, uint32_t iLogGroup, uint32_t fFlags, const char *pszFormat, va_list va) +{ + if (pErrInfo) + { + AssertPtr(pErrInfo); + Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); + if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET) + { + char *pszOut = (char *)memchr(pErrInfo->pszMsg, '\0', pErrInfo->cbMsg - 2); + if (pszOut) + { + va_list va2; + va_copy(va2, va); + RTStrPrintfV(pszOut, &pErrInfo->pszMsg[pErrInfo->cbMsg] - pszOut, pszFormat, va2); + va_end(va2); + } + } + else + { + while (*pszFormat == ' ') + pszFormat++; + return RTErrInfoSetV(pErrInfo, rc, pszFormat, va); + } + } + + /* The logging: */ + if (fFlags & RTERRINFO_LOG_F_RELEASE) + { + PRTLOGGER pLogger = RTLogRelGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + { + va_list va2; + va_copy(va2, va); + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %N\n", rc, pszFormat, &va2); + va_end(va2); + } + } + + PRTLOGGER pLogger = RTLogGetDefaultInstanceExWeak(RT_MAKE_U32(RTLOGGRPFLAGS_LEVEL_1, iLogGroup)); + if (pLogger) + { + va_list va2; + va_copy(va2, va); + RTLogLoggerExWeak(pLogger, RTLOGGRPFLAGS_LEVEL_1, iLogGroup, "RTErrInfoAdd(%Rrc): %N\n", rc, pszFormat, &va2); + va_end(va2); + } + + return rc; +} + diff --git a/src/VBox/Runtime/common/err/errmsg-sorter.cpp b/src/VBox/Runtime/common/err/errmsg-sorter.cpp new file mode 100644 index 00000000..fb403d8d --- /dev/null +++ b/src/VBox/Runtime/common/err/errmsg-sorter.cpp @@ -0,0 +1,483 @@ +/* $Id: errmsg-sorter.cpp $ */ +/** @file + * IPRT - Status code messages, sorter build program. + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/err.h> +#include <iprt/asm.h> +#include <iprt/string.h> +#include <VBox/err.h> + +#include <stdio.h> +#include <stdlib.h> + + +/* + * Include the string table code. + */ +#define BLDPROG_STRTAB_MAX_STRLEN 512 +#define BLDPROG_STRTAB_WITH_COMPRESSION +#define BLDPROG_STRTAB_PURE_ASCII +#define BLDPROG_STRTAB_WITH_CAMEL_WORDS +#include <iprt/bldprog-strtab-template.cpp.h> + + +/********************************************************************************************************************************* +* Structures and Typedefs * +*********************************************************************************************************************************/ +/** Used for raw-input and sorting. */ +typedef struct RTSTATUSMSGINT1 +{ + /** Pointer to the short message string. */ + const char *pszMsgShort; + /** Pointer to the full message string. */ + const char *pszMsgFull; + /** Pointer to the define string. */ + const char *pszDefine; + /** Status code number. */ + int iCode; + /** Set if duplicate. */ + bool fDuplicate; +} RTSTATUSMSGINT1; +typedef RTSTATUSMSGINT1 *PRTSTATUSMSGINT1; + + +/** This is used when building the string table and printing it. */ +typedef struct RTSTATUSMSGINT2 +{ + /** The short message string. */ + BLDPROGSTRING MsgShort; + /** The full message string. */ + BLDPROGSTRING MsgFull; + /** The define string. */ + BLDPROGSTRING Define; + /** Pointer to the define string. */ + const char *pszDefine; + /** Status code number. */ + int iCode; + /** Index into the primary table (for multiple passes). */ + unsigned idx1; +} RTSTATUSMSGINT2; +typedef RTSTATUSMSGINT2 *PRTSTATUSMSGINT2; + + +/** This used to determin minimum field sizes. */ +typedef struct RTSTATUSMSGSTATS +{ + unsigned offMax; + unsigned cchMax; + unsigned cBitsOffset; + unsigned cBitsLength; +} RTSTATUSMSGSTATS; +typedef RTSTATUSMSGSTATS *PRTSTATUSMSGSTATS; + + +/********************************************************************************************************************************* +* Global Variables * +*********************************************************************************************************************************/ +static const char *g_pszProgName = "errmsg-sorter"; +static RTSTATUSMSGINT1 g_aStatusMsgs[] = +{ +#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING) +# include "errmsgdata.h" +#else + { "Success.", "Success.", "VINF_SUCCESS", 0, false }, +#endif +}; + + +static RTEXITCODE error(const char *pszFormat, ...) +{ + va_list va; + va_start(va, pszFormat); + fprintf(stderr, "%s: error: ", g_pszProgName); + vfprintf(stderr, pszFormat, va); + va_end(va); + return RTEXITCODE_FAILURE; +} + + +/** qsort callback. */ +static int CompareErrMsg(const void *pv1, const void *pv2) RT_NOTHROW_DEF +{ + PRTSTATUSMSGINT1 p1 = (PRTSTATUSMSGINT1)pv1; + PRTSTATUSMSGINT1 p2 = (PRTSTATUSMSGINT1)pv2; + int iDiff; + if (p1->iCode < p2->iCode) + iDiff = -1; + else if (p1->iCode > p2->iCode) + iDiff = 1; + else + iDiff = 0; + return iDiff; +} + + +/** + * Checks whether @a pszDefine is a deliberate duplicate define that should be + * omitted. + */ +static bool IgnoreDuplicateDefine(const char *pszDefine) +{ + size_t const cchDefine = strlen(pszDefine); + + static const RTSTRTUPLE s_aTails[] = + { + { RT_STR_TUPLE("_FIRST") }, + { RT_STR_TUPLE("_LAST") }, + { RT_STR_TUPLE("_HIGEST") }, + { RT_STR_TUPLE("_LOWEST") }, + }; + for (size_t i = 0; i < RT_ELEMENTS(s_aTails); i++) + if ( cchDefine > s_aTails[i].cch + && memcmp(&pszDefine[cchDefine - s_aTails[i].cch], s_aTails[i].psz, s_aTails[i].cch) == 0) + return true; + + static const RTSTRTUPLE s_aDeliberateOrSilly[] = + { + { RT_STR_TUPLE("VERR_VRDP_TIMEOUT") }, + { RT_STR_TUPLE("VINF_VRDP_SUCCESS") }, + { RT_STR_TUPLE("VWRN_CONTINUE_RECOMPILE") }, + { RT_STR_TUPLE("VWRN_PATM_CONTINUE_SEARCH") }, + }; + for (size_t i = 0; i < RT_ELEMENTS(s_aDeliberateOrSilly); i++) + if ( cchDefine == s_aDeliberateOrSilly[i].cch + && memcmp(pszDefine, s_aDeliberateOrSilly[i].psz, cchDefine) == 0) + return true; + + return false; +} + + +DECLINLINE(void) GatherStringStats(PRTSTATUSMSGSTATS pStats, PBLDPROGSTRING pString) +{ + if (pStats->offMax < pString->offStrTab) + pStats->offMax = pString->offStrTab; + if (pStats->cchMax < pString->cchString) + pStats->cchMax = (unsigned)pString->cchString; +} + + +DECLINLINE(unsigned) CalcBitsForValue(size_t uValue) +{ + unsigned cBits = 1; + while (RT_BIT_64(cBits) < uValue && cBits < 64) + cBits++; + return cBits; +} + + +static void CalcBitsForStringStats(PRTSTATUSMSGSTATS pStats) +{ + pStats->cBitsOffset = CalcBitsForValue(pStats->offMax); + pStats->cBitsLength = CalcBitsForValue(pStats->cchMax); +} + + +int main(int argc, char **argv) +{ + /* + * Parse arguments. + */ + enum { kMode_All, kMode_NoFullMsg, kMode_OnlyDefines } enmMode; + if (argc == 3 && strcmp(argv[1], "--all") == 0) + enmMode = kMode_All; + else if (argc == 3 && strcmp(argv[1], "--no-full-msg") == 0) + enmMode = kMode_NoFullMsg; + else if (argc == 3 && strcmp(argv[1], "--only-defines") == 0) + enmMode = kMode_OnlyDefines; + else + { + fprintf(stderr, + "syntax error!\n" + "Usage: %s <--all|--no-full-msg|--only-defines> <outfile>\n", argv[0]); + return RTEXITCODE_SYNTAX; + } + const char * const pszOutFile = argv[2]; + + /* + * Sort the table and mark duplicates. + */ + qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareErrMsg); + + int rcExit = RTEXITCODE_SUCCESS; + int iPrev = INT32_MAX; + for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++) + { + /* Deal with duplicates, trying to eliminate unnecessary *_FIRST, *_LAST, + *_LOWEST, and *_HIGHEST entries as well as some deliberate duplicate entries. + This means we need to look forward and backwards here. */ + PRTSTATUSMSGINT1 pMsg = &g_aStatusMsgs[i]; + if (pMsg->iCode == iPrev && i != 0) + { + if (IgnoreDuplicateDefine(pMsg->pszDefine)) + { + pMsg->fDuplicate = true; + continue; + } + PRTSTATUSMSGINT1 pPrev = &g_aStatusMsgs[i - 1]; + rcExit = error("Duplicate value %d - %s and %s\n", iPrev, pMsg->pszDefine, pPrev->pszDefine); + } + else if (i + 1 < RT_ELEMENTS(g_aStatusMsgs)) + { + PRTSTATUSMSGINT1 pNext = &g_aStatusMsgs[i]; + if ( pMsg->iCode == pNext->iCode + && IgnoreDuplicateDefine(pMsg->pszDefine)) + { + pMsg->fDuplicate = true; + continue; + } + } + iPrev = pMsg->iCode; + pMsg->fDuplicate = false; + } + + /* + * Create a string table for it all. + */ + BLDPROGSTRTAB StrTab; + if (!BldProgStrTab_Init(&StrTab, RT_ELEMENTS(g_aStatusMsgs) * 3)) + return error("Out of memory!\n"); + + static RTSTATUSMSGINT2 s_aStatusMsgs2[RT_ELEMENTS(g_aStatusMsgs)]; + unsigned cStatusMsgs = 0; + for (unsigned i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++) + if (!g_aStatusMsgs[i].fDuplicate) + { + s_aStatusMsgs2[cStatusMsgs].idx1 = i; + s_aStatusMsgs2[cStatusMsgs].iCode = g_aStatusMsgs[i].iCode; + s_aStatusMsgs2[cStatusMsgs].pszDefine = g_aStatusMsgs[i].pszDefine; + BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].Define, g_aStatusMsgs[i].pszDefine); + cStatusMsgs++; + } + + if (enmMode != kMode_OnlyDefines) + for (size_t i = 0; i < cStatusMsgs; i++) + BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[i].MsgShort, g_aStatusMsgs[s_aStatusMsgs2[i].idx1].pszMsgShort); + + if (enmMode == kMode_All) + for (size_t i = 0; i < cStatusMsgs; i++) + BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[i].MsgFull, g_aStatusMsgs[s_aStatusMsgs2[i].idx1].pszMsgFull); + + if (!BldProgStrTab_CompileIt(&StrTab, true)) + return error("BldProgStrTab_CompileIt failed!\n"); + + /* + * Prepare output file. + */ + FILE *pOut = fopen(pszOutFile, "wt"); + if (pOut) + { + /* + * . + */ + RTSTATUSMSGSTATS Defines = {0, 0, 0, 0}; + RTSTATUSMSGSTATS MsgShort = {0, 0, 0, 0}; + RTSTATUSMSGSTATS MsgFull = {0, 0, 0, 0}; + for (size_t i = 0; i < cStatusMsgs; i++) + { + GatherStringStats(&Defines, &s_aStatusMsgs2[i].Define); + GatherStringStats(&MsgShort, &s_aStatusMsgs2[i].MsgShort); + GatherStringStats(&MsgFull, &s_aStatusMsgs2[i].MsgFull); + } + CalcBitsForStringStats(&Defines); + CalcBitsForStringStats(&MsgShort); + CalcBitsForStringStats(&MsgFull); + printf(" Defines: max offset %#x -> %u bits, max length %#x -> bits %u\n", + Defines.offMax, Defines.cBitsOffset, (unsigned)Defines.cchMax, Defines.cBitsLength); + if (enmMode != kMode_OnlyDefines) + printf("MsgShort: max offset %#x -> %u bits, max length %#x -> bits %u\n", + MsgShort.offMax, MsgShort.cBitsOffset, (unsigned)MsgShort.cchMax, MsgShort.cBitsLength); + if (enmMode == kMode_All) + printf(" MsgFull: max offset %#x -> %u bits, max length %#x -> bits %u\n", + MsgFull.offMax, MsgFull.cBitsOffset, (unsigned)MsgFull.cchMax, MsgFull.cBitsLength); + + unsigned cBitsCodePos = CalcBitsForValue((size_t)s_aStatusMsgs2[cStatusMsgs - 1].iCode); + unsigned cBitsCodeNeg = CalcBitsForValue((size_t)-s_aStatusMsgs2[0].iCode); + unsigned cBitsCode = RT_MAX(cBitsCodePos, cBitsCodeNeg) + 1; + printf("Statuses: min %d, max %d -> %u bits\n", + s_aStatusMsgs2[0].iCode, s_aStatusMsgs2[cStatusMsgs - 1].iCode, cBitsCode); + + /* + * Print the table. + */ + fprintf(pOut, + "\n" + "#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)\n" + "# pragma pack(1)\n" + "#endif\n" + "typedef struct RTMSGENTRYINT\n" + "{\n"); + /* 16 + 16 + 8 */ + bool fOptimalLayout = true; + if ( enmMode == kMode_OnlyDefines + && cBitsCode <= 16 + && Defines.cBitsOffset <= 16 + && Defines.cBitsLength <= 8) + fprintf(pOut, + " uint16_t offDefine; /* need %2u bits, max %#x */\n" + " uint8_t cchDefine; /* need %2u bits, max %#x */\n" + " int16_t iCode; /* need %2u bits */\n", + Defines.cBitsOffset, Defines.offMax, Defines.cBitsLength, Defines.cchMax, cBitsCode); + else if ( enmMode == kMode_NoFullMsg + && cBitsCode + Defines.cBitsOffset + Defines.cBitsLength + MsgShort.cBitsOffset + MsgShort.cBitsLength <= 64) + fprintf(pOut, + " uint64_t offDefine : %2u; /* max %#x */\n" + " uint64_t cchDefine : %2u; /* max %#x */\n" + " uint64_t offMsgShort : %2u; /* max %#x */\n" + " uint64_t cchMsgShort : %2u; /* max %#x */\n" + " int64_t iCode : %2u;\n", + Defines.cBitsOffset, Defines.offMax, + Defines.cBitsLength, Defines.cchMax, + MsgShort.cBitsOffset, MsgShort.offMax, + MsgShort.cBitsLength, MsgShort.cchMax, + cBitsCode); + else if ( enmMode == kMode_All + && Defines.cBitsOffset + Defines.cBitsLength + + MsgShort.cBitsOffset + MsgShort.cBitsLength + + MsgFull.cBitsOffset + MsgFull.cBitsLength + + cBitsCode <= 96 + && cBitsCode + Defines.cBitsLength + MsgShort.cBitsLength <= 32) + fprintf(pOut, + " uint64_t offDefine : %2u; /* max %#x */\n" + " uint64_t offMsgShort : %2u; /* max %#x */\n" + " uint64_t offMsgFull : %2u; /* max %#x */\n" + " uint64_t cchMsgFull : %2u; /* max %#x */\n" + " int32_t iCode : %2u;\n" + " uint32_t cchDefine : %2u; /* max %#x */\n" + " uint32_t cchMsgShort : %2u; /* max %#x */\n", + Defines.cBitsOffset, Defines.offMax, + MsgShort.cBitsOffset, MsgShort.offMax, + MsgFull.cBitsOffset, MsgFull.offMax, + MsgFull.cBitsLength, MsgFull.cchMax, + cBitsCode, + Defines.cBitsLength, Defines.cchMax, + MsgShort.cBitsLength, MsgShort.cchMax); + else + { + fprintf(stderr, "%s: warning: Optimized structure layouts needs readjusting...\n", g_pszProgName); + fOptimalLayout = false; + fprintf(pOut, + " uint32_t offDefine : 23; /* need %u bits, max %#x */\n" + " uint32_t cchDefine : 9; /* need %u bits, max %#x */\n", + Defines.cBitsOffset, Defines.offMax, Defines.cBitsLength, Defines.cchMax); + if (enmMode != kMode_OnlyDefines) + fprintf(pOut, + " uint32_t offMsgShort : 23; /* need %u bits, max %#x */\n" + " uint32_t cchMsgShort : 9; /* need %u bits, max %#x */\n", + MsgShort.cBitsOffset, MsgShort.offMax, MsgShort.cBitsLength, MsgShort.offMax); + if (enmMode == kMode_All) + fprintf(pOut, + " uint32_t offMsgFull : 23; /* need %u bits, max %#x */\n" + " uint32_t cchMsgFull : 9; /* need %u bits, max %#x */\n", + MsgFull.cBitsOffset, MsgFull.offMax, MsgFull.cBitsLength, MsgFull.cchMax); + fprintf(pOut, + " int32_t iCode; /* need %u bits */\n", cBitsCode); + } + fprintf(pOut, + "} RTMSGENTRYINT;\n" + "typedef RTMSGENTRYINT *PCRTMSGENTRYINT;\n" + "#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)\n" + "# pragma pack()\n" + "#endif\n" + "\n" + "static const RTMSGENTRYINT g_aStatusMsgs[ /*%lu*/ ] =\n" + "{\n" + , + (unsigned long)cStatusMsgs); + + if (enmMode == kMode_All && fOptimalLayout) + for (size_t i = 0; i < cStatusMsgs; i++) + fprintf(pOut, " { %#08x, %#08x, %#08x, %3u, %6d, %3u, %3u }, /* %s */\n", + s_aStatusMsgs2[i].Define.offStrTab, + s_aStatusMsgs2[i].MsgShort.offStrTab, + s_aStatusMsgs2[i].MsgFull.offStrTab, + (unsigned)s_aStatusMsgs2[i].MsgFull.cchString, + s_aStatusMsgs2[i].iCode, + (unsigned)s_aStatusMsgs2[i].Define.cchString, + (unsigned)s_aStatusMsgs2[i].MsgShort.cchString, + s_aStatusMsgs2[i].pszDefine); + else if (enmMode == kMode_All) + for (size_t i = 0; i < cStatusMsgs; i++) + fprintf(pOut, " { %#08x, %3u, %#08x, %3u, %#08x, %3u, %8d }, /* %s */\n", + s_aStatusMsgs2[i].Define.offStrTab, + (unsigned)s_aStatusMsgs2[i].Define.cchString, + s_aStatusMsgs2[i].MsgShort.offStrTab, + (unsigned)s_aStatusMsgs2[i].MsgShort.cchString, + s_aStatusMsgs2[i].MsgFull.offStrTab, + (unsigned)s_aStatusMsgs2[i].MsgFull.cchString, + s_aStatusMsgs2[i].iCode, + s_aStatusMsgs2[i].pszDefine); + else if (enmMode == kMode_NoFullMsg) + for (size_t i = 0; i < cStatusMsgs; i++) + fprintf(pOut, " { %#08x, %3u, %#08x, %3u, %8d }, /* %s */\n", + s_aStatusMsgs2[i].Define.offStrTab, + (unsigned)s_aStatusMsgs2[i].Define.cchString, + s_aStatusMsgs2[i].MsgShort.offStrTab, + (unsigned)s_aStatusMsgs2[i].MsgShort.cchString, + s_aStatusMsgs2[i].iCode, + s_aStatusMsgs2[i].pszDefine); + else if (enmMode == kMode_OnlyDefines) + for (size_t i = 0; i < cStatusMsgs; i++) + fprintf(pOut, " { %#08x, %3u, %8d }, /* %s */\n", + s_aStatusMsgs2[i].Define.offStrTab, + (unsigned)s_aStatusMsgs2[i].Define.cchString, + s_aStatusMsgs2[i].iCode, + s_aStatusMsgs2[i].pszDefine); + else + return error("Unsupported message selection (%d)!\n", enmMode); + fprintf(pOut, + "};\n" + "\n"); + + BldProgStrTab_WriteStringTable(&StrTab, pOut, "static ", "g_", "StatusMsgStrTab"); + + /* + * Close the output file and we're done. + */ + fflush(pOut); + if (ferror(pOut)) + rcExit = error("Error writing '%s'!\n", pszOutFile); + if (fclose(pOut) != 0) + rcExit = error("Failed to close '%s' after writing it!\n", pszOutFile); + } + else + rcExit = error("Failed to open '%s' for writing!\n", pszOutFile); + return rcExit; +} + diff --git a/src/VBox/Runtime/common/err/errmsg.cpp b/src/VBox/Runtime/common/err/errmsg.cpp new file mode 100644 index 00000000..7512ff8d --- /dev/null +++ b/src/VBox/Runtime/common/err/errmsg.cpp @@ -0,0 +1,338 @@ +/* $Id: errmsg.cpp $ */ +/** @file + * IPRT - Status code messages. + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/err.h> +#include "internal/iprt.h" + +#include <iprt/asm.h> +#include <iprt/string.h> +#include <VBox/err.h> + +#include <iprt/bldprog-strtab.h> + + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ +#if (defined(IN_RT_STATIC) || defined(IPRT_ERRMSG_DEFINES_ONLY)) && !defined(IPRT_ERRMSG_NO_FULL_MSG) +/** Skip the full message in static builds to save space. + * This is defined when IPRT_ERRMSG_DEFINES_ONLY is defined. */ +# define IPRT_ERRMSG_NO_FULL_MSG +#endif + + +/********************************************************************************************************************************* +* Global Variables * +*********************************************************************************************************************************/ +#ifdef IPRT_NO_ERROR_DATA +/* Cook data just for VINF_SUCCESS so that code below compiles fine. */ +static const char g_achStrTabData[] = { "VINF_SUCCESS" }; +static const RTBLDPROGSTRTAB g_StatusMsgStrTab = { g_achStrTabData, sizeof(g_achStrTabData) - 1, 0, NULL }; +static const struct +{ + int16_t iCode; + uint8_t offDefine; + uint8_t cchDefine; + uint8_t offMsgShort; + uint8_t cchMsgShort; + uint8_t offMsgFull; + uint8_t cchMsgFull; +} g_aStatusMsgs[] = +{ + { VINF_SUCCESS, 0, 12, 0, 12, 0, 12, }, +}; +#elif defined(IPRT_ERRMSG_DEFINES_ONLY) +# include "errmsgdata-only-defines.h" +#elif defined(IPRT_ERRMSG_NO_FULL_MSG) +# include "errmsgdata-no-full-msg.h" +#else +# include "errmsgdata-all.h" +#endif + + +/** + * Looks up the message table entry for @a rc. + * + * @returns index into g_aStatusMsgs on success, ~(size_t)0 if not found. + * @param rc The status code to locate the entry for. + */ +static size_t rtErrLookup(int rc) +{ + /* + * Perform binary search (duplicate code in rtErrWinLookup). + */ + size_t iStart = 0; + size_t iEnd = RT_ELEMENTS(g_aStatusMsgs); + for (;;) + { + size_t i = iStart + (iEnd - iStart) / 2; + int const iCode = g_aStatusMsgs[i].iCode; + if (rc < iCode) + { + if (iStart < i) + iEnd = i; + else + break; + } + else if (rc > iCode) + { + i++; + if (i < iEnd) + iStart = i; + else + break; + } + else + return i; + } + +#ifdef RT_STRICT + for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++) + Assert(g_aStatusMsgs[i].iCode != rc); +#endif + + return ~(size_t)0; +} + + +RTDECL(bool) RTErrIsKnown(int rc) +{ + return rtErrLookup(rc) != ~(size_t)0; +} +RT_EXPORT_SYMBOL(RTErrIsKnown); + + +RTDECL(ssize_t) RTErrQueryDefine(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown) +{ + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) + return RTBldProgStrTabQueryString(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine, + pszBuf, cbBuf); + if (fFailIfUnknown) + return VERR_NOT_FOUND; + return RTStrFormatU32(pszBuf, cbBuf, rc, 10, 0, 0, RTSTR_F_VALSIGNED); +} +RT_EXPORT_SYMBOL(RTErrQueryDefine); + + +/** + * Helper for rtErrQueryMsgNotFound. + */ +DECLINLINE(ssize_t) rtErrQueryCopyHelper(char **ppszBuf, size_t *pcbBuf, const char *pszSrc, size_t cchSrc, ssize_t cchRet) +{ + char *pszDst = *ppszBuf; + size_t cbDst = *pcbBuf; + if (cbDst > cchSrc) + { + memcpy(pszDst, pszSrc, cchSrc); + cbDst -= cchSrc; + pszDst += cchSrc; + cchRet += cchSrc; + *pszDst = '\0'; + } + else + { + while (cbDst > 1 && cchSrc > 0) + { + *pszDst++ = *pszSrc++; + cchSrc--; + cbDst--; + } + if (cbDst > 0) + *pszDst = '\0'; + cchRet = VERR_BUFFER_OVERFLOW; + } + *ppszBuf = pszDst; + *pcbBuf = cbDst; + return cchRet; +} + + +/** + * RTErrQueryMsgShort & RTErrQueryMsgFull helper. + */ +DECL_NO_INLINE(static, ssize_t) rtErrQueryMsgNotFound(int rc, char *pszBuf, size_t cbBuf) +{ + /* Unknown Status %d (%#x) */ + ssize_t cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE("Unknown Status "), 0); + char szValue[64]; + size_t cchValue = (size_t)RTStrFormatU32(szValue, sizeof(szValue), rc, 10, 0, 0, RTSTR_F_VALSIGNED); + cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, szValue, cchValue, cchRet); + cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE(" ("), cchRet); + cchValue = (size_t)RTStrFormatU32(szValue, sizeof(szValue), rc, 16, 0, 0, RTSTR_F_SPECIAL); + cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, szValue, cchValue, cchRet); + cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE(")"), cchRet); + return cchRet; +} + + +RTDECL(ssize_t) RTErrQueryMsgShort(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown) +{ + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) +#ifdef IPRT_ERRMSG_DEFINES_ONLY + return RTBldProgStrTabQueryString(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine, + pszBuf, cbBuf); +#else + return RTBldProgStrTabQueryString(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort, + pszBuf, cbBuf); +#endif + if (fFailIfUnknown) + return VERR_NOT_FOUND; + return rtErrQueryMsgNotFound(rc, pszBuf, cbBuf); +} +RT_EXPORT_SYMBOL(RTErrQueryMsgShort); + + +RTDECL(ssize_t) RTErrQueryMsgFull(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown) +{ +#if defined(IPRT_ERRMSG_DEFINES_ONLY) || defined(IPRT_ERRMSG_NO_FULL_MSG) + return RTErrQueryMsgShort(rc, pszBuf, cbBuf, fFailIfUnknown); +#else + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) + return RTBldProgStrTabQueryString(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull, + pszBuf, cbBuf); + if (fFailIfUnknown) + return VERR_NOT_FOUND; + return rtErrQueryMsgNotFound(rc, pszBuf, cbBuf); +#endif +} +RT_EXPORT_SYMBOL(RTErrQueryMsgShort); + + +RTDECL(size_t) RTErrFormatDefine(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp) +{ + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) + return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine, + pfnOutput, pvArgOutput); + size_t cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED); + return pfnOutput(pvArgOutput, pszTmp, cchValue); +} +RT_EXPORT_SYMBOL(RTErrFormatDefine); + + +/** + * RTErrFormatMsgShort & RTErrFormatMsgFull helper. + */ +static size_t rtErrFormatMsgNotFound(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp) +{ + size_t cchRet = pfnOutput(pvArgOutput, RT_STR_TUPLE("Unknown Status ")); + size_t cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED); + cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue); + cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" (")); + cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL); + cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue); + cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(")")); + return cchRet; +} + + +RTDECL(size_t) RTErrFormatMsgShort(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp) +{ + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) +#ifndef IPRT_ERRMSG_DEFINES_ONLY + return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort, + pfnOutput, pvArgOutput); +#else + return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine, + pfnOutput, pvArgOutput); +#endif + return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp); +} +RT_EXPORT_SYMBOL(RTErrFormatMsgShort); + + +RTDECL(size_t) RTErrFormatMsgFull(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp) +{ +#ifdef IPRT_ERRMSG_NO_FULL_MSG + return RTErrFormatMsgShort(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp); +#else + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) + return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull, + pfnOutput, pvArgOutput); + return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp); +#endif +} +RT_EXPORT_SYMBOL(RTErrFormatMsgFull); + + +RTDECL(size_t) RTErrFormatMsgAll(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp) +{ + size_t idx = rtErrLookup(rc); + if (idx != ~(size_t)0) + { + size_t cchValue; + size_t cchRet = RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine, + pfnOutput, pvArgOutput); + cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" (")); + cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED); + cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue); +#ifdef IPRT_ERRMSG_DEFINES_ONLY + cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(")")); +#elif defined(IPRT_ERRMSG_NO_FULL_MSG) + cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(") - ")); + cchRet += RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort, + pfnOutput, pvArgOutput); +#else + cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(") - ")); + cchRet += RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab, + g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull, + pfnOutput, pvArgOutput); +#endif + return cchRet; + } + return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp); +} +RT_EXPORT_SYMBOL(RTErrFormatMsgAll); + diff --git a/src/VBox/Runtime/common/err/errmsg.sed b/src/VBox/Runtime/common/err/errmsg.sed new file mode 100644 index 00000000..8b1f4886 --- /dev/null +++ b/src/VBox/Runtime/common/err/errmsg.sed @@ -0,0 +1,98 @@ +# $Id: errmsg.sed $ +## @file +# IPRT - SED script for converting */err.h. +# + +# +# Copyright (C) 2006-2022 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.org. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, in version 3 of the +# License. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <https://www.gnu.org/licenses>. +# +# The contents of this file may alternatively be used under the terms +# of the Common Development and Distribution License Version 1.0 +# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +# in the VirtualBox distribution, in which case the provisions of the +# CDDL are applicable instead of those of the GPL. +# +# You may elect to license modified versions of this file under the +# terms and conditions of either the GPL or the CDDL or both. +# +# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +# + +# Handle text inside the markers. +/SED-START/,/SED-END/{ + +# if (#define) goto defines +/^[[:space:]]*#[[:space:]]*define/b defines + +# if (/**) goto description +/\/\*\*/b description + +} + +# Everything else is deleted! +d +b end + + +## +# Convert the defines +:defines +s/^[[:space:]]*#[[:space:]]*define[[:space:]]*\([[:alnum:]_]*\)[[:space:]]*\(.*\)[[:space:]]*$/ "\1",\n \1, false }, / +b end + +## +# Convert descriptive comments. /** desc */ +:description + +# Read all the lines belonging to the comment into the buffer. +:look-for-end-of-comment +/\*\//bend-of-comment +N +blook-for-end-of-comment +:end-of-comment + +# anything with @{ and @} is skipped +/@[\{\}]/d + +# Fix double spaces +s/[[:space:]][[:space:]]/ /g + +# Fix \# sequences (doxygen needs them, we don't). +s/\\#/#/g + +# insert punctuation. +s/\([^.[:space:]]\)[[:space:]]*\*\//\1. \*\// + +# convert /** short. more +s/[[:space:]]*\/\*\*[[:space:]]*/ { NULL, \"/ +s/ { NULL, \"\([^.!?"]*[.!?][.!?]*\)/ { \"\1\",\n \"\1/ + +# terminate the string +s/[[:space:]]*\*\//\"\,/ + +# translate empty lines into new-lines (only one, please). +s/[[:space:]]*[[:space:]]\*[[:space:]][[:space:]]*\*[[:space:]][[:space:]]*/\\n/g + +# remove asterics. +s/[[:space:]]*[[:space:]]\*[[:space:]][[:space:]]*/ /g +b end + + +# next expression +:end diff --git a/src/VBox/Runtime/common/err/errmsgcom.sed b/src/VBox/Runtime/common/err/errmsgcom.sed new file mode 100644 index 00000000..b325b8b6 --- /dev/null +++ b/src/VBox/Runtime/common/err/errmsgcom.sed @@ -0,0 +1,76 @@ +# $Id: errmsgcom.sed $ +## @file +# IPRT - SED script for converting COM errors +# + +# +# Copyright (C) 2006-2022 Oracle and/or its affiliates. +# +# This file is part of VirtualBox base platform packages, as +# available from https://www.virtualbox.org. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, in version 3 of the +# License. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <https://www.gnu.org/licenses>. +# +# The contents of this file may alternatively be used under the terms +# of the Common Development and Distribution License Version 1.0 +# (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +# in the VirtualBox distribution, in which case the provisions of the +# CDDL are applicable instead of those of the GPL. +# +# You may elect to license modified versions of this file under the +# terms and conditions of either the GPL or the CDDL or both. +# +# SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +# + +# we only care about message definitions +/No symbolic name defined/b skip_it +\/\/ MessageId: /b messageid +d +b end + + +# Everything else is deleted! +:skip_it +d +b end + + +# +# A message ID we care about +# +:messageid +# concatenate the next four lines to the string +N +N +N +N +{ + # remove DOS <CR>. + s/\r//g + # remove the message ID + s/\/\/ MessageId: //g + # remove the stuff in between + s/\/\/\n\/\/ MessageText:\n\/\/\n\/\/ *//g + # backslashes have to be escaped + s/\\/\\\\/g + # double quotes have to be escaped, too + s/"/\\"/g + # output C array entry + s/\([[:alnum:]_]*\)[\t ]*\n\(.*\)[\t ]*$/{ "\2", "\1", \1 }, / +} +b end + +# next expression +:end diff --git a/src/VBox/Runtime/common/err/errmsgxpcom.cpp b/src/VBox/Runtime/common/err/errmsgxpcom.cpp new file mode 100644 index 00000000..78577e79 --- /dev/null +++ b/src/VBox/Runtime/common/err/errmsgxpcom.cpp @@ -0,0 +1,170 @@ +/* $Id: errmsgxpcom.cpp $ */ +/** @file + * IPRT - Status code messages for XPCOM. + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include <iprt/errcore.h> +#include "internal/iprt.h" + +#include <iprt/asm.h> +#include <iprt/string.h> +#include <iprt/errcore.h> + + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ +typedef uint32_t VBOXSTATUSTYPE; /* used by errmsgvboxcomdata.h */ + + +/********************************************************************************************************************************* +* Global Variables * +*********************************************************************************************************************************/ +/** Array of messages. + * The data is generated by a sed script. + */ +static const RTCOMERRMSG g_aStatusMsgs[] = +{ +#define MY_ERR(_def, _desc, _val) { _desc, _def, _val } + + MY_ERR("NS_OK", "Success", UINT32_C(0x00000000)), + MY_ERR("NS_ERROR_NOT_IMPLEMENTED", "Not implemented", UINT32_C(0x80004001)), + MY_ERR("NS_ERROR_NO_INTERFACE", "Interface not supported", UINT32_C(0x80004002)), + MY_ERR("NS_ERROR_INVALID_POINTER", "Invalid pointer value", UINT32_C(0x80004003)), + MY_ERR("NS_ERROR_ABORT", "Operation aborted", UINT32_C(0x80004004)), + MY_ERR("NS_ERROR_FAILURE", "Operation failed", UINT32_C(0x80004005)), + MY_ERR("NS_ERROR_CALL_FAILED", "Call to remote object failed", UINT32_C(0x800706be)), + MY_ERR("NS_ERROR_UNEXPECTED", "Unexpected error", UINT32_C(0x8000ffff)), + + MY_ERR("NS_ERROR_CANNOT_CONVERT_DATA", "Cannot convert data", UINT32_C(0x80010001)), + MY_ERR("NS_ERROR_OBJECT_IS_IMMUTABLE", "Object is immutable", UINT32_C(0x80010002)), + MY_ERR("NS_ERROR_LOSS_OF_SIGNIFICANT_DATA", "Loss of significant data", UINT32_C(0x80010003)), + MY_ERR("NS_ERROR_PROXY_INVALID_IN_PARAMETER", "Cannot proxy an IN parameter", UINT32_C(0x80010010)), + MY_ERR("NS_ERROR_PROXY_INVALID_OUT_PARAMETER", "Cannot proxy an OUT parameter", UINT32_C(0x80010011)), + MY_ERR("NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA", "Loss of insignificant data", UINT32_C(0x00010001)), + + MY_ERR("E_ACCESSDENIED", "Access denied", UINT32_C(0x80070005)), /* VirtualBox addition */ + MY_ERR("NS_ERROR_OUT_OF_MEMORY", "Memory allocation failed", UINT32_C(0x8007000e)), + MY_ERR("NS_ERROR_INVALID_ARG", "Invalid argument value", UINT32_C(0x80070057)), + + MY_ERR("NS_ERROR_NO_AGGREGATION", "Class does not allow aggregation", UINT32_C(0x80040110)), + MY_ERR("NS_ERROR_NOT_AVAILABLE", "Resource not available", UINT32_C(0x80040111)), + MY_ERR("NS_ERROR_FACTORY_NOT_REGISTERED", "Class not registered", UINT32_C(0x80040154)), + MY_ERR("NS_ERROR_FACTORY_REGISTER_AGAIN", "Cannot be registered, try again later", UINT32_C(0x80040155)), + MY_ERR("NS_ERROR_FACTORY_NOT_LOADED", "Dynamically loaded factory cannot be found", UINT32_C(0x800401f8)), + MY_ERR("NS_ERROR_FACTORY_EXISTS", "Factory already exists", UINT32_C(0xc1f30100)), + MY_ERR("NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT", "Factory does not support signatures", UINT32_C(0xc1f30101)), + MY_ERR("NS_ERROR_NOT_INITIALIZED", "Instance not initialized", UINT32_C(0xc1f30001)), + MY_ERR("NS_ERROR_ALREADY_INITIALIZED", "Instance already initialized", UINT32_C(0xc1f30002)), + + MY_ERR("NS_BASE_STREAM_CLOSED", "Stream closed", UINT32_C(0x80470002)), + MY_ERR("NS_BASE_STREAM_OSERROR", "Operative system stream error", UINT32_C(0x80470003)), + MY_ERR("NS_BASE_STREAM_ILLEGAL_ARGS", "Illegal argument to stream method", UINT32_C(0x80470004)), + MY_ERR("NS_BASE_STREAM_NO_CONVERTER", "No stream converter", UINT32_C(0x80470005)), + MY_ERR("NS_BASE_STREAM_BAD_CONVERSION", "Badstream conversion", UINT32_C(0x80470006)), + MY_ERR("NS_BASE_STREAM_WOULD_BLOCK", "Stream operation would block", UINT32_C(0x80470007)), + + MY_ERR("NS_ERROR_FILE_UNRECOGNIZED_PATH", "Unrecognized path", UINT32_C(0x80520001)), + MY_ERR("NS_ERROR_FILE_UNRESOLVABLE_SYMLINK", "NS_ERROR_FILE_UNRESOLVABLE_SYMLINK", UINT32_C(0x80520002)), + MY_ERR("NS_ERROR_FILE_EXECUTION_FAILED", "NS_ERROR_FILE_EXECUTION_FAILED", UINT32_C(0x80520003)), + MY_ERR("NS_ERROR_FILE_UNKNOWN_TYPE", "NS_ERROR_FILE_UNKNOWN_TYPE", UINT32_C(0x80520004)), + MY_ERR("NS_ERROR_FILE_DESTINATION_NOT_DIR", "NS_ERROR_FILE_DESTINATION_NOT_DIR", UINT32_C(0x80520005)), + MY_ERR("NS_ERROR_FILE_TARGET_DOES_NOT_EXIST", "NS_ERROR_FILE_TARGET_DOES_NOT_EXIST", UINT32_C(0x80520006)), + MY_ERR("NS_ERROR_FILE_COPY_OR_MOVE_FAILED", "NS_ERROR_FILE_COPY_OR_MOVE_FAILED", UINT32_C(0x80520007)), + MY_ERR("NS_ERROR_FILE_ALREADY_EXISTS", "NS_ERROR_FILE_ALREADY_EXISTS", UINT32_C(0x80520008)), + MY_ERR("NS_ERROR_FILE_INVALID_PATH", "NS_ERROR_FILE_INVALID_PATH", UINT32_C(0x80520009)), + MY_ERR("NS_ERROR_FILE_DISK_FULL", "NS_ERROR_FILE_DISK_FULL", UINT32_C(0x8052000a)), + MY_ERR("NS_ERROR_FILE_CORRUPTED", "NS_ERROR_FILE_CORRUPTED", UINT32_C(0x8052000b)), + MY_ERR("NS_ERROR_FILE_NOT_DIRECTORY", "NS_ERROR_FILE_NOT_DIRECTORY", UINT32_C(0x8052000c)), + MY_ERR("NS_ERROR_FILE_IS_DIRECTORY", "NS_ERROR_FILE_IS_DIRECTORY", UINT32_C(0x8052000d)), + MY_ERR("NS_ERROR_FILE_IS_LOCKED", "NS_ERROR_FILE_IS_LOCKED", UINT32_C(0x8052000e)), + MY_ERR("NS_ERROR_FILE_TOO_BIG", "NS_ERROR_FILE_TOO_BIG", UINT32_C(0x8052000f)), + MY_ERR("NS_ERROR_FILE_NO_DEVICE_SPACE", "NS_ERROR_FILE_NO_DEVICE_SPACE", UINT32_C(0x80520010)), + MY_ERR("NS_ERROR_FILE_NAME_TOO_LONG", "NS_ERROR_FILE_NAME_TOO_LONG", UINT32_C(0x80520011)), + MY_ERR("NS_ERROR_FILE_NOT_FOUND", "NS_ERROR_FILE_NOT_FOUND", UINT32_C(0x80520012)), + MY_ERR("NS_ERROR_FILE_READ_ONLY", "NS_ERROR_FILE_READ_ONLY", UINT32_C(0x80520013)), + MY_ERR("NS_ERROR_FILE_DIR_NOT_EMPTY", "NS_ERROR_FILE_DIR_NOT_EMPTY", UINT32_C(0x80520014)), + MY_ERR("NS_ERROR_FILE_ACCESS_DENIED", "NS_ERROR_FILE_ACCESS_DENIED", UINT32_C(0x80520015)), + MY_ERR("NS_SUCCESS_FILE_DIRECTORY_EMPTY", "NS_SUCCESS_FILE_DIRECTORY_EMPTY", UINT32_C(0x00520001)), + MY_ERR("NS_ERROR_SOCKET_FAIL", "IPC daemon socket error", UINT32_C(0xc1f30200)), /* new XPCOM error code */ + +#if defined(VBOX) && !defined(IN_GUEST) && !defined(DOXYGEN_RUNNING) +# include "errmsgvboxcomdata.h" +#endif + + { NULL, NULL, 0 } +#undef MY_ERR +}; + + +/** Temporary buffers to format unknown messages in. + * @{ + */ +static char g_aszUnknownStr[8][64]; +static RTCOMERRMSG g_aUnknownMsgs[8] = +{ + { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 }, + { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 }, + { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 }, + { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 }, + { &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], 0 }, + { &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], 0 }, + { &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], 0 }, + { &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], 0 } +}; +/** Last used index in g_aUnknownMsgs. */ +static volatile uint32_t g_iUnknownMsgs; +/** @} */ + + +RTDECL(PCRTCOMERRMSG) RTErrCOMGet(uint32_t rc) +{ + unsigned i; + for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1; i++) + if (g_aStatusMsgs[i].iCode == rc) + return &g_aStatusMsgs[i]; + + /* + * Need to use the temporary stuff. + */ + int32_t iMsg = (ASMAtomicIncU32(&g_iUnknownMsgs) - 1) % RT_ELEMENTS(g_aUnknownMsgs); + RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "Unknown Status 0x%X", rc); + return &g_aUnknownMsgs[iMsg]; +} +RT_EXPORT_SYMBOL(RTErrCOMGet); + diff --git a/src/VBox/Runtime/common/err/nocrt-strerror.cpp b/src/VBox/Runtime/common/err/nocrt-strerror.cpp new file mode 100644 index 00000000..047cbf46 --- /dev/null +++ b/src/VBox/Runtime/common/err/nocrt-strerror.cpp @@ -0,0 +1,464 @@ +/* $Id: nocrt-strerror.cpp $ */ +/** @file + * IPRT - No-CRT - Convert errno value to string. + */ + +/* + * Copyright (C) 2006-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#define IPRT_NO_CRT_FOR_3RD_PARTY +#include "internal/nocrt.h" +#include <iprt/nocrt/string.h> +#include <iprt/nocrt/errno.h> +#include <iprt/assert.h> +#include <iprt/log.h> + + +#undef strerror +const char *RT_NOCRT(strerror)(int iErrNo) +{ + /* + * Process error codes. + * + * (Use a switch and not a table since the numbers vary among compilers + * and OSes. So we let the compiler switch optimizer handle speed issues.) + * + * This switch is arranged like the Linux i386 errno.h! This switch is mirrored + * by RTErrConvertToErrno and RTErrConvertFromErrno. + */ + switch (iErrNo) + { /* Linux number */ + case 0: return "no error"; +#ifdef EPERM + RT_CASE_RET_STR(EPERM); /* 1 */ +#endif +#ifdef ENOENT + RT_CASE_RET_STR(ENOENT); +#endif +#ifdef ESRCH + RT_CASE_RET_STR(ESRCH); +#endif +#ifdef EINTR + RT_CASE_RET_STR(EINTR); +#endif +#ifdef EIO + RT_CASE_RET_STR(EIO); +#endif +#ifdef ENXIO + RT_CASE_RET_STR(ENXIO); /** @todo fix this duplicate error */ +#endif +#ifdef E2BIG + RT_CASE_RET_STR(E2BIG); +#endif +#ifdef ENOEXEC + RT_CASE_RET_STR(ENOEXEC); +#endif +#ifdef EBADF + RT_CASE_RET_STR(EBADF); +#endif +#ifdef ECHILD + RT_CASE_RET_STR(ECHILD); /* 10 */ /** @todo fix duplicate error */ +#endif +#ifdef EAGAIN + RT_CASE_RET_STR(EAGAIN); +#endif +#ifdef ENOMEM + RT_CASE_RET_STR(ENOMEM); +#endif +#ifdef EACCES + RT_CASE_RET_STR(EACCES); /** @todo fix duplicate error */ +#endif +#ifdef EFAULT + RT_CASE_RET_STR(EFAULT); +#endif +#ifdef ENOTBLK + RT_CASE_RET_STR(ENOTBLK); +#endif +#ifdef EBUSY + RT_CASE_RET_STR(EBUSY); +#endif +#ifdef EEXIST + RT_CASE_RET_STR(EEXIST); +#endif +#ifdef EXDEV + RT_CASE_RET_STR(EXDEV); +#endif +#ifdef ENODEV + RT_CASE_RET_STR(ENODEV); /** @todo fix duplicate error */ +#endif +#ifdef ENOTDIR + RT_CASE_RET_STR(ENOTDIR); /* 20 */ +#endif +#ifdef EISDIR + RT_CASE_RET_STR(EISDIR); +#endif +#ifdef EINVAL + RT_CASE_RET_STR(EINVAL); +#endif +#ifdef ENFILE + RT_CASE_RET_STR(ENFILE); /** @todo fix duplicate error */ +#endif +#ifdef EMFILE + RT_CASE_RET_STR(EMFILE); +#endif +#ifdef ENOTTY + RT_CASE_RET_STR(ENOTTY); +#endif +#ifdef ETXTBSY + RT_CASE_RET_STR(ETXTBSY); +#endif +#ifdef EFBIG + RT_CASE_RET_STR(EFBIG); +#endif +#ifdef ENOSPC + RT_CASE_RET_STR(ENOSPC); +#endif +#ifdef ESPIPE + RT_CASE_RET_STR(ESPIPE); +#endif +#ifdef EROFS + RT_CASE_RET_STR(EROFS); /* 30 */ +#endif +#ifdef EMLINK + RT_CASE_RET_STR(EMLINK); +#endif +#ifdef EPIPE + RT_CASE_RET_STR(EPIPE); +#endif +#ifdef EDOM + RT_CASE_RET_STR(EDOM); /** @todo fix duplicate error */ +#endif +#ifdef ERANGE + RT_CASE_RET_STR(ERANGE); /** @todo fix duplicate error */ +#endif +#ifdef EDEADLK + RT_CASE_RET_STR(EDEADLK); +#endif +#ifdef ENAMETOOLONG + RT_CASE_RET_STR(ENAMETOOLONG); +#endif +#ifdef ENOLCK + RT_CASE_RET_STR(ENOLCK); +#endif +#ifdef ENOSYS /** @todo map this differently on solaris. */ + RT_CASE_RET_STR(ENOSYS); +#endif +#ifdef ENOTEMPTY + RT_CASE_RET_STR(ENOTEMPTY); +#endif +#ifdef ELOOP + RT_CASE_RET_STR(ELOOP); /* 40 */ +#endif + //41?? +#ifdef ENOMSG + RT_CASE_RET_STR(ENOMSG); +#endif +#ifdef EIDRM + RT_CASE_RET_STR(EIDRM); +#endif +#ifdef ECHRNG + RT_CASE_RET_STR(ECHRNG); +#endif +#ifdef EL2NSYNC + RT_CASE_RET_STR(EL2NSYNC); +#endif +#ifdef EL3HLT + RT_CASE_RET_STR(EL3HLT); +#endif +#ifdef EL3RST + RT_CASE_RET_STR(EL3RST); +#endif +#ifdef ELNRNG + RT_CASE_RET_STR(ELNRNG); +#endif +#ifdef EUNATCH + RT_CASE_RET_STR(EUNATCH); +#endif +#ifdef ENOCSI + RT_CASE_RET_STR(ENOCSI); +#endif +#ifdef EL2HLT + RT_CASE_RET_STR(EL2HLT); +#endif +#ifdef EBADE + RT_CASE_RET_STR(EBADE); +#endif +#ifdef EBADR + RT_CASE_RET_STR(EBADR); +#endif +#ifdef EXFULL + RT_CASE_RET_STR(EXFULL); +#endif +#ifdef ENOANO + RT_CASE_RET_STR(ENOANO); +#endif +#ifdef EBADRQC + RT_CASE_RET_STR(EBADRQC); +#endif +#ifdef EBADSLT + RT_CASE_RET_STR(EBADSLT); +#endif + //case 58: +#ifdef EBFONT + RT_CASE_RET_STR(EBFONT); +#endif +#ifdef ENOSTR + RT_CASE_RET_STR(ENOSTR); +#endif +#ifdef ENODATA + RT_CASE_RET_STR(ENODATA); +#endif +#ifdef ETIME + RT_CASE_RET_STR(ETIME); +#endif +#ifdef ENOSR + RT_CASE_RET_STR(ENOSR); +#endif +#ifdef ENONET + RT_CASE_RET_STR(ENONET); +#endif +#ifdef ENOPKG + RT_CASE_RET_STR(ENOPKG); +#endif +#ifdef EREMOTE + RT_CASE_RET_STR(EREMOTE); +#endif +#ifdef ENOLINK + RT_CASE_RET_STR(ENOLINK); +#endif +#ifdef EADV + RT_CASE_RET_STR(EADV); +#endif +#ifdef ESRMNT + RT_CASE_RET_STR(ESRMNT); +#endif +#ifdef ECOMM + RT_CASE_RET_STR(ECOMM); +#endif +#ifdef EPROTO + RT_CASE_RET_STR(EPROTO); +#endif +#ifdef EMULTIHOP + RT_CASE_RET_STR(EMULTIHOP); +#endif +#ifdef EDOTDOT + RT_CASE_RET_STR(EDOTDOT); +#endif +#ifdef EBADMSG + RT_CASE_RET_STR(EBADMSG); +#endif +#ifdef EOVERFLOW + RT_CASE_RET_STR(EOVERFLOW); /** @todo fix duplicate error? */ +#endif +#ifdef ENOTUNIQ + RT_CASE_RET_STR(ENOTUNIQ); +#endif +#ifdef EBADFD + RT_CASE_RET_STR(EBADFD); /** @todo fix duplicate error? */ +#endif +#ifdef EREMCHG + RT_CASE_RET_STR(EREMCHG); +#endif +#ifdef ELIBACC + RT_CASE_RET_STR(ELIBACC); +#endif +#ifdef ELIBBAD + RT_CASE_RET_STR(ELIBBAD); +#endif +#ifdef ELIBSCN + RT_CASE_RET_STR(ELIBSCN); +#endif +#ifdef ELIBMAX + RT_CASE_RET_STR(ELIBMAX); +#endif +#ifdef ELIBEXEC + RT_CASE_RET_STR(ELIBEXEC); +#endif +#ifdef EILSEQ + RT_CASE_RET_STR(EILSEQ); +#endif +#ifdef ERESTART + RT_CASE_RET_STR(ERESTART);/** @todo fix duplicate error?*/ +#endif +#ifdef ESTRPIPE + RT_CASE_RET_STR(ESTRPIPE); +#endif +#ifdef EUSERS + RT_CASE_RET_STR(EUSERS); +#endif +#ifdef ENOTSOCK + RT_CASE_RET_STR(ENOTSOCK); +#endif +#ifdef EDESTADDRREQ + RT_CASE_RET_STR(EDESTADDRREQ); +#endif +#ifdef EMSGSIZE + RT_CASE_RET_STR(EMSGSIZE); +#endif +#ifdef EPROTOTYPE + RT_CASE_RET_STR(EPROTOTYPE); +#endif +#ifdef ENOPROTOOPT + RT_CASE_RET_STR(ENOPROTOOPT); +#endif +#ifdef EPROTONOSUPPORT + RT_CASE_RET_STR(EPROTONOSUPPORT); +#endif +#ifdef ESOCKTNOSUPPORT + RT_CASE_RET_STR(ESOCKTNOSUPPORT); +#endif +#ifdef EOPNOTSUPP /** @todo map this differently on solaris. */ + RT_CASE_RET_STR(EOPNOTSUPP); +#endif +#ifdef EPFNOSUPPORT + RT_CASE_RET_STR(EPFNOSUPPORT); +#endif +#ifdef EAFNOSUPPORT + RT_CASE_RET_STR(EAFNOSUPPORT); +#endif +#ifdef EADDRINUSE + RT_CASE_RET_STR(EADDRINUSE); +#endif +#ifdef EADDRNOTAVAIL + RT_CASE_RET_STR(EADDRNOTAVAIL); +#endif +#ifdef ENETDOWN + RT_CASE_RET_STR(ENETDOWN); +#endif +#ifdef ENETUNREACH + RT_CASE_RET_STR(ENETUNREACH); +#endif +#ifdef ENETRESET + RT_CASE_RET_STR(ENETRESET); +#endif +#ifdef ECONNABORTED + RT_CASE_RET_STR(ECONNABORTED); +#endif +#ifdef ECONNRESET + RT_CASE_RET_STR(ECONNRESET); +#endif +#ifdef ENOBUFS + RT_CASE_RET_STR(ENOBUFS); +#endif +#ifdef EISCONN + RT_CASE_RET_STR(EISCONN); +#endif +#ifdef ENOTCONN + RT_CASE_RET_STR(ENOTCONN); +#endif +#ifdef ESHUTDOWN + RT_CASE_RET_STR(ESHUTDOWN); +#endif +#ifdef ETOOMANYREFS + RT_CASE_RET_STR(ETOOMANYREFS); +#endif +#ifdef ETIMEDOUT + RT_CASE_RET_STR(ETIMEDOUT); +#endif +#ifdef ECONNREFUSED + RT_CASE_RET_STR(ECONNREFUSED); +#endif +#ifdef EHOSTDOWN + RT_CASE_RET_STR(EHOSTDOWN); +#endif +#ifdef EHOSTUNREACH + RT_CASE_RET_STR(EHOSTUNREACH); +#endif +#ifdef EALREADY +# if !defined(ENOLCK) || (EALREADY != ENOLCK) + RT_CASE_RET_STR(EALREADY); +# endif +#endif +#ifdef EINPROGRESS +# if !defined(ENODEV) || (EINPROGRESS != ENODEV) + RT_CASE_RET_STR(EINPROGRESS); +# endif +#endif +#ifdef ESTALE + RT_CASE_RET_STR(ESTALE); /* 116: Stale NFS file handle */ +#endif +#ifdef EUCLEAN + RT_CASE_RET_STR(EUCLEAN); +#endif +#ifdef ENOTNAM + RT_CASE_RET_STR(ENOTNAM); +#endif +#ifdef ENAVAIL + RT_CASE_RET_STR(ENAVAIL); +#endif +#ifdef EISNAM + RT_CASE_RET_STR(EISNAM); +#endif +#ifdef EREMOTEIO + RT_CASE_RET_STR(EREMOTEIO); +#endif +#ifdef EDQUOT + RT_CASE_RET_STR(EDQUOT); /** @todo fix duplicate error */ +#endif +#ifdef ENOMEDIUM + RT_CASE_RET_STR(ENOMEDIUM); +#endif +#ifdef EMEDIUMTYPE + RT_CASE_RET_STR(EMEDIUMTYPE); +#endif +#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) + RT_CASE_RET_STR(EWOULDBLOCK); +#endif + + /* Non-linux */ + +#ifdef EPROCLIM + RT_CASE_RET_STR(EPROCLIM); +#endif +#ifdef EDOOFUS +# if EDOOFUS != EINVAL + RT_CASE_RET_STR(EDOOFUS); +# endif +#endif +#ifdef ENOTSUP +# ifndef EOPNOTSUPP + RT_CASE_RET_STR(ENOTSUP); +# else +# if ENOTSUP != EOPNOTSUPP + RT_CASE_RET_STR(ENOTSUP); +# endif +# endif +#endif + default: + AssertLogRelMsgFailedReturn(("Unhandled error code %d\n", iErrNo), "unknown-errno-value"); + } +} +RT_ALIAS_AND_EXPORT_NOCRT_SYMBOL(strerror); + |