Bump external/ikdasm to master.
[mono-project.git] / mono / io-layer / error.c
blobe45fff4bcdda3efa2f323e8b5f72240d22b18683
1 /*
2 * error.c: Error reporting
4 * Author:
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
8 */
10 #include <config.h>
11 #include <glib.h>
12 #include <pthread.h>
13 #include <string.h>
14 #include <errno.h>
16 #include "mono/io-layer/wapi.h"
18 static pthread_key_t error_key;
19 static mono_once_t error_key_once=MONO_ONCE_INIT;
20 extern gboolean _wapi_has_shut_down;
22 static void error_init(void)
24 int ret;
26 ret = pthread_key_create(&error_key, NULL);
27 g_assert (ret == 0);
30 void _wapi_error_cleanup (void)
32 int ret;
34 ret = pthread_key_delete (error_key);
35 g_assert (ret == 0);
38 /**
39 * GetLastError:
41 * Retrieves the last error that occurred in the calling thread.
43 * Return value: The error code for the last error that happened on
44 * the calling thread.
46 guint32 GetLastError(void)
48 guint32 err;
49 void *errptr;
51 if (_wapi_has_shut_down)
52 return 0;
53 mono_once(&error_key_once, error_init);
54 errptr=pthread_getspecific(error_key);
55 err=GPOINTER_TO_UINT(errptr);
57 return(err);
60 /**
61 * SetLastError:
62 * @code: The error code.
64 * Sets the error code in the calling thread.
66 void SetLastError(guint32 code)
68 int ret;
70 if (_wapi_has_shut_down)
71 return;
72 /* Set the thread-local error code */
73 mono_once(&error_key_once, error_init);
74 ret = pthread_setspecific(error_key, GUINT_TO_POINTER(code));
75 g_assert (ret == 0);
78 guint32
79 errno_to_WSA (guint32 code, const gchar *function_name)
81 gint result = -1;
82 char *sys_error;
83 gchar *msg;
85 switch (code) {
86 case 0: result = ERROR_SUCCESS; break;
87 case EACCES: result = WSAEACCES; break;
88 #ifdef EADDRINUSE
89 case EADDRINUSE: result = WSAEADDRINUSE; break;
90 #endif
91 #ifdef EAFNOSUPPORT
92 case EAFNOSUPPORT: result = WSAEAFNOSUPPORT; break;
93 #endif
94 #if EAGAIN != EWOULDBLOCK
95 case EAGAIN: result = WSAEWOULDBLOCK; break;
96 #endif
97 #ifdef EALREADY
98 case EALREADY: result = WSAEALREADY; break;
99 #endif
100 case EBADF: result = WSAENOTSOCK; break;
101 #ifdef ECONNABORTED
102 case ECONNABORTED: result = WSAENETDOWN; break;
103 #endif
104 #ifdef ECONNREFUSED
105 case ECONNREFUSED: result = WSAECONNREFUSED; break;
106 #endif
107 #ifdef ECONNRESET
108 case ECONNRESET: result = WSAECONNRESET; break;
109 #endif
110 case EFAULT: result = WSAEFAULT; break;
111 #ifdef EHOSTUNREACH
112 case EHOSTUNREACH: result = WSAEHOSTUNREACH; break;
113 #endif
114 #ifdef EINPROGRESS
115 case EINPROGRESS: result = WSAEINPROGRESS; break;
116 #endif
117 case EINTR: result = WSAEINTR; break;
118 case EINVAL: result = WSAEINVAL; break;
119 /*FIXME: case EIO: result = WSAE????; break; */
120 #ifdef EISCONN
121 case EISCONN: result = WSAEISCONN; break;
122 #endif
123 /* FIXME: case ELOOP: result = WSA????; break; */
124 case EMFILE: result = WSAEMFILE; break;
125 #ifdef EMSGSIZE
126 case EMSGSIZE: result = WSAEMSGSIZE; break;
127 #endif
128 /* FIXME: case ENAMETOOLONG: result = WSAEACCES; break; */
129 #ifdef ENETUNREACH
130 case ENETUNREACH: result = WSAENETUNREACH; break;
131 #endif
132 #ifdef ENOBUFS
133 case ENOBUFS: result = WSAENOBUFS; break; /* not documented */
134 #endif
135 /* case ENOENT: result = WSAE????; break; */
136 case ENOMEM: result = WSAENOBUFS; break;
137 #ifdef ENOPROTOOPT
138 case ENOPROTOOPT: result = WSAENOPROTOOPT; break;
139 #endif
140 #ifdef ENOSR
141 case ENOSR: result = WSAENETDOWN; break;
142 #endif
143 #ifdef ENOTCONN
144 case ENOTCONN: result = WSAENOTCONN; break;
145 #endif
146 /*FIXME: case ENOTDIR: result = WSAE????; break; */
147 #ifdef ENOTSOCK
148 case ENOTSOCK: result = WSAENOTSOCK; break;
149 #endif
150 case ENOTTY: result = WSAENOTSOCK; break;
151 #ifdef EOPNOTSUPP
152 case EOPNOTSUPP: result = WSAEOPNOTSUPP; break;
153 #endif
154 case EPERM: result = WSAEACCES; break;
155 case EPIPE: result = WSAESHUTDOWN; break;
156 #ifdef EPROTONOSUPPORT
157 case EPROTONOSUPPORT: result = WSAEPROTONOSUPPORT; break;
158 #endif
159 #if ERESTARTSYS
160 case ERESTARTSYS: result = WSAENETDOWN; break;
161 #endif
162 /*FIXME: case EROFS: result = WSAE????; break; */
163 #ifdef ESOCKTNOSUPPORT
164 case ESOCKTNOSUPPORT: result = WSAESOCKTNOSUPPORT; break;
165 #endif
166 #ifdef ETIMEDOUT
167 case ETIMEDOUT: result = WSAETIMEDOUT; break;
168 #endif
169 #ifdef EWOULDBLOCK
170 case EWOULDBLOCK: result = WSAEWOULDBLOCK; break;
171 #endif
172 #ifdef EADDRNOTAVAIL
173 case EADDRNOTAVAIL: result = WSAEADDRNOTAVAIL; break;
174 #endif
175 /* This might happen with unix sockets */
176 case ENOENT: result = WSAECONNREFUSED; break;
177 #ifdef EDESTADDRREQ
178 case EDESTADDRREQ: result = WSAEDESTADDRREQ; break;
179 #endif
180 #ifdef EHOSTDOWN
181 case EHOSTDOWN: result = WSAEHOSTDOWN; break;
182 #endif
183 #ifdef ENETDOWN
184 case ENETDOWN: result = WSAENETDOWN; break;
185 #endif
186 case ENODEV: result = WSAENETDOWN; break;
187 default:
188 sys_error = strerror (code);
189 msg = g_locale_to_utf8 (sys_error, strlen (sys_error), NULL, NULL, NULL);
190 if (function_name == NULL)
191 function_name = __func__;
193 g_warning ("%s: Need to translate %d [%s] into winsock error",
194 function_name, code, msg);
196 g_free (msg);
197 result = WSASYSCALLFAILURE;
200 return result;
203 gint
204 _wapi_get_win32_file_error (gint err)
206 gint ret;
207 /* mapping ideas borrowed from wine. they may need some work */
209 switch (err) {
210 case EACCES: case EPERM: case EROFS:
211 ret = ERROR_ACCESS_DENIED;
212 break;
214 case EAGAIN:
215 ret = ERROR_SHARING_VIOLATION;
216 break;
218 case EBUSY:
219 ret = ERROR_LOCK_VIOLATION;
220 break;
222 case EEXIST:
223 ret = ERROR_FILE_EXISTS;
224 break;
226 case EINVAL: case ESPIPE:
227 ret = ERROR_SEEK;
228 break;
230 case EISDIR:
231 ret = ERROR_CANNOT_MAKE;
232 break;
234 case ENFILE: case EMFILE:
235 ret = ERROR_TOO_MANY_OPEN_FILES;
236 break;
238 case ENOENT: case ENOTDIR:
239 ret = ERROR_FILE_NOT_FOUND;
240 break;
242 case ENOSPC:
243 ret = ERROR_HANDLE_DISK_FULL;
244 break;
246 case ENOTEMPTY:
247 ret = ERROR_DIR_NOT_EMPTY;
248 break;
250 case ENOEXEC:
251 ret = ERROR_BAD_FORMAT;
252 break;
254 case ENAMETOOLONG:
255 ret = ERROR_FILENAME_EXCED_RANGE;
256 break;
258 #ifdef EINPROGRESS
259 case EINPROGRESS:
260 ret = ERROR_IO_PENDING;
261 break;
262 #endif
264 case ENOSYS:
265 ret = ERROR_NOT_SUPPORTED;
266 break;
268 case EBADF:
269 ret = ERROR_INVALID_HANDLE;
270 break;
272 case EIO:
273 ret = ERROR_INVALID_HANDLE;
274 break;
276 case EINTR:
277 ret = ERROR_IO_PENDING; /* best match I could find */
278 break;
280 case EPIPE:
281 ret = ERROR_WRITE_FAULT;
282 break;
284 default:
285 g_message ("Unknown errno: %s\n", g_strerror (err));
286 ret = ERROR_GEN_FAILURE;
287 break;
290 return ret;