PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/otherlibs/win32unix/unixsupport.c

http://github.com/bmeurer/ocamljit2
C | 275 lines | 232 code | 24 blank | 19 comment | 13 complexity | be49ab4bf3d5829e2ca2587c1c695693 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0
  1. /***********************************************************************/
  2. /* */
  3. /* Objective Caml */
  4. /* */
  5. /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
  6. /* */
  7. /* Copyright 1996 Institut National de Recherche en Informatique et */
  8. /* en Automatique. All rights reserved. This file is distributed */
  9. /* under the terms of the GNU Library General Public License, with */
  10. /* the special exception on linking described in file ../../LICENSE. */
  11. /* */
  12. /***********************************************************************/
  13. /* $Id$ */
  14. #include <stddef.h>
  15. #include <mlvalues.h>
  16. #include <callback.h>
  17. #include <alloc.h>
  18. #include <memory.h>
  19. #include <fail.h>
  20. #include <custom.h>
  21. #include "unixsupport.h"
  22. #include "cst2constr.h"
  23. #include <errno.h>
  24. /* Heap-allocation of Windows file handles */
  25. static int win_handle_compare(value v1, value v2)
  26. {
  27. HANDLE h1 = Handle_val(v1);
  28. HANDLE h2 = Handle_val(v2);
  29. return h1 == h2 ? 0 : h1 < h2 ? -1 : 1;
  30. }
  31. static intnat win_handle_hash(value v)
  32. {
  33. return (intnat) Handle_val(v);
  34. }
  35. static struct custom_operations win_handle_ops = {
  36. "_handle",
  37. custom_finalize_default,
  38. win_handle_compare,
  39. win_handle_hash,
  40. custom_serialize_default,
  41. custom_deserialize_default
  42. };
  43. value win_alloc_handle(HANDLE h)
  44. {
  45. value res = alloc_custom(&win_handle_ops, sizeof(struct filedescr), 0, 1);
  46. Handle_val(res) = h;
  47. Descr_kind_val(res) = KIND_HANDLE;
  48. CRT_fd_val(res) = NO_CRT_FD;
  49. Flags_fd_val(res) = FLAGS_FD_IS_BLOCKING;
  50. return res;
  51. }
  52. value win_alloc_socket(SOCKET s)
  53. {
  54. value res = alloc_custom(&win_handle_ops, sizeof(struct filedescr), 0, 1);
  55. Socket_val(res) = s;
  56. Descr_kind_val(res) = KIND_SOCKET;
  57. CRT_fd_val(res) = NO_CRT_FD;
  58. Flags_fd_val(res) = FLAGS_FD_IS_BLOCKING;
  59. return res;
  60. }
  61. #if 0
  62. /* PR#4750: this function is no longer used */
  63. value win_alloc_handle_or_socket(HANDLE h)
  64. {
  65. value res = win_alloc_handle(h);
  66. int opt;
  67. int optlen = sizeof(opt);
  68. if (getsockopt((SOCKET) h, SOL_SOCKET, SO_TYPE, (char *)&opt, &optlen) == 0)
  69. Descr_kind_val(res) = KIND_SOCKET;
  70. return res;
  71. }
  72. #endif
  73. /* Mapping of Windows error codes to POSIX error codes */
  74. struct error_entry { DWORD win_code; int range; int posix_code; };
  75. static struct error_entry win_error_table[] = {
  76. { ERROR_INVALID_FUNCTION, 0, EINVAL},
  77. { ERROR_FILE_NOT_FOUND, 0, ENOENT},
  78. { ERROR_PATH_NOT_FOUND, 0, ENOENT},
  79. { ERROR_TOO_MANY_OPEN_FILES, 0, EMFILE},
  80. { ERROR_ACCESS_DENIED, 0, EACCES},
  81. { ERROR_INVALID_HANDLE, 0, EBADF},
  82. { ERROR_ARENA_TRASHED, 0, ENOMEM},
  83. { ERROR_NOT_ENOUGH_MEMORY, 0, ENOMEM},
  84. { ERROR_INVALID_BLOCK, 0, ENOMEM},
  85. { ERROR_BAD_ENVIRONMENT, 0, E2BIG},
  86. { ERROR_BAD_FORMAT, 0, ENOEXEC},
  87. { ERROR_INVALID_ACCESS, 0, EINVAL},
  88. { ERROR_INVALID_DATA, 0, EINVAL},
  89. { ERROR_INVALID_DRIVE, 0, ENOENT},
  90. { ERROR_CURRENT_DIRECTORY, 0, EACCES},
  91. { ERROR_NOT_SAME_DEVICE, 0, EXDEV},
  92. { ERROR_NO_MORE_FILES, 0, ENOENT},
  93. { ERROR_LOCK_VIOLATION, 0, EACCES},
  94. { ERROR_BAD_NETPATH, 0, ENOENT},
  95. { ERROR_NETWORK_ACCESS_DENIED, 0, EACCES},
  96. { ERROR_BAD_NET_NAME, 0, ENOENT},
  97. { ERROR_FILE_EXISTS, 0, EEXIST},
  98. { ERROR_CANNOT_MAKE, 0, EACCES},
  99. { ERROR_FAIL_I24, 0, EACCES},
  100. { ERROR_INVALID_PARAMETER, 0, EINVAL},
  101. { ERROR_NO_PROC_SLOTS, 0, EAGAIN},
  102. { ERROR_DRIVE_LOCKED, 0, EACCES},
  103. { ERROR_BROKEN_PIPE, 0, EPIPE},
  104. { ERROR_NO_DATA, 0, EPIPE},
  105. { ERROR_DISK_FULL, 0, ENOSPC},
  106. { ERROR_INVALID_TARGET_HANDLE, 0, EBADF},
  107. { ERROR_INVALID_HANDLE, 0, EINVAL},
  108. { ERROR_WAIT_NO_CHILDREN, 0, ECHILD},
  109. { ERROR_CHILD_NOT_COMPLETE, 0, ECHILD},
  110. { ERROR_DIRECT_ACCESS_HANDLE, 0, EBADF},
  111. { ERROR_NEGATIVE_SEEK, 0, EINVAL},
  112. { ERROR_SEEK_ON_DEVICE, 0, EACCES},
  113. { ERROR_DIR_NOT_EMPTY, 0, ENOTEMPTY},
  114. { ERROR_NOT_LOCKED, 0, EACCES},
  115. { ERROR_BAD_PATHNAME, 0, ENOENT},
  116. { ERROR_MAX_THRDS_REACHED, 0, EAGAIN},
  117. { ERROR_LOCK_FAILED, 0, EACCES},
  118. { ERROR_ALREADY_EXISTS, 0, EEXIST},
  119. { ERROR_FILENAME_EXCED_RANGE, 0, ENOENT},
  120. { ERROR_NESTING_NOT_ALLOWED, 0, EAGAIN},
  121. { ERROR_NOT_ENOUGH_QUOTA, 0, ENOMEM},
  122. { ERROR_INVALID_STARTING_CODESEG,
  123. ERROR_INFLOOP_IN_RELOC_CHAIN - ERROR_INVALID_STARTING_CODESEG,
  124. ENOEXEC },
  125. { ERROR_WRITE_PROTECT,
  126. ERROR_SHARING_BUFFER_EXCEEDED - ERROR_WRITE_PROTECT,
  127. EACCES },
  128. { WSAEINVAL, 0, EINVAL },
  129. { WSAEACCES, 0, EACCES },
  130. { WSAEBADF, 0, EBADF },
  131. { WSAEFAULT, 0, EFAULT },
  132. { WSAEINTR, 0, EINTR },
  133. { WSAEINVAL, 0, EINVAL },
  134. { WSAEMFILE, 0, EMFILE },
  135. #ifdef WSANAMETOOLONG
  136. { WSANAMETOOLONG, 0, ENAMETOOLONG },
  137. #endif
  138. #ifdef WSAENFILE
  139. { WSAENFILE, 0, ENFILE },
  140. #endif
  141. { WSAENOTEMPTY, 0, ENOTEMPTY },
  142. { 0, -1, 0 }
  143. };
  144. void win32_maperr(DWORD errcode)
  145. {
  146. int i;
  147. for (i = 0; win_error_table[i].range >= 0; i++) {
  148. if (errcode >= win_error_table[i].win_code &&
  149. errcode <= win_error_table[i].win_code + win_error_table[i].range) {
  150. errno = win_error_table[i].posix_code;
  151. return;
  152. }
  153. }
  154. /* Not found: save original error code, negated so that we can
  155. recognize it in unix_error_message */
  156. errno = -errcode;
  157. }
  158. /* Windows socket errors */
  159. #define EWOULDBLOCK -WSAEWOULDBLOCK
  160. #define EINPROGRESS -WSAEINPROGRESS
  161. #define EALREADY -WSAEALREADY
  162. #define ENOTSOCK -WSAENOTSOCK
  163. #define EDESTADDRREQ -WSAEDESTADDRREQ
  164. #define EMSGSIZE -WSAEMSGSIZE
  165. #define EPROTOTYPE -WSAEPROTOTYPE
  166. #define ENOPROTOOPT -WSAENOPROTOOPT
  167. #define EPROTONOSUPPORT -WSAEPROTONOSUPPORT
  168. #define ESOCKTNOSUPPORT -WSAESOCKTNOSUPPORT
  169. #define EOPNOTSUPP -WSAEOPNOTSUPP
  170. #define EPFNOSUPPORT -WSAEPFNOSUPPORT
  171. #define EAFNOSUPPORT -WSAEAFNOSUPPORT
  172. #define EADDRINUSE -WSAEADDRINUSE
  173. #define EADDRNOTAVAIL -WSAEADDRNOTAVAIL
  174. #define ENETDOWN -WSAENETDOWN
  175. #define ENETUNREACH -WSAENETUNREACH
  176. #define ENETRESET -WSAENETRESET
  177. #define ECONNABORTED -WSAECONNABORTED
  178. #define ECONNRESET -WSAECONNRESET
  179. #define ENOBUFS -WSAENOBUFS
  180. #define EISCONN -WSAEISCONN
  181. #define ENOTCONN -WSAENOTCONN
  182. #define ESHUTDOWN -WSAESHUTDOWN
  183. #define ETOOMANYREFS -WSAETOOMANYREFS
  184. #define ETIMEDOUT -WSAETIMEDOUT
  185. #define ECONNREFUSED -WSAECONNREFUSED
  186. #define ELOOP -WSAELOOP
  187. #define EHOSTDOWN -WSAEHOSTDOWN
  188. #define EHOSTUNREACH -WSAEHOSTUNREACH
  189. #define EPROCLIM -WSAEPROCLIM
  190. #define EUSERS -WSAEUSERS
  191. #define EDQUOT -WSAEDQUOT
  192. #define ESTALE -WSAESTALE
  193. #define EREMOTE -WSAEREMOTE
  194. #define EOVERFLOW -ERROR_ARITHMETIC_OVERFLOW
  195. #define EACCESS EACCES
  196. int error_table[] = {
  197. E2BIG, EACCESS, EAGAIN, EBADF, EBUSY, ECHILD, EDEADLK, EDOM,
  198. EEXIST, EFAULT, EFBIG, EINTR, EINVAL, EIO, EISDIR, EMFILE, EMLINK,
  199. ENAMETOOLONG, ENFILE, ENODEV, ENOENT, ENOEXEC, ENOLCK, ENOMEM, ENOSPC,
  200. ENOSYS, ENOTDIR, ENOTEMPTY, ENOTTY, ENXIO, EPERM, EPIPE, ERANGE,
  201. EROFS, ESPIPE, ESRCH, EXDEV, EWOULDBLOCK, EINPROGRESS, EALREADY,
  202. ENOTSOCK, EDESTADDRREQ, EMSGSIZE, EPROTOTYPE, ENOPROTOOPT,
  203. EPROTONOSUPPORT, ESOCKTNOSUPPORT, EOPNOTSUPP, EPFNOSUPPORT,
  204. EAFNOSUPPORT, EADDRINUSE, EADDRNOTAVAIL, ENETDOWN, ENETUNREACH,
  205. ENETRESET, ECONNABORTED, ECONNRESET, ENOBUFS, EISCONN, ENOTCONN,
  206. ESHUTDOWN, ETOOMANYREFS, ETIMEDOUT, ECONNREFUSED, EHOSTDOWN,
  207. EHOSTUNREACH, ELOOP, EOVERFLOW /*, EUNKNOWNERR */
  208. };
  209. static value * unix_error_exn = NULL;
  210. value unix_error_of_code (int errcode)
  211. {
  212. int errconstr;
  213. value err;
  214. errconstr =
  215. cst_to_constr(errcode, error_table, sizeof(error_table)/sizeof(int), -1);
  216. if (errconstr == Val_int(-1)) {
  217. err = alloc_small(1, 0);
  218. Field(err, 0) = Val_int(errcode);
  219. } else {
  220. err = errconstr;
  221. }
  222. return err;
  223. }
  224. void unix_error(int errcode, char *cmdname, value cmdarg)
  225. {
  226. value res;
  227. value name = Val_unit, err = Val_unit, arg = Val_unit;
  228. int errconstr;
  229. Begin_roots3 (name, err, arg);
  230. arg = cmdarg == Nothing ? copy_string("") : cmdarg;
  231. name = copy_string(cmdname);
  232. err = unix_error_of_code (errcode);
  233. if (unix_error_exn == NULL) {
  234. unix_error_exn = caml_named_value("Unix.Unix_error");
  235. if (unix_error_exn == NULL)
  236. invalid_argument("Exception Unix.Unix_error not initialized, please link unix.cma");
  237. }
  238. res = alloc_small(4, 0);
  239. Field(res, 0) = *unix_error_exn;
  240. Field(res, 1) = err;
  241. Field(res, 2) = name;
  242. Field(res, 3) = arg;
  243. End_roots();
  244. mlraise(res);
  245. }
  246. void uerror(cmdname, cmdarg)
  247. char * cmdname;
  248. value cmdarg;
  249. {
  250. unix_error(errno, cmdname, cmdarg);
  251. }