PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/mono/io-layer/error.c

http://github.com/mono/mono
C | 293 lines | 223 code | 39 blank | 31 comment | 10 complexity | e6c1352430dcd12d49a0c4b29309f35f MD5 | raw file
Possible License(s): GPL-2.0, CC-BY-SA-3.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, Unlicense, Apache-2.0
  1. /*
  2. * error.c: Error reporting
  3. *
  4. * Author:
  5. * Dick Porter (dick@ximian.com)
  6. *
  7. * (C) 2002 Ximian, Inc.
  8. */
  9. #include <config.h>
  10. #include <glib.h>
  11. #include <pthread.h>
  12. #include <string.h>
  13. #include <errno.h>
  14. #include "mono/io-layer/wapi.h"
  15. #include "mono/io-layer/wapi-private.h"
  16. #include "mono/utils/mono-once.h"
  17. static pthread_key_t error_key;
  18. static mono_once_t error_key_once=MONO_ONCE_INIT;
  19. static void error_init(void)
  20. {
  21. int ret;
  22. ret = pthread_key_create(&error_key, NULL);
  23. g_assert (ret == 0);
  24. }
  25. void _wapi_error_cleanup (void)
  26. {
  27. int ret;
  28. ret = pthread_key_delete (error_key);
  29. g_assert (ret == 0);
  30. }
  31. /**
  32. * GetLastError:
  33. *
  34. * Retrieves the last error that occurred in the calling thread.
  35. *
  36. * Return value: The error code for the last error that happened on
  37. * the calling thread.
  38. */
  39. guint32 GetLastError(void)
  40. {
  41. guint32 err;
  42. void *errptr;
  43. if (_wapi_has_shut_down)
  44. return 0;
  45. mono_once(&error_key_once, error_init);
  46. errptr=pthread_getspecific(error_key);
  47. err=GPOINTER_TO_UINT(errptr);
  48. return(err);
  49. }
  50. /**
  51. * SetLastError:
  52. * @code: The error code.
  53. *
  54. * Sets the error code in the calling thread.
  55. */
  56. void SetLastError(guint32 code)
  57. {
  58. int ret;
  59. if (_wapi_has_shut_down)
  60. return;
  61. /* Set the thread-local error code */
  62. mono_once(&error_key_once, error_init);
  63. ret = pthread_setspecific(error_key, GUINT_TO_POINTER(code));
  64. g_assert (ret == 0);
  65. }
  66. guint32
  67. errno_to_WSA (guint32 code, const gchar *function_name)
  68. {
  69. gint result = -1;
  70. char *sys_error;
  71. gchar *msg;
  72. switch (code) {
  73. case 0: result = ERROR_SUCCESS; break;
  74. case EACCES: result = WSAEACCES; break;
  75. #ifdef EADDRINUSE
  76. case EADDRINUSE: result = WSAEADDRINUSE; break;
  77. #endif
  78. #ifdef EAFNOSUPPORT
  79. case EAFNOSUPPORT: result = WSAEAFNOSUPPORT; break;
  80. #endif
  81. #if EAGAIN != EWOULDBLOCK
  82. case EAGAIN: result = WSAEWOULDBLOCK; break;
  83. #endif
  84. #ifdef EALREADY
  85. case EALREADY: result = WSAEALREADY; break;
  86. #endif
  87. case EBADF: result = WSAENOTSOCK; break;
  88. #ifdef ECONNABORTED
  89. case ECONNABORTED: result = WSAENETDOWN; break;
  90. #endif
  91. #ifdef ECONNREFUSED
  92. case ECONNREFUSED: result = WSAECONNREFUSED; break;
  93. #endif
  94. #ifdef ECONNRESET
  95. case ECONNRESET: result = WSAECONNRESET; break;
  96. #endif
  97. case EFAULT: result = WSAEFAULT; break;
  98. #ifdef EHOSTUNREACH
  99. case EHOSTUNREACH: result = WSAEHOSTUNREACH; break;
  100. #endif
  101. #ifdef EINPROGRESS
  102. case EINPROGRESS: result = WSAEINPROGRESS; break;
  103. #endif
  104. case EINTR: result = WSAEINTR; break;
  105. case EINVAL: result = WSAEINVAL; break;
  106. /*FIXME: case EIO: result = WSAE????; break; */
  107. #ifdef EISCONN
  108. case EISCONN: result = WSAEISCONN; break;
  109. #endif
  110. /* FIXME: case ELOOP: result = WSA????; break; */
  111. case EMFILE: result = WSAEMFILE; break;
  112. #ifdef EMSGSIZE
  113. case EMSGSIZE: result = WSAEMSGSIZE; break;
  114. #endif
  115. /* FIXME: case ENAMETOOLONG: result = WSAEACCES; break; */
  116. #ifdef ENETUNREACH
  117. case ENETUNREACH: result = WSAENETUNREACH; break;
  118. #endif
  119. #ifdef ENOBUFS
  120. case ENOBUFS: result = WSAENOBUFS; break; /* not documented */
  121. #endif
  122. /* case ENOENT: result = WSAE????; break; */
  123. case ENOMEM: result = WSAENOBUFS; break;
  124. #ifdef ENOPROTOOPT
  125. case ENOPROTOOPT: result = WSAENOPROTOOPT; break;
  126. #endif
  127. #ifdef ENOSR
  128. case ENOSR: result = WSAENETDOWN; break;
  129. #endif
  130. #ifdef ENOTCONN
  131. case ENOTCONN: result = WSAENOTCONN; break;
  132. #endif
  133. /*FIXME: case ENOTDIR: result = WSAE????; break; */
  134. #ifdef ENOTSOCK
  135. case ENOTSOCK: result = WSAENOTSOCK; break;
  136. #endif
  137. case ENOTTY: result = WSAENOTSOCK; break;
  138. #ifdef EOPNOTSUPP
  139. case EOPNOTSUPP: result = WSAEOPNOTSUPP; break;
  140. #endif
  141. case EPERM: result = WSAEACCES; break;
  142. case EPIPE: result = WSAESHUTDOWN; break;
  143. #ifdef EPROTONOSUPPORT
  144. case EPROTONOSUPPORT: result = WSAEPROTONOSUPPORT; break;
  145. #endif
  146. #if ERESTARTSYS
  147. case ERESTARTSYS: result = WSAENETDOWN; break;
  148. #endif
  149. /*FIXME: case EROFS: result = WSAE????; break; */
  150. #ifdef ESOCKTNOSUPPORT
  151. case ESOCKTNOSUPPORT: result = WSAESOCKTNOSUPPORT; break;
  152. #endif
  153. #ifdef ETIMEDOUT
  154. case ETIMEDOUT: result = WSAETIMEDOUT; break;
  155. #endif
  156. #ifdef EWOULDBLOCK
  157. case EWOULDBLOCK: result = WSAEWOULDBLOCK; break;
  158. #endif
  159. #ifdef EADDRNOTAVAIL
  160. case EADDRNOTAVAIL: result = WSAEADDRNOTAVAIL; break;
  161. #endif
  162. /* This might happen with unix sockets */
  163. case ENOENT: result = WSAECONNREFUSED; break;
  164. #ifdef EDESTADDRREQ
  165. case EDESTADDRREQ: result = WSAEDESTADDRREQ; break;
  166. #endif
  167. #ifdef EHOSTDOWN
  168. case EHOSTDOWN: result = WSAEHOSTDOWN; break;
  169. #endif
  170. #ifdef ENETDOWN
  171. case ENETDOWN: result = WSAENETDOWN; break;
  172. #endif
  173. case ENODEV: result = WSAENETDOWN; break;
  174. default:
  175. sys_error = strerror (code);
  176. msg = g_locale_to_utf8 (sys_error, strlen (sys_error), NULL, NULL, NULL);
  177. if (function_name == NULL)
  178. function_name = __func__;
  179. g_warning ("%s: Need to translate %d [%s] into winsock error",
  180. function_name, code, msg);
  181. g_free (msg);
  182. result = WSASYSCALLFAILURE;
  183. }
  184. return result;
  185. }
  186. gint
  187. _wapi_get_win32_file_error (gint err)
  188. {
  189. gint ret;
  190. /* mapping ideas borrowed from wine. they may need some work */
  191. switch (err) {
  192. case EACCES: case EPERM: case EROFS:
  193. ret = ERROR_ACCESS_DENIED;
  194. break;
  195. case EAGAIN:
  196. ret = ERROR_SHARING_VIOLATION;
  197. break;
  198. case EBUSY:
  199. ret = ERROR_LOCK_VIOLATION;
  200. break;
  201. case EEXIST:
  202. ret = ERROR_FILE_EXISTS;
  203. break;
  204. case EINVAL: case ESPIPE:
  205. ret = ERROR_SEEK;
  206. break;
  207. case EISDIR:
  208. ret = ERROR_CANNOT_MAKE;
  209. break;
  210. case ENFILE: case EMFILE:
  211. ret = ERROR_TOO_MANY_OPEN_FILES;
  212. break;
  213. case ENOENT: case ENOTDIR:
  214. ret = ERROR_FILE_NOT_FOUND;
  215. break;
  216. case ENOSPC:
  217. ret = ERROR_HANDLE_DISK_FULL;
  218. break;
  219. case ENOTEMPTY:
  220. ret = ERROR_DIR_NOT_EMPTY;
  221. break;
  222. case ENOEXEC:
  223. ret = ERROR_BAD_FORMAT;
  224. break;
  225. case ENAMETOOLONG:
  226. ret = ERROR_FILENAME_EXCED_RANGE;
  227. break;
  228. #ifdef EINPROGRESS
  229. case EINPROGRESS:
  230. ret = ERROR_IO_PENDING;
  231. break;
  232. #endif
  233. case ENOSYS:
  234. ret = ERROR_NOT_SUPPORTED;
  235. break;
  236. case EBADF:
  237. ret = ERROR_INVALID_HANDLE;
  238. break;
  239. case EIO:
  240. ret = ERROR_INVALID_HANDLE;
  241. break;
  242. case EINTR:
  243. ret = ERROR_IO_PENDING; /* best match I could find */
  244. break;
  245. case EPIPE:
  246. ret = ERROR_WRITE_FAULT;
  247. break;
  248. default:
  249. g_message ("Unknown errno: %s\n", g_strerror (err));
  250. ret = ERROR_GEN_FAILURE;
  251. break;
  252. }
  253. return ret;
  254. }