2003-02-02 Piers Haken <piersh@friskit.com>
[mono.git] / mono / io-layer / error.c
1 /*
2  * error.c:  Error reporting
3  *
4  * Author:
5  *      Dick Porter (dick@ximian.com)
6  *
7  * (C) 2002 Ximian, Inc.
8  */
9
10 #include <config.h>
11 #include <glib.h>
12 #include <pthread.h>
13 #include <string.h>
14 #include <errno.h>
15
16 #include "mono/io-layer/wapi.h"
17
18 static pthread_key_t error_key;
19 static mono_once_t error_key_once=MONO_ONCE_INIT;
20
21 static void error_init(void)
22 {
23         pthread_key_create(&error_key, NULL);
24 }
25
26 /**
27  * GetLastError:
28  *
29  * Retrieves the last error that occurred in the calling thread.
30  *
31  * Return value: The error code for the last error that happened on
32  * the calling thread.
33  */
34 guint32 GetLastError(void)
35 {
36         guint32 err;
37         void *errptr;
38         
39         mono_once(&error_key_once, error_init);
40         errptr=pthread_getspecific(error_key);
41         err=GPOINTER_TO_UINT(errptr);
42         
43         return(err);
44 }
45
46 /**
47  * SetLastError:
48  * @code: The error code.
49  *
50  * Sets the error code in the calling thread.
51  */
52 void SetLastError(guint32 code)
53 {
54         /* Set the thread-local error code */
55         mono_once(&error_key_once, error_init);
56         pthread_setspecific(error_key, GUINT_TO_POINTER(code));
57 }
58
59 guint32
60 errno_to_WSA (guint32 code, const gchar *function_name)
61 {
62         gint result = -1;
63         char *sys_error;
64         gchar *msg;
65
66         switch (code) {
67         case EACCES: result = WSAEACCES; break;
68         case EADDRINUSE: result = WSAEADDRINUSE; break;
69         case EAFNOSUPPORT: result = WSAEAFNOSUPPORT; break;
70 #if EAGAIN != EWOULDBLOCK
71         case EAGAIN: result = WSAEWOULDBLOCK; break;
72 #endif
73         case EALREADY: result = WSAEALREADY; break;
74         case EBADF: result = WSAENOTSOCK; break;
75         case ECONNABORTED: result = WSAENETDOWN; break;
76         case ECONNREFUSED: result = WSAECONNREFUSED; break;
77         case ECONNRESET: result = WSAECONNRESET; break;
78         case EFAULT: result = WSAEFAULT; break;
79         case EINPROGRESS: result = WSAEINPROGRESS; break;
80         case EINTR: result = WSAEINTR; break;
81         case EINVAL: result = WSAEINVAL; break;
82         /*FIXME: case EIO: result = WSAE????; break; */
83         case EISCONN: result = WSAEISCONN; break;
84         /* FIXME: case ELOOP: result = WSA????; break; */
85         case EMFILE: result = WSAEMFILE; break;
86         case EMSGSIZE: result = WSAEMSGSIZE; break;
87         /* FIXME: case ENAMETOOLONG: result = WSAEACCES; break; */
88         case ENETUNREACH: result = WSAENETUNREACH; break;
89         case ENOBUFS: result = WSAENOBUFS; break; /* not documented */
90         /* case ENOENT: result = WSAE????; break; */
91         case ENOMEM: result = WSAENOBUFS; break;
92         case ENOPROTOOPT: result = WSAENOPROTOOPT; break;
93 #ifdef ENOSR
94         case ENOSR: result = WSAENETDOWN; break;
95 #endif
96         case ENOTCONN: result = WSAENOTCONN; break;
97         /*FIXME: case ENOTDIR: result = WSAE????; break; */
98         case ENOTSOCK: result = WSAENOTSOCK; break;
99         case ENOTTY: result = WSAENOTSOCK; break;
100         case EOPNOTSUPP: result = WSAEOPNOTSUPP; break;
101         case EPERM: result = WSAEACCES; break;
102         case EPIPE: result = WSAESHUTDOWN; break;
103         case EPROTONOSUPPORT: result = WSAENETDOWN; break;
104 #if ERESTARTSYS
105         case ERESTARTSYS: result = WSAENETDOWN; break;
106 #endif
107         /*FIXME: case EROFS: result = WSAE????; break; */
108         case ESOCKTNOSUPPORT: result = WSAENETDOWN; break;
109         case ETIMEDOUT: result = WSAENETDOWN; break;
110         case EWOULDBLOCK: result = WSAEWOULDBLOCK; break;
111         default:
112                 sys_error = strerror (code);
113                 msg = g_locale_to_utf8 (sys_error, strlen (sys_error), NULL, NULL, NULL);
114                 if (function_name == NULL)
115                         function_name = G_GNUC_PRETTY_FUNCTION;
116
117                 g_warning ("%s: Need to translate %d [%s] into winsock error",
118                            function_name, code, msg);
119
120                 g_free (msg);
121                 result = WSASYSCALLFAILURE;
122         }
123
124         return result;
125 }
126