2004-02-19 Gonzalo Paniagua Javier <gonzalo@ximian.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 EHOSTUNREACH: result = WSAEHOSTUNREACH; break;
80         case EINPROGRESS: result = WSAEINPROGRESS; break;
81         case EINTR: result = WSAEINTR; break;
82         case EINVAL: result = WSAEINVAL; break;
83         /*FIXME: case EIO: result = WSAE????; break; */
84         case EISCONN: result = WSAEISCONN; break;
85         /* FIXME: case ELOOP: result = WSA????; break; */
86         case EMFILE: result = WSAEMFILE; break;
87         case EMSGSIZE: result = WSAEMSGSIZE; break;
88         /* FIXME: case ENAMETOOLONG: result = WSAEACCES; break; */
89         case ENETUNREACH: result = WSAENETUNREACH; break;
90         case ENOBUFS: result = WSAENOBUFS; break; /* not documented */
91         /* case ENOENT: result = WSAE????; break; */
92         case ENOMEM: result = WSAENOBUFS; break;
93         case ENOPROTOOPT: result = WSAENOPROTOOPT; break;
94 #ifdef ENOSR
95         case ENOSR: result = WSAENETDOWN; break;
96 #endif
97         case ENOTCONN: result = WSAENOTCONN; break;
98         /*FIXME: case ENOTDIR: result = WSAE????; break; */
99         case ENOTSOCK: result = WSAENOTSOCK; break;
100         case ENOTTY: result = WSAENOTSOCK; break;
101         case EOPNOTSUPP: result = WSAEOPNOTSUPP; break;
102         case EPERM: result = WSAEACCES; break;
103         case EPIPE: result = WSAESHUTDOWN; break;
104         case EPROTONOSUPPORT: result = WSAEPROTONOSUPPORT; break;
105 #if ERESTARTSYS
106         case ERESTARTSYS: result = WSAENETDOWN; break;
107 #endif
108         /*FIXME: case EROFS: result = WSAE????; break; */
109         case ESOCKTNOSUPPORT: result = WSAESOCKTNOSUPPORT; break;
110         case ETIMEDOUT: result = WSAENETDOWN; break;
111         case EWOULDBLOCK: result = WSAEWOULDBLOCK; break;
112         default:
113                 sys_error = strerror (code);
114                 msg = g_locale_to_utf8 (sys_error, strlen (sys_error), NULL, NULL, NULL);
115                 if (function_name == NULL)
116                         function_name = G_GNUC_PRETTY_FUNCTION;
117
118                 g_warning ("%s: Need to translate %d [%s] into winsock error",
119                            function_name, code, msg);
120
121                 g_free (msg);
122                 result = WSASYSCALLFAILURE;
123         }
124
125         return result;
126 }
127