--- /dev/null
+/* ----------------------------------------------------------------------------\r
+ (c) The University of Glasgow 2006\r
+ \r
+ Useful Win32 bits\r
+ ------------------------------------------------------------------------- */\r
+\r
+#include "HsBase.h"\r
+\r
+/* This is the error table that defines the mapping between OS error\r
+ codes and errno values */\r
+\r
+struct errentry {\r
+ unsigned long oscode; /* OS return value */\r
+ int errnocode; /* System V error code */\r
+};\r
+\r
+static struct errentry errtable[] = {\r
+ { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */\r
+ { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */\r
+ { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */\r
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */\r
+ { ERROR_ACCESS_DENIED, EACCES }, /* 5 */\r
+ { ERROR_INVALID_HANDLE, EBADF }, /* 6 */\r
+ { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */\r
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */\r
+ { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */\r
+ { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */\r
+ { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */\r
+ { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */\r
+ { ERROR_INVALID_DATA, EINVAL }, /* 13 */\r
+ { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */\r
+ { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */\r
+ { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */\r
+ { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */\r
+ { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */\r
+ { ERROR_BAD_NETPATH, ENOENT }, /* 53 */\r
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */\r
+ { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */\r
+ { ERROR_FILE_EXISTS, EEXIST }, /* 80 */\r
+ { ERROR_CANNOT_MAKE, EACCES }, /* 82 */\r
+ { ERROR_FAIL_I24, EACCES }, /* 83 */\r
+ { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */\r
+ { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */\r
+ { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */\r
+ { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */\r
+ { ERROR_DISK_FULL, ENOSPC }, /* 112 */\r
+ { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */\r
+ { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */\r
+ { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */\r
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */\r
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */\r
+ { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */\r
+ { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */\r
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */\r
+ { ERROR_NOT_LOCKED, EACCES }, /* 158 */\r
+ { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */\r
+ { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */\r
+ { ERROR_LOCK_FAILED, EACCES }, /* 167 */\r
+ { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */\r
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */\r
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */\r
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */\r
+};\r
+\r
+/* size of the table */\r
+#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0]))\r
+\r
+/* The following two constants must be the minimum and maximum\r
+ values in the (contiguous) range of Exec Failure errors. */\r
+#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG\r
+#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN\r
+\r
+/* These are the low and high value in the range of errors that are\r
+ access violations */\r
+#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT\r
+#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED\r
+\r
+void maperrno (void)\r
+{\r
+ int i;\r
+ DWORD dwErrorCode;\r
+\r
+ dwErrorCode = GetLastError();\r
+\r
+ /* check the table for the OS error code */\r
+ for (i = 0; i < ERRTABLESIZE; ++i)\r
+ {\r
+ if (dwErrorCode == errtable[i].oscode)\r
+ {\r
+ errno = errtable[i].errnocode;\r
+ return;\r
+ }\r
+ }\r
+\r
+ /* The error code wasn't in the table. We check for a range of */\r
+ /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */\r
+ /* EINVAL is returned. */\r
+\r
+ if (dwErrorCode >= MIN_EACCES_RANGE && dwErrorCode <= MAX_EACCES_RANGE)\r
+ errno = EACCES;\r
+ else\r
+ if (dwErrorCode >= MIN_EXEC_ERROR && dwErrorCode <= MAX_EXEC_ERROR)\r
+ errno = ENOEXEC;\r
+ else\r
+ errno = EINVAL;\r
+}\r
+\r
+#define TICKS_PER_SECOND 50\r
+// must match GHC.Conc.tick_freq\r
+\r
+HsInt getTicksOfDay(void)\r
+{\r
+ HsInt64 t;\r
+ FILETIME ft;\r
+ GetSystemTimeAsFileTime(&ft);\r
+ t = ((HsInt64)ft.dwHighDateTime << 32) | ft.dwLowDateTime;\r
+ t = (t * TICKS_PER_SECOND) / 10000000LL;\r
+ /* FILETIMES are in units of 100ns */\r
+ return (HsInt)t;\r
+}\r
+\r