diff src/sysdep.c @ 255:084402c475ba r20-5b26

Import from CVS: tag r20-5b26
author cvs
date Mon, 13 Aug 2007 10:21:18 +0200
parents 677f6a0ee643
children 11cf20601dec
line wrap: on
line diff
--- a/src/sysdep.c	Mon Aug 13 10:20:29 2007 +0200
+++ b/src/sysdep.c	Mon Aug 13 10:21:18 2007 +0200
@@ -80,8 +80,10 @@
 #ifndef WINDOWSNT
 #include <sys/times.h>
 #endif
+
 #ifdef WINDOWSNT
 #include <sys/utime.h>
+#include <windows.h>
 #include "ntheap.h"
 #endif
 
@@ -2374,7 +2376,7 @@
 
 
 /************************************************************************/
-/*                        Emulation of strerror()                       */
+/*           Emulation of strerror() and errno support                  */
 /************************************************************************/
 
 #ifndef HAVE_STRERROR
@@ -2403,6 +2405,104 @@
 
 #endif /* ! HAVE_STRERROR */
 
+#ifdef WINDOWSNT
+
+struct errentry {
+  unsigned long oscode;  /* Win32 error */
+  int errnocode;         /* unix errno */
+};
+
+static struct errentry errtable[] = {
+  {  ERROR_INVALID_FUNCTION,       EINVAL    },  /* 1 */
+  {  ERROR_FILE_NOT_FOUND,         ENOENT    },  /* 2 */
+  {  ERROR_PATH_NOT_FOUND,         ENOENT    },  /* 3 */
+  {  ERROR_TOO_MANY_OPEN_FILES,    EMFILE    },  /* 4 */
+  {  ERROR_ACCESS_DENIED,          EACCES    },  /* 5 */
+  {  ERROR_INVALID_HANDLE,         EBADF     },  /* 6 */
+  {  ERROR_ARENA_TRASHED,          ENOMEM    },  /* 7 */
+  {  ERROR_NOT_ENOUGH_MEMORY,      ENOMEM    },  /* 8 */
+  {  ERROR_INVALID_BLOCK,          ENOMEM    },  /* 9 */
+  {  ERROR_BAD_ENVIRONMENT,        E2BIG     },  /* 10 */
+  {  ERROR_BAD_FORMAT,             ENOEXEC   },  /* 11 */
+  {  ERROR_INVALID_ACCESS,         EINVAL    },  /* 12 */
+  {  ERROR_INVALID_DATA,           EINVAL    },  /* 13 */
+  {  ERROR_INVALID_DRIVE,          ENOENT    },  /* 15 */
+  {  ERROR_CURRENT_DIRECTORY,      EACCES    },  /* 16 */
+  {  ERROR_NOT_SAME_DEVICE,        EXDEV     },  /* 17 */
+  {  ERROR_NO_MORE_FILES,          ENOENT    },  /* 18 */
+  {  ERROR_LOCK_VIOLATION,         EACCES    },  /* 33 */
+  {  ERROR_BAD_NETPATH,            ENOENT    },  /* 53 */
+  {  ERROR_NETWORK_ACCESS_DENIED,  EACCES    },  /* 65 */
+  {  ERROR_BAD_NET_NAME,           ENOENT    },  /* 67 */
+  {  ERROR_FILE_EXISTS,            EEXIST    },  /* 80 */
+  {  ERROR_CANNOT_MAKE,            EACCES    },  /* 82 */
+  {  ERROR_FAIL_I24,               EACCES    },  /* 83 */
+  {  ERROR_INVALID_PARAMETER,      EINVAL    },  /* 87 */
+  {  ERROR_NO_PROC_SLOTS,          EAGAIN    },  /* 89 */
+  {  ERROR_DRIVE_LOCKED,           EACCES    },  /* 108 */
+  {  ERROR_BROKEN_PIPE,            EPIPE     },  /* 109 */
+  {  ERROR_DISK_FULL,              ENOSPC    },  /* 112 */
+  {  ERROR_INVALID_TARGET_HANDLE,  EBADF     },  /* 114 */
+  {  ERROR_INVALID_HANDLE,         EINVAL    },  /* 124 */
+  {  ERROR_WAIT_NO_CHILDREN,       ECHILD    },  /* 128 */
+  {  ERROR_CHILD_NOT_COMPLETE,     ECHILD    },  /* 129 */
+  {  ERROR_DIRECT_ACCESS_HANDLE,   EBADF     },  /* 130 */
+  {  ERROR_NEGATIVE_SEEK,          EINVAL    },  /* 131 */
+  {  ERROR_SEEK_ON_DEVICE,         EACCES    },  /* 132 */
+  {  ERROR_DIR_NOT_EMPTY,          ENOTEMPTY },  /* 145 */
+  {  ERROR_NOT_LOCKED,             EACCES    },  /* 158 */
+  {  ERROR_BAD_PATHNAME,           ENOENT    },  /* 161 */
+  {  ERROR_MAX_THRDS_REACHED,      EAGAIN    },  /* 164 */
+  {  ERROR_LOCK_FAILED,            EACCES    },  /* 167 */
+  {  ERROR_ALREADY_EXISTS,         EEXIST    },  /* 183 */
+  {  ERROR_FILENAME_EXCED_RANGE,   ENOENT    },  /* 206 */
+  {  ERROR_NESTING_NOT_ALLOWED,    EAGAIN    },  /* 215 */
+  {  ERROR_NOT_ENOUGH_QUOTA,       ENOMEM    }    /* 1816 */
+};
+
+/* The following two constants must be the minimum and maximum
+   values in the (contiguous) range of Exec Failure errors. */
+#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
+#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
+
+/* These are the low and high value in the range of errors that are
+   access violations */
+#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
+#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
+
+void
+mswindows_set_errno (unsigned long win32_error)
+{
+  int i;
+
+  /* check the table for the OS error code */
+  for (i = 0; i < sizeof(errtable)/sizeof(errtable[0]); ++i)
+    {
+      if (win32_error == errtable[i].oscode)
+	{
+	  errno = errtable[i].errnocode;
+	  return;
+	}
+    }
+
+  /* The error code wasn't in the table.  We check for a range of
+   * EACCES errors or exec failure errors (ENOEXEC).  Otherwise EINVAL is
+   * returned. */
+  if (win32_error >= MIN_EACCES_RANGE && win32_error <= MAX_EACCES_RANGE)
+    errno = EACCES;
+  else if (win32_error >= MIN_EXEC_ERROR && win32_error <= MAX_EXEC_ERROR)
+    errno = ENOEXEC;
+  else
+    errno = EINVAL;
+}
+
+void
+mswindows_set_last_errno (void)
+{
+  mswindows_set_errno (GetLastError ());
+}
+
+#endif /* WINDOWSNT */
 
 
 /************************************************************************/