summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs-2.0/mpr/mprLog.c
diff options
context:
space:
mode:
authorDerrell Lipman <derrell@samba.org>2006-09-26 16:58:27 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:20:21 -0500
commit77e8402dd68079c0e245fc8826daf2c6ad334766 (patch)
tree64f65c7d3fb7f3aa970311f70e3f8bae4c0fc40c /source4/lib/appweb/ejs-2.0/mpr/mprLog.c
parent06de0f0b743056ba845de000339d4c3beb7cb845 (diff)
downloadsamba-77e8402dd68079c0e245fc8826daf2c6ad334766.tar.gz
samba-77e8402dd68079c0e245fc8826daf2c6ad334766.tar.bz2
samba-77e8402dd68079c0e245fc8826daf2c6ad334766.zip
r18925: Add current snapshot of the ejs-2.0 code. Tridge, will you be incorporating this?
(This used to be commit 917af234a8d517f82bd42256a940608a16b988f4)
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/mpr/mprLog.c')
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprLog.c602
1 files changed, 602 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprLog.c b/source4/lib/appweb/ejs-2.0/mpr/mprLog.c
new file mode 100644
index 0000000000..1eb175ed95
--- /dev/null
+++ b/source4/lib/appweb/ejs-2.0/mpr/mprLog.c
@@ -0,0 +1,602 @@
+/**
+ * @file mprLog.c
+ * @brief Mbedthis Portable Runtime (MPR) Logging and error reporting.
+ * @remarks We always provide these routines.
+ */
+
+/*********************************** License **********************************/
+/*
+ * @copy default
+ *
+ * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
+ *
+ * This software is distributed under commercial and open source licenses.
+ * You may use the GPL open source license described below or you may acquire
+ * a commercial license from Mbedthis Software. You agree to be fully bound
+ * by the terms of either license. Consult the LICENSE.TXT distributed with
+ * this software for full details.
+ *
+ * This software is open source; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See the GNU General Public License for more
+ * details at: http://www.mbedthis.com/downloads/gplLicense.html
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * This GPL license does NOT permit incorporating this software into
+ * proprietary programs. If you are unable to comply with the GPL, you must
+ * acquire a commercial license to use this software. Commercial licenses
+ * for this software and support services are available from Mbedthis
+ * Software at http://www.mbedthis.com
+ *
+ * @end
+ */
+
+#include "mpr.h"
+
+/****************************** Forward Declarations **************************/
+
+static void defaultLogHandler(MPR_LOC_DEC(ctx, loc), int flags,
+ int level, const char *msg);
+static void logOutput(MPR_LOC_DEC(ctx, loc), int flags, int level,
+ const char *msg);
+
+/************************************ Code ************************************/
+
+void mprLog(MprCtx ctx, int level, const char *fmt, ...)
+{
+ va_list args;
+ char *buf;
+
+ if (level > mprGetLogLevel(ctx)) {
+ return;
+ }
+
+ va_start(args, fmt);
+ mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
+ va_end(args);
+
+ logOutput(MPR_LOC_ARGS(ctx), MPR_LOG_SRC, level, buf);
+
+ va_end(args);
+ mprFree(buf);
+}
+
+/*****************************************************************************/
+/*
+ * Do raw output
+ */
+
+void mprRawLog(MprCtx ctx, const char *fmt, ...)
+{
+ va_list args;
+ char *buf;
+ int len;
+
+ va_start(args, fmt);
+ len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
+ va_end(args);
+
+ logOutput(MPR_LOC_ARGS(ctx), MPR_RAW, 0, buf);
+ mprFree(buf);
+}
+
+/*****************************************************************************/
+/*
+ * Handle an error
+ */
+
+void mprError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
+{
+ va_list args;
+ char *buf;
+ int len;
+
+ va_start(args, fmt);
+ len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
+ va_end(args);
+
+ logOutput(MPR_LOC_PASS(ctx, loc), MPR_ERROR_MSG | MPR_ERROR_SRC, 0, buf);
+
+ mprFree(buf);
+}
+
+/*****************************************************************************/
+/*
+ * Handle an error that should be displayed to the user
+ */
+
+void mprUserError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
+{
+ va_list args;
+ char *buf;
+ int len;
+
+ va_start(args, fmt);
+ len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
+ va_end(args);
+
+ logOutput(MPR_LOC_PASS(ctx, loc), MPR_USER_MSG | MPR_ERROR_SRC, 0, buf);
+
+ mprFree(buf);
+}
+
+/*****************************************************************************/
+/*
+ * Handle a fatal error. Forcibly shutdown the application.
+ */
+
+void mprFatalError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
+{
+ va_list args;
+ char *buf;
+ int len;
+
+ va_start(args, fmt);
+ len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
+ va_end(args);
+
+ logOutput(MPR_LOC_PASS(ctx, loc), MPR_USER_MSG | MPR_FATAL_SRC, 0, buf);
+
+ mprFree(buf);
+
+#if BREW
+ mprSignalExit(ctx);
+#else
+ exit(2);
+#endif
+}
+
+/*****************************************************************************/
+/*
+ * Handle a program assertion
+ */
+
+void mprAssertError(MPR_LOC_DEC(ctx, loc), const char *msg)
+{
+ logOutput(MPR_LOC_PASS(ctx, loc), MPR_ASSERT_MSG | MPR_ASSERT_SRC, 0, msg);
+}
+
+/*****************************************************************************/
+/*
+ * Handle an error
+ */
+
+void mprStaticError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
+{
+ va_list args;
+ int len;
+ char buf[MPR_MAX_STRING];
+
+ va_start(args, fmt);
+ len = mprVsprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ logOutput(MPR_LOC_PASS(ctx, loc), MPR_ERROR_MSG | MPR_ERROR_SRC, 0, buf);
+}
+
+/*****************************************************************************/
+/*
+ * Direct output to the standard output. Does not hook into the logging
+ * system and does not allocate memory.
+ */
+
+void mprStaticAssert(const char *loc, const char *msg)
+{
+#if BLD_DEBUG
+ char buf[MPR_MAX_STRING];
+ int len;
+
+ len = mprSprintf(buf, sizeof(buf), "Assertion %s, failed at %s\n",
+ msg, loc);
+ mprBreakpoint(loc, buf);
+
+#if BLD_HOST_UNIX
+ /*
+ * MOB -- but is stdout always okay to use
+ */
+ write(1, buf, len);
+#elif BREW || WIN
+ /*
+ * Only time we use printf. We can't get an alloc context so we have
+ * to use real print
+ */
+#if BREW && !BREW_SIMULATOR
+ printf(" MP: %s\n", buf);
+#else
+ printf("%s\n", buf);
+#endif
+
+#endif
+#endif
+}
+
+/*****************************************************************************/
+
+int mprGetLogLevel(MprCtx ctx)
+{
+ return mprGetApp(ctx)->logLevel;
+}
+
+/******************************************************************************/
+
+void mprSetLogLevel(MprCtx ctx, int level)
+{
+ mprGetApp(ctx)->logLevel = level;
+}
+
+/*****************************************************************************/
+/*
+ * Output a log message to the log handler
+ */
+
+static void logOutput(MPR_LOC_DEC(ctx, loc), int flags, int level,
+ const char *msg)
+{
+ MprLogHandler handler;
+
+ if (flags & (MPR_ERROR_SRC | MPR_FATAL_SRC | MPR_ASSERT_SRC)) {
+ mprBreakpoint(MPR_LOC, 0);
+ }
+
+ mprAssert(ctx != 0);
+ handler = mprGetApp(ctx)->logHandler;
+ if (handler != 0) {
+ (handler)(MPR_LOC_PASS(ctx, loc), flags, level, msg);
+ return;
+ }
+ defaultLogHandler(MPR_LOC_PASS(ctx, loc), flags, level, msg);
+}
+
+/*****************************************************************************/
+/*
+ * Default log output is just to the console
+ */
+
+static void defaultLogHandler(MPR_LOC_DEC(ctx, loc), int flags,
+ int level, const char *msg)
+{
+ MprApp *app;
+ char *prefix;
+
+ app = mprGetApp(ctx);
+ prefix = app->name;
+
+ while (*msg == '\n') {
+ mprPrintf(ctx, "\n");
+ msg++;
+ }
+
+ if (flags & MPR_LOG_SRC) {
+#if BREW && !BREW_SIMULATOR
+ mprPrintf(ctx, "%s\n", msg);
+#else
+ mprPrintf(ctx, "%s: %d: %s\n", prefix, level, msg);
+#endif
+
+ } else if (flags & MPR_ERROR_SRC) {
+ /*
+ * Use static printing to avoid malloc when the messages are small.
+ * This is important for memory allocation errors.
+ */
+ if (strlen(msg) < (MPR_MAX_STRING - 32)) {
+ mprStaticPrintf(ctx, "%s: Error: %s\n", prefix, msg);
+ } else {
+ mprPrintf(ctx, "%s: Error: %s\n", prefix, msg);
+ }
+
+ } else if (flags & MPR_FATAL_SRC) {
+ mprPrintf(ctx, "%s: Fatal: %s\n", prefix, msg);
+
+ } else if (flags & MPR_ASSERT_SRC) {
+#if BLD_FEATURE_ALLOC_LEAK_TRACK
+ mprPrintf(ctx, "%s: Assertion %s, failed at %s\n", prefix, msg, loc);
+#else
+ mprPrintf(ctx, "%s: Assertion %s, failed\n", prefix, msg);
+#endif
+
+ } else if (flags & MPR_RAW) {
+ mprPrintf(ctx, "%s", msg);
+
+ } else {
+ return;
+ }
+}
+
+/*****************************************************************************/
+/*
+ * Map the O/S error code to portable error codes.
+ */
+
+int mprGetOsError()
+{
+#if WIN
+ int rc;
+ rc = GetLastError();
+
+ /*
+ * Client has closed the pipe
+ */
+ if (rc == ERROR_NO_DATA) {
+ return EPIPE;
+ }
+ return rc;
+#endif
+#if LINUX || VXWORKS || SOLARIS
+ return errno;
+#endif
+#if BREW
+ /*
+ * No such thing on Brew. Errors are per class
+ */
+ return 0;
+#endif
+}
+
+/******************************************************************************/
+#if UNUSED
+
+const char *mprGetErrorMsg(int err)
+{
+ /*
+ * MPR error messages. Declare here so we don't have any globals.
+ */
+ char *mprErrMessages[] = {
+ /* 0 MPR_ERR_OK */ "Success",
+ /* -201 MPR_ERR_GENERAL */ "General error",
+ /* -202 MPR_ERR_ABORTED */ "Aborted",
+ /* -203 MPR_ERR_ALREADY_EXISTS */ "Already exists",
+ /* -204 MPR_ERR_BAD_ARGS */ "Bad args",
+ /* -205 MPR_ERR_BAD_FORMAT */ "Bad format",
+ /* -206 MPR_ERR_BAD_HANDLE */ "Bad handle",
+ /* -207 MPR_ERR_BAD_STATE */ "Bad state",
+ /* -208 MPR_ERR_BAD_SYNTAX */ "Bad syntax",
+ /* -209 MPR_ERR_BAD_TYPE */ "Bad type",
+ /* -210 MPR_ERR_BAD_VALUE */ "Bad value",
+ /* -211 MPR_ERR_BUSY */ "Busy",
+ /* -212 MPR_ERR_CANT_ACCESS */ "Can't access",
+ /* -213 MPR_ERR_CANT_COMPLETE */ "Can't complete",
+ /* -214 MPR_ERR_CANT_CREATE */ "Can't create",
+ /* -215 MPR_ERR_CANT_INITIALIZE */ "Can't initialize",
+ /* -216 MPR_ERR_CANT_OPEN */ "Can't open",
+ /* -217 MPR_ERR_CANT_READ */ "Can't read",
+ /* -218 MPR_ERR_CANT_WRITE */ "Can't write",
+ /* -219 MPR_ERR_DELETED */ "Already deleted",
+ /* -220 MPR_ERR_NETWORK */ "Network error",
+ /* -221 MPR_ERR_NOT_FOUND */ "Not found",
+ /* -222 MPR_ERR_NOT_INITIALIZED */ "Not initialized",
+ /* -223 MPR_ERR_NOT_READY */ "Not ready",
+ /* -224 MPR_ERR_READ_ONLY */ "Read only",
+ /* -225 MPR_ERR_TIMEOUT */ "Timeout",
+ /* -226 MPR_ERR_TOO_MANY */ "Too many",
+ /* -227 MPR_ERR_WONT_FIT */ "Won't fit",
+ /* -228 MPR_ERR_WOULD_BLOCK */ "Would block",
+ /* -229 MPR_ERR_CANT_ALLOCATE */ "Can't allocate",
+ };
+ int mprNumErr = sizeof(mprErrMessages) / sizeof(char*);
+
+/*
+ * Operating system error messages
+ */
+#if WIN
+char *osErrMessages[] =
+{
+ /* 0 */ "No error",
+ /* 1 EPERM */ "Operation not permitted",
+ /* 2 ENOENT */ "No such file or directory",
+ /* 3 ESRCH */ "No such process",
+ /* 4 EINTR */ "Interrupted function call",
+ /* 5 EIO */ "I/O error",
+ /* 6 ENXIO */ "No such device or address",
+ /* 7 E2BIG */ "Arg list too long",
+ /* 8 ENOEXEC */ "Exec format error",
+ /* 9 EBADF */ "Bad file number",
+ /* 10 ECHILD */ "No child processes",
+ /* 11 EAGAIN */ "Try again",
+ /* 12 ENOMEM */ "Out of memory",
+ /* 13 EACCES */ "Permission denied",
+ /* 14 EFAULT */ "Bad address",
+ /* 15 ENOTBLK */ "Unknown error",
+ /* 16 EBUSY */ "Resource busy",
+ /* 17 EEXIST */ "File exists",
+ /* 18 EXDEV */ "Improper link",
+ /* 19 ENODEV */ "No such device",
+ /* 20 ENOTDIR */ "Not a directory",
+ /* 21 EISDIR */ "Is a directory",
+ /* 22 EINVAL */ "Invalid argument",
+ /* 23 ENFILE */ "Too many open files in system",
+ /* 24 EMFILE */ "Too many open files",
+ /* 25 ENOTTY */ "Inappropriate I/O control operation",
+ /* 26 ETXTBSY */ "Unknown error",
+ /* 27 EFBIG */ "File too large",
+ /* 28 ENOSPC */ "No space left on device",
+ /* 29 ESPIPE */ "Invalid seek",
+ /* 30 EROFS */ "Read-only file system",
+ /* 31 EMLINK */ "Too many links",
+ /* 32 EPIPE */ "Broken pipe",
+ /* 33 EDOM */ "Domain error",
+ /* 34 ERANGE */ "Result too large",
+ /* 35 EUCLEAN */ "Unknown error",
+ /* 36 EDEADLK */ "Resource deadlock would occur",
+ /* 37 UNKNOWN */ "Unknown error",
+ /* 38 ENAMETOOLONG */ "Filename too long",
+ /* 39 ENOLCK */ "No locks available",
+ /* 40 ENOSYS */ "Function not implemented",
+ /* 41 ENOTEMPTY */ "Directory not empty",
+ /* 42 EILSEQ */ "Illegal byte sequence",
+ /* 43 ENETDOWN */ "Network is down",
+ /* 44 ECONNRESET */ "Connection reset",
+ /* 45 ECONNREFUSED */ "Connection refused",
+ /* 46 EADDRINUSE */ "Address already in use"
+
+};
+
+#else /* WIN */
+
+char *osErrMessages[] =
+{
+ /* 0 */ "Success"
+ /* 1 EPERM */ "Operation not permitted"
+ /* 2 ENOENT */ "No such file or directory"
+ /* 3 ESRCH */ "No such process"
+ /* 4 EINTR */ "Interrupted system call"
+ /* 5 EIO */ "I/O error"
+ /* 6 ENXIO */ "No such device or address"
+ /* 7 E2BIG */ "Arg list too long"
+ /* 8 ENOEXEC */ "Exec format error"
+ /* 9 EBADF */ "Bad file number"
+ /* 10 ECHILD */ "No child processes"
+ /* 11 EAGAIN */ "Try again"
+ /* 12 ENOMEM */ "Out of memory"
+ /* 13 EACCES */ "Permission denied"
+ /* 14 EFAULT */ "Bad address"
+ /* 15 ENOTBLK */ "Block device required"
+ /* 16 EBUSY */ "Device or resource busy"
+ /* 17 EEXIST */ "File exists"
+ /* 18 EXDEV */ "Cross-device link"
+ /* 19 ENODEV */ "No such device"
+ /* 20 ENOTDIR */ "Not a directory"
+ /* 21 EISDIR */ "Is a directory"
+ /* 22 EINVAL */ "Invalid argument"
+ /* 23 ENFILE */ "File table overflow"
+ /* 24 EMFILE */ "Too many open files"
+ /* 25 ENOTTY */ "Not a typewriter"
+ /* 26 ETXTBSY */ "Text file busy"
+ /* 27 EFBIG */ "File too large"
+ /* 28 ENOSPC */ "No space left on device"
+ /* 29 ESPIPE */ "Illegal seek"
+ /* 30 EROFS */ "Read-only file system"
+ /* 31 EMLINK */ "Too many links"
+ /* 32 EPIPE */ "Broken pipe"
+ /* 33 EDOM */ "Math argument out of domain of func"
+ /* 34 ERANGE */ "Math result not representable"
+ /* 35 EDEADLK */ "Resource deadlock would occur"
+ /* 36 ENAMETOOLONG */ "File name too long"
+ /* 37 ENOLCK */ "No record locks available"
+ /* 38 ENOSYS */ "Function not implemented"
+ /* 39 ENOTEMPTY */ "Directory not empty"
+ /* 40 ELOOP */ "Too many symbolic links encountered"
+ /* 41 EWOULDBLOCK EAGAIN */"Operation would block"
+ /* 42 ENOMSG */ "No message of desired type"
+ /* 43 EIDRM */ "Identifier removed"
+
+#if !BLD_FEATURE_SQUEEZE
+ /* 44 ECHRNG */ "Channel number out of range"
+ /* 45 EL2NSYNC */ "Level 2 not synchronized"
+ /* 46 EL3HLT */ "Level 3 halted"
+ /* 47 EL3RST */ "Level 3 reset"
+ /* 48 ELNRNG */ "Link number out of range"
+ /* 49 EUNATCH */ "Protocol driver not attached"
+ /* 50 ENOCSI */ "No CSI structure available"
+ /* 51 EL2HLT */ "Level 2 halted"
+ /* 52 EBADE */ "Invalid exchange"
+ /* 53 EBADR */ "Invalid request descriptor"
+ /* 54 EXFULL */ "Exchange full"
+ /* 55 ENOANO */ "No anode"
+ /* 56 EBADRQC */ "Invalid request code"
+ /* 57 EBADSLT */ "Invalid slot"
+ /* 59 EBFONT */ "Bad font file format"
+ /* 60 ENOSTR */ "Device not a stream"
+ /* 61 ENODATA */ "No data available"
+ /* 62 ETIME */ "Timer expired"
+ /* 63 ENOSR */ "Out of streams resources"
+ /* 64 ENONET */ "Machine is not on the network"
+ /* 65 ENOPKG */ "Package not installed"
+ /* 66 EREMOTE */ "Object is remote"
+ /* 67 ENOLINK */ "Link has been severed"
+ /* 68 EADV */ "Advertise error"
+ /* 69 ESRMNT */ "Srmount error"
+ /* 70 ECOMM */ "Communication error on send"
+ /* 71 EPROTO */ "Protocol error"
+ /* 72 EMULTIHOP */ "Multihop attempted"
+ /* 73 EDOTDOT */ "RFS specific error"
+ /* 74 EBADMSG */ "Not a data message"
+ /* 75 EOVERFLOW */ "Value too large for defined data type"
+ /* 76 ENOTUNIQ */ "Name not unique on network"
+ /* 77 EBADFD */ "File descriptor in bad state"
+ /* 78 EREMCHG */ "Remote address changed"
+ /* 79 ELIBACC */ "Can not access a needed shared library"
+ /* 80 ELIBBAD */ "Accessing a corrupted shared library"
+ /* 81 ELIBSCN */ ".lib section in a.out corrupted"
+ /* 82 ELIBMAX */ "Linking in too many shared libraries"
+ /* 83 ELIBEXEC */ "Cannot exec a shared library directly"
+ /* 84 EILSEQ */ "Illegal byte sequence"
+ /* 85 ERESTART */ "Interrupted system call should be restarted"
+ /* 86 ESTRPIPE */ "Streams pipe error"
+ /* 87 EUSERS */ "Too many users"
+ /* 88 ENOTSOCK */ "Socket operation on non-socket"
+ /* 89 EDESTADDRREQ */ "Destination address required"
+ /* 90 EMSGSIZE */ "Message too long"
+ /* 91 EPROTOTYPE */ "Protocol wrong type for socket"
+ /* 92 ENOPROTOOPT */ "Protocol not available"
+ /* 93 EPROTONOSUPPORT */ "Protocol not supported"
+ /* 94 ESOCKTNOSUPPORT */ "Socket type not supported"
+ /* 95 EOPNOTSUPP */ "Operation not supported on transport endpoint"
+ /* 96 EPFNOSUPPORT */ "Protocol family not supported"
+ /* 97 EAFNOSUPPORT */ "Address family not supported by protocol"
+ /* 98 EADDRINUSE */ "Address already in use"
+ /* 99 EADDRNOTAVAIL */ "Cannot assign requested address"
+ /* 100 ENETDOWN */ "Network is down"
+ /* 101 ENETUNREACH */ "Network is unreachable"
+ /* 102 ENETRESET */ "Network dropped connection because of reset"
+ /* 103 ECONNABORTED */ "Software caused connection abort"
+ /* 104 ECONNRESET */ "Connection reset by peer"
+ /* 105 ENOBUFS */ "No buffer space available"
+ /* 106 EISCONN */ "Transport endpoint is already connected"
+ /* 107 ENOTCONN */ "Transport endpoint is not connected"
+ /* 108 ESHUTDOWN */ "Cannot send after transport endpoint shutdown"
+ /* 109 ETOOMANYREFS */ "Too many references: cannot splice"
+ /* 110 ETIMEDOUT */ "Connection timed out"
+ /* 111 ECONNREFUSED */ "Connection refused"
+ /* 112 EHOSTDOWN */ "Host is down"
+ /* 113 EHOSTUNREACH */ "No route to host"
+ /* 114 EALREADY */ "Operation already in progress"
+ /* 115 EINPROGRESS */ "Operation now in progress"
+ /* 116 ESTALE */ "Stale NFS file handle"
+ /* 117 EUCLEAN */ "Structure needs cleaning"
+ /* 118 ENOTNAM */ "Not a XENIX named type file"
+ /* 119 ENAVAIL */ "No XENIX semaphores available"
+ /* 120 EISNAM */ "Is a named type file"
+ /* 121 EREMOTEIO */ "Remote I/O error"
+ /* 122 EDQUOT */ "Quota exceeded"
+ /* 123 ENOMEDIUM */ "No medium found"
+ /* 124 EMEDIUMTYPE */ "Wrong medium type"
+};
+#endif /* BLD_FEATURE_SQUEEZE */
+#endif /* WIN */
+
+ int osNumErr = sizeof(osErrMessages) / sizeof(char*);
+
+ if (err < MPR_ERR_BASE) {
+ err = MPR_ERR_BASE - err;
+ if (err < 0 || err >= mprNumErr) {
+ return "Bad error code";
+ }
+ return mprErrMessages[err];
+
+ } else {
+ /*
+ * Negative O/S error code. Map to a positive standard Posix error.
+ */
+ err = -err;
+ if (err < 0 || err >= osNumErr) {
+ return "Bad O/S error code";
+ }
+ return osErrMessages[err];
+ }
+}
+
+#endif
+/*****************************************************************************/
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim:tw=78
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */