summaryrefslogtreecommitdiff
path: root/src/os_windows/os_errno.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/os_windows/os_errno.c')
-rw-r--r--src/os_windows/os_errno.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/src/os_windows/os_errno.c b/src/os_windows/os_errno.c
new file mode 100644
index 00000000..ba8ec359
--- /dev/null
+++ b/src/os_windows/os_errno.c
@@ -0,0 +1,428 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_get_errno_ret_zero --
+ * Return the last system error, including an error of zero.
+ */
+int
+__os_get_errno_ret_zero()
+{
+ /* This routine must be able to return the same value repeatedly. */
+ return (errno);
+}
+
+/*
+ * We've seen cases where system calls failed but errno was never set. For
+ * that reason, __os_get_errno() and __os_get_syserr set errno to EAGAIN if
+ * it's not already set, to work around the problem. For obvious reasons,
+ * we can only call this function if we know an error has occurred, that
+ * is, we can't test the return for a non-zero value after the get call.
+ *
+ * __os_get_errno --
+ * Return the last ANSI C "errno" value or EAGAIN if the last error
+ * is zero.
+ */
+int
+__os_get_errno()
+{
+ /* This routine must be able to return the same value repeatedly. */
+ if (errno == 0)
+ __os_set_errno(EAGAIN);
+ return (errno);
+}
+
+#ifdef HAVE_REPLICATION_THREADS
+/*
+ * __os_get_neterr --
+ * Return the last networking error or EAGAIN if the last error is zero.
+ *
+ * PUBLIC: #ifdef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __os_get_neterr __P((void));
+ * PUBLIC: #endif
+ */
+int
+__os_get_neterr()
+{
+ int err;
+
+ /* This routine must be able to return the same value repeatedly. */
+ err = WSAGetLastError();
+ if (err == 0)
+ WSASetLastError(err = ERROR_RETRY);
+ return (err);
+}
+#endif
+
+/*
+ * __os_get_syserr --
+ * Return the last system error or EAGAIN if the last error is zero.
+ */
+int
+__os_get_syserr()
+{
+ int err;
+
+ /* This routine must be able to return the same value repeatedly. */
+ err = GetLastError();
+ if (err == 0)
+ SetLastError(err = ERROR_RETRY);
+ return (err);
+}
+
+/*
+ * __os_set_errno --
+ * Set the value of errno.
+ */
+void
+__os_set_errno(evalue)
+ int evalue;
+{
+ /*
+ * This routine is called by the compatibility interfaces (DB 1.85,
+ * dbm and hsearch). Force values > 0, that is, not one of DB 2.X
+ * and later's public error returns. If something bad has happened,
+ * default to EFAULT -- a nasty return. Otherwise, default to EINVAL.
+ * As the compatibility APIs aren't included on Windows, the Windows
+ * version of this routine doesn't need this behavior.
+ */
+ errno =
+ evalue >= 0 ? evalue : (evalue == DB_RUNRECOVERY ? EFAULT : EINVAL);
+}
+
+/*
+ * __os_strerror --
+ * Return a string associated with the system error.
+ */
+char *
+__os_strerror(error, buf, len)
+ int error;
+ char *buf;
+ size_t len;
+{
+#ifdef DB_WINCE
+#define MAX_TMPBUF_LEN 512
+ _TCHAR tbuf[MAX_TMPBUF_LEN];
+ size_t maxlen;
+
+ DB_ASSERT(NULL, error != 0);
+
+ memset(tbuf, 0, sizeof(_TCHAR)*MAX_TMPBUF_LEN);
+ maxlen = (len > MAX_TMPBUF_LEN ? MAX_TMPBUF_LEN : len);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, (DWORD)error,
+ 0, tbuf, maxlen-1, NULL);
+
+ if (WideCharToMultiByte(CP_UTF8, 0, tbuf, -1,
+ buf, len, 0, NULL) == 0)
+ strncpy(buf, DB_STR("0035",
+ "Error message translation failed."), len);
+#else
+ DB_ASSERT(NULL, error != 0);
+ /*
+ * Explicitly call FormatMessageA, since we want to receive a char
+ * string back, not a tchar string.
+ */
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, (DWORD)error, 0, buf, (DWORD)(len - 1), NULL);
+ buf[len - 1] = '\0';
+#endif
+
+ return (buf);
+}
+
+/*
+ * __os_posix_err --
+ * Convert a system error to a POSIX error.
+ */
+int
+__os_posix_err(error)
+ int error;
+{
+ /* Handle calls on successful returns. */
+ if (error == 0)
+ return (0);
+
+ /*
+ * Translate the Windows error codes we care about.
+ */
+ switch (error) {
+ case ERROR_INVALID_PARAMETER:
+ return (EINVAL);
+
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_INVALID_DRIVE:
+ case ERROR_PATH_NOT_FOUND:
+ return (ENOENT);
+
+ case ERROR_NO_MORE_FILES:
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return (EMFILE);
+
+ case ERROR_ACCESS_DENIED:
+ return (EPERM);
+
+ case ERROR_INVALID_HANDLE:
+ return (EBADF);
+
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return (ENOMEM);
+
+ case ERROR_DISK_FULL:
+ return (ENOSPC);
+
+ case ERROR_ARENA_TRASHED:
+ case ERROR_BAD_COMMAND:
+ case ERROR_BAD_ENVIRONMENT:
+ case ERROR_BAD_FORMAT:
+ case ERROR_GEN_FAILURE:
+ case ERROR_INVALID_ACCESS:
+ case ERROR_INVALID_BLOCK:
+ case ERROR_INVALID_DATA:
+ case ERROR_READ_FAULT:
+ case ERROR_WRITE_FAULT:
+ return (EFAULT);
+
+ case ERROR_ALREADY_EXISTS:
+ case ERROR_FILE_EXISTS:
+ return (EEXIST);
+
+ case ERROR_NOT_SAME_DEVICE:
+ return (EXDEV);
+
+ case ERROR_WRITE_PROTECT:
+ return (EACCES);
+
+ case ERROR_LOCK_FAILED:
+ case ERROR_LOCK_VIOLATION:
+ case ERROR_NOT_READY:
+ case ERROR_SHARING_VIOLATION:
+ return (EBUSY);
+
+ case ERROR_RETRY:
+ return (EINTR);
+ }
+
+ /*
+ * Translate the Windows socket error codes.
+ */
+ switch (error) {
+ case WSAEADDRINUSE:
+#ifdef EADDRINUSE
+ return (EADDRINUSE);
+#else
+ break;
+#endif
+ case WSAEADDRNOTAVAIL:
+#ifdef EADDRNOTAVAIL
+ return (EADDRNOTAVAIL);
+#else
+ break;
+#endif
+ case WSAEAFNOSUPPORT:
+#ifdef EAFNOSUPPORT
+ return (EAFNOSUPPORT);
+#else
+ break;
+#endif
+ case WSAEALREADY:
+#ifdef EALREADY
+ return (EALREADY);
+#else
+ break;
+#endif
+ case WSAEBADF:
+ return (EBADF);
+ case WSAECONNABORTED:
+#ifdef ECONNABORTED
+ return (ECONNABORTED);
+#else
+ break;
+#endif
+ case WSAECONNREFUSED:
+#ifdef ECONNREFUSED
+ return (ECONNREFUSED);
+#else
+ break;
+#endif
+ case WSAECONNRESET:
+#ifdef ECONNRESET
+ return (ECONNRESET);
+#else
+ break;
+#endif
+ case WSAEDESTADDRREQ:
+#ifdef EDESTADDRREQ
+ return (EDESTADDRREQ);
+#else
+ break;
+#endif
+ case WSAEFAULT:
+ return (EFAULT);
+ case WSAEHOSTDOWN:
+#ifdef EHOSTDOWN
+ return (EHOSTDOWN);
+#else
+ break;
+#endif
+ case WSAEHOSTUNREACH:
+#ifdef EHOSTUNREACH
+ return (EHOSTUNREACH);
+#else
+ break;
+#endif
+ case WSAEINPROGRESS:
+#ifdef EINPROGRESS
+ return (EINPROGRESS);
+#else
+ break;
+#endif
+ case WSAEINTR:
+ return (EINTR);
+ case WSAEINVAL:
+ return (EINVAL);
+ case WSAEISCONN:
+#ifdef EISCONN
+ return (EISCONN);
+#else
+ break;
+#endif
+ case WSAELOOP:
+#ifdef ELOOP
+ return (ELOOP);
+#else
+ break;
+#endif
+ case WSAEMFILE:
+ return (EMFILE);
+ case WSAEMSGSIZE:
+#ifdef EMSGSIZE
+ return (EMSGSIZE);
+#else
+ break;
+#endif
+ case WSAENAMETOOLONG:
+ return (ENAMETOOLONG);
+ case WSAENETDOWN:
+#ifdef ENETDOWN
+ return (ENETDOWN);
+#else
+ break;
+#endif
+ case WSAENETRESET:
+#ifdef ENETRESET
+ return (ENETRESET);
+#else
+ break;
+#endif
+ case WSAENETUNREACH:
+#ifdef ENETUNREACH
+ return (ENETUNREACH);
+#else
+ break;
+#endif
+ case WSAENOBUFS:
+#ifdef ENOBUFS
+ return (ENOBUFS);
+#else
+ break;
+#endif
+ case WSAENOPROTOOPT:
+#ifdef ENOPROTOOPT
+ return (ENOPROTOOPT);
+#else
+ break;
+#endif
+ case WSAENOTCONN:
+#ifdef ENOTCONN
+ return (ENOTCONN);
+#else
+ break;
+#endif
+ case WSANOTINITIALISED:
+ return (EAGAIN);
+ case WSAENOTSOCK:
+#ifdef ENOTSOCK
+ return (ENOTSOCK);
+#else
+ break;
+#endif
+ case WSAEOPNOTSUPP:
+ return (DB_OPNOTSUP);
+ case WSAEPFNOSUPPORT:
+#ifdef EPFNOSUPPORT
+ return (EPFNOSUPPORT);
+#else
+ break;
+#endif
+ case WSAEPROTONOSUPPORT:
+#ifdef EPROTONOSUPPORT
+ return (EPROTONOSUPPORT);
+#else
+ break;
+#endif
+ case WSAEPROTOTYPE:
+#ifdef EPROTOTYPE
+ return (EPROTOTYPE);
+#else
+ break;
+#endif
+ case WSAESHUTDOWN:
+#ifdef ESHUTDOWN
+ return (ESHUTDOWN);
+#else
+ break;
+#endif
+ case WSAESOCKTNOSUPPORT:
+#ifdef ESOCKTNOSUPPORT
+ return (ESOCKTNOSUPPORT);
+#else
+ break;
+#endif
+ case WSAETIMEDOUT:
+#ifdef ETIMEDOUT
+ return (ETIMEDOUT);
+#else
+ break;
+#endif
+ case WSAETOOMANYREFS:
+#ifdef ETOOMANYREFS
+ return (ETOOMANYREFS);
+#else
+ break;
+#endif
+ case WSAEWOULDBLOCK:
+#ifdef EWOULDBLOCK
+ return (EWOULDBLOCK);
+#else
+ return (EAGAIN);
+#endif
+ case WSAHOST_NOT_FOUND:
+#ifdef EHOSTUNREACH
+ return (EHOSTUNREACH);
+#else
+ break;
+#endif
+ case WSASYSNOTREADY:
+ return (EAGAIN);
+ case WSATRY_AGAIN:
+ return (EAGAIN);
+ case WSAVERNOTSUPPORTED:
+ return (DB_OPNOTSUP);
+ case WSAEACCES:
+ return (EACCES);
+ }
+
+ /*
+ * EFAULT is the default if we don't have a translation.
+ */
+ return (EFAULT);
+}