2 * error.c: Error reporting
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
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)
26 ret
= pthread_key_create(&error_key
, NULL
);
30 void _wapi_error_cleanup (void)
34 ret
= pthread_key_delete (error_key
);
41 * Retrieves the last error that occurred in the calling thread.
43 * Return value: The error code for the last error that happened on
46 guint32
GetLastError(void)
51 if (_wapi_has_shut_down
)
53 mono_once(&error_key_once
, error_init
);
54 errptr
=pthread_getspecific(error_key
);
55 err
=GPOINTER_TO_UINT(errptr
);
62 * @code: The error code.
64 * Sets the error code in the calling thread.
66 void SetLastError(guint32 code
)
70 if (_wapi_has_shut_down
)
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
));
79 errno_to_WSA (guint32 code
, const gchar
*function_name
)
86 case 0: result
= ERROR_SUCCESS
; break;
87 case EACCES
: result
= WSAEACCES
; break;
89 case EADDRINUSE
: result
= WSAEADDRINUSE
; break;
92 case EAFNOSUPPORT
: result
= WSAEAFNOSUPPORT
; break;
94 #if EAGAIN != EWOULDBLOCK
95 case EAGAIN
: result
= WSAEWOULDBLOCK
; break;
98 case EALREADY
: result
= WSAEALREADY
; break;
100 case EBADF
: result
= WSAENOTSOCK
; break;
102 case ECONNABORTED
: result
= WSAENETDOWN
; break;
105 case ECONNREFUSED
: result
= WSAECONNREFUSED
; break;
108 case ECONNRESET
: result
= WSAECONNRESET
; break;
110 case EFAULT
: result
= WSAEFAULT
; break;
112 case EHOSTUNREACH
: result
= WSAEHOSTUNREACH
; break;
115 case EINPROGRESS
: result
= WSAEINPROGRESS
; break;
117 case EINTR
: result
= WSAEINTR
; break;
118 case EINVAL
: result
= WSAEINVAL
; break;
119 /*FIXME: case EIO: result = WSAE????; break; */
121 case EISCONN
: result
= WSAEISCONN
; break;
123 /* FIXME: case ELOOP: result = WSA????; break; */
124 case EMFILE
: result
= WSAEMFILE
; break;
126 case EMSGSIZE
: result
= WSAEMSGSIZE
; break;
128 /* FIXME: case ENAMETOOLONG: result = WSAEACCES; break; */
130 case ENETUNREACH
: result
= WSAENETUNREACH
; break;
133 case ENOBUFS
: result
= WSAENOBUFS
; break; /* not documented */
135 /* case ENOENT: result = WSAE????; break; */
136 case ENOMEM
: result
= WSAENOBUFS
; break;
138 case ENOPROTOOPT
: result
= WSAENOPROTOOPT
; break;
141 case ENOSR
: result
= WSAENETDOWN
; break;
144 case ENOTCONN
: result
= WSAENOTCONN
; break;
146 /*FIXME: case ENOTDIR: result = WSAE????; break; */
148 case ENOTSOCK
: result
= WSAENOTSOCK
; break;
150 case ENOTTY
: result
= WSAENOTSOCK
; break;
152 case EOPNOTSUPP
: result
= WSAEOPNOTSUPP
; break;
154 case EPERM
: result
= WSAEACCES
; break;
155 case EPIPE
: result
= WSAESHUTDOWN
; break;
156 #ifdef EPROTONOSUPPORT
157 case EPROTONOSUPPORT
: result
= WSAEPROTONOSUPPORT
; break;
160 case ERESTARTSYS
: result
= WSAENETDOWN
; break;
162 /*FIXME: case EROFS: result = WSAE????; break; */
163 #ifdef ESOCKTNOSUPPORT
164 case ESOCKTNOSUPPORT
: result
= WSAESOCKTNOSUPPORT
; break;
167 case ETIMEDOUT
: result
= WSAETIMEDOUT
; break;
170 case EWOULDBLOCK
: result
= WSAEWOULDBLOCK
; break;
173 case EADDRNOTAVAIL
: result
= WSAEADDRNOTAVAIL
; break;
175 /* This might happen with unix sockets */
176 case ENOENT
: result
= WSAECONNREFUSED
; break;
178 case EDESTADDRREQ
: result
= WSAEDESTADDRREQ
; break;
181 case EHOSTDOWN
: result
= WSAEHOSTDOWN
; break;
184 case ENETDOWN
: result
= WSAENETDOWN
; break;
186 case ENODEV
: result
= WSAENETDOWN
; break;
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
);
197 result
= WSASYSCALLFAILURE
;
204 _wapi_get_win32_file_error (gint err
)
207 /* mapping ideas borrowed from wine. they may need some work */
210 case EACCES
: case EPERM
: case EROFS
:
211 ret
= ERROR_ACCESS_DENIED
;
215 ret
= ERROR_SHARING_VIOLATION
;
219 ret
= ERROR_LOCK_VIOLATION
;
223 ret
= ERROR_FILE_EXISTS
;
226 case EINVAL
: case ESPIPE
:
231 ret
= ERROR_CANNOT_MAKE
;
234 case ENFILE
: case EMFILE
:
235 ret
= ERROR_TOO_MANY_OPEN_FILES
;
238 case ENOENT
: case ENOTDIR
:
239 ret
= ERROR_FILE_NOT_FOUND
;
243 ret
= ERROR_HANDLE_DISK_FULL
;
247 ret
= ERROR_DIR_NOT_EMPTY
;
251 ret
= ERROR_BAD_FORMAT
;
255 ret
= ERROR_FILENAME_EXCED_RANGE
;
260 ret
= ERROR_IO_PENDING
;
265 ret
= ERROR_NOT_SUPPORTED
;
269 ret
= ERROR_INVALID_HANDLE
;
273 ret
= ERROR_INVALID_HANDLE
;
277 ret
= ERROR_IO_PENDING
; /* best match I could find */
281 ret
= ERROR_WRITE_FAULT
;
285 g_message ("Unknown errno: %s\n", g_strerror (err
));
286 ret
= ERROR_GEN_FAILURE
;