2 * error.c: Error reporting
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
16 #include "mono/io-layer/wapi.h"
17 #include "mono/io-layer/wapi-private.h"
18 #include "mono/utils/mono-lazy-init.h"
20 static pthread_key_t error_key;
21 static mono_lazy_init_t error_key_once = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
23 static void error_init(void)
27 ret = pthread_key_create(&error_key, NULL);
31 static void error_cleanup (void)
35 ret = pthread_key_delete (error_key);
39 void _wapi_error_cleanup (void)
41 mono_lazy_cleanup (&error_key_once, error_cleanup);
47 * Retrieves the last error that occurred in the calling thread.
49 * Return value: The error code for the last error that happened on
52 guint32 GetLastError(void)
57 if (_wapi_has_shut_down)
59 mono_lazy_initialize(&error_key_once, error_init);
60 errptr=pthread_getspecific(error_key);
61 err=GPOINTER_TO_UINT(errptr);
68 * @code: The error code.
70 * Sets the error code in the calling thread.
72 void SetLastError(guint32 code)
76 if (_wapi_has_shut_down)
78 /* Set the thread-local error code */
79 mono_lazy_initialize(&error_key_once, error_init);
80 ret = pthread_setspecific(error_key, GUINT_TO_POINTER(code));
85 errno_to_WSA (guint32 code, const gchar *function_name)
92 case 0: result = ERROR_SUCCESS; break;
93 case EACCES: result = WSAEACCES; break;
95 case EADDRINUSE: result = WSAEADDRINUSE; break;
98 case EAFNOSUPPORT: result = WSAEAFNOSUPPORT; break;
100 #if EAGAIN != EWOULDBLOCK
101 case EAGAIN: result = WSAEWOULDBLOCK; break;
104 case EALREADY: result = WSAEALREADY; break;
106 case EBADF: result = WSAENOTSOCK; break;
108 case ECONNABORTED: result = WSAENETDOWN; break;
111 case ECONNREFUSED: result = WSAECONNREFUSED; break;
114 case ECONNRESET: result = WSAECONNRESET; break;
116 case EFAULT: result = WSAEFAULT; break;
118 case EHOSTUNREACH: result = WSAEHOSTUNREACH; break;
121 case EINPROGRESS: result = WSAEINPROGRESS; break;
123 case EINTR: result = WSAEINTR; break;
124 case EINVAL: result = WSAEINVAL; break;
125 /*FIXME: case EIO: result = WSAE????; break; */
127 case EISCONN: result = WSAEISCONN; break;
129 /* FIXME: case ELOOP: result = WSA????; break; */
130 case EMFILE: result = WSAEMFILE; break;
132 case EMSGSIZE: result = WSAEMSGSIZE; break;
134 /* FIXME: case ENAMETOOLONG: result = WSAEACCES; break; */
136 case ENETUNREACH: result = WSAENETUNREACH; break;
139 case ENOBUFS: result = WSAENOBUFS; break; /* not documented */
141 /* case ENOENT: result = WSAE????; break; */
142 case ENOMEM: result = WSAENOBUFS; break;
144 case ENOPROTOOPT: result = WSAENOPROTOOPT; break;
147 case ENOSR: result = WSAENETDOWN; break;
150 case ENOTCONN: result = WSAENOTCONN; break;
152 /*FIXME: case ENOTDIR: result = WSAE????; break; */
154 case ENOTSOCK: result = WSAENOTSOCK; break;
156 case ENOTTY: result = WSAENOTSOCK; break;
158 case EOPNOTSUPP: result = WSAEOPNOTSUPP; break;
160 case EPERM: result = WSAEACCES; break;
161 case EPIPE: result = WSAESHUTDOWN; break;
162 #ifdef EPROTONOSUPPORT
163 case EPROTONOSUPPORT: result = WSAEPROTONOSUPPORT; break;
166 case ERESTARTSYS: result = WSAENETDOWN; break;
168 /*FIXME: case EROFS: result = WSAE????; break; */
169 #ifdef ESOCKTNOSUPPORT
170 case ESOCKTNOSUPPORT: result = WSAESOCKTNOSUPPORT; break;
173 case ETIMEDOUT: result = WSAETIMEDOUT; break;
176 case EWOULDBLOCK: result = WSAEWOULDBLOCK; break;
179 case EADDRNOTAVAIL: result = WSAEADDRNOTAVAIL; break;
181 /* This might happen with unix sockets */
182 case ENOENT: result = WSAECONNREFUSED; break;
184 case EDESTADDRREQ: result = WSAEDESTADDRREQ; break;
187 case EHOSTDOWN: result = WSAEHOSTDOWN; break;
190 case ENETDOWN: result = WSAENETDOWN; break;
192 case ENODEV: result = WSAENETDOWN; break;
194 sys_error = strerror (code);
195 msg = g_locale_to_utf8 (sys_error, strlen (sys_error), NULL, NULL, NULL);
196 if (function_name == NULL)
197 function_name = __func__;
199 g_warning ("%s: Need to translate %d [%s] into winsock error",
200 function_name, code, msg);
203 result = WSASYSCALLFAILURE;
210 _wapi_get_win32_file_error (gint err)
213 /* mapping ideas borrowed from wine. they may need some work */
216 case EACCES: case EPERM: case EROFS:
217 ret = ERROR_ACCESS_DENIED;
221 ret = ERROR_SHARING_VIOLATION;
225 ret = ERROR_LOCK_VIOLATION;
229 ret = ERROR_FILE_EXISTS;
232 case EINVAL: case ESPIPE:
237 ret = ERROR_CANNOT_MAKE;
240 case ENFILE: case EMFILE:
241 ret = ERROR_TOO_MANY_OPEN_FILES;
244 case ENOENT: case ENOTDIR:
245 ret = ERROR_FILE_NOT_FOUND;
249 ret = ERROR_HANDLE_DISK_FULL;
253 ret = ERROR_DIR_NOT_EMPTY;
257 ret = ERROR_BAD_FORMAT;
261 ret = ERROR_FILENAME_EXCED_RANGE;
266 ret = ERROR_IO_PENDING;
271 ret = ERROR_NOT_SUPPORTED;
275 ret = ERROR_INVALID_HANDLE;
279 ret = ERROR_INVALID_HANDLE;
283 ret = ERROR_IO_PENDING; /* best match I could find */
287 ret = ERROR_WRITE_FAULT;
291 g_message ("Unknown errno: %s\n", g_strerror (err));
292 ret = ERROR_GEN_FAILURE;