[sgen] Always use one concurrent worker
[mono-project.git] / mono / io-layer / error.c
blob5b1b22d6dcd08d7cd3871e3ce99c52310f6cc7cf
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"
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)
25 int ret;
27 ret = pthread_key_create(&error_key, NULL);
28 g_assert (ret == 0);
31 static void error_cleanup (void)
33 int ret;
35 ret = pthread_key_delete (error_key);
36 g_assert (ret == 0);
39 void _wapi_error_cleanup (void)
41 mono_lazy_cleanup (&error_key_once, error_cleanup);
44 /**
45 * GetLastError:
47 * Retrieves the last error that occurred in the calling thread.
49 * Return value: The error code for the last error that happened on
50 * the calling thread.
52 guint32 GetLastError(void)
54 guint32 err;
55 void *errptr;
57 if (_wapi_has_shut_down)
58 return 0;
59 mono_lazy_initialize(&error_key_once, error_init);
60 errptr=pthread_getspecific(error_key);
61 err=GPOINTER_TO_UINT(errptr);
63 return(err);
66 /**
67 * SetLastError:
68 * @code: The error code.
70 * Sets the error code in the calling thread.
72 void SetLastError(guint32 code)
74 int ret;
76 if (_wapi_has_shut_down)
77 return;
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));
81 g_assert (ret == 0);
84 gint
85 _wapi_get_win32_file_error (gint err)
87 gint ret;
88 /* mapping ideas borrowed from wine. they may need some work */
90 switch (err) {
91 case EACCES: case EPERM: case EROFS:
92 ret = ERROR_ACCESS_DENIED;
93 break;
95 case EAGAIN:
96 ret = ERROR_SHARING_VIOLATION;
97 break;
99 case EBUSY:
100 ret = ERROR_LOCK_VIOLATION;
101 break;
103 case EEXIST:
104 ret = ERROR_FILE_EXISTS;
105 break;
107 case EINVAL: case ESPIPE:
108 ret = ERROR_SEEK;
109 break;
111 case EISDIR:
112 ret = ERROR_CANNOT_MAKE;
113 break;
115 case ENFILE: case EMFILE:
116 ret = ERROR_TOO_MANY_OPEN_FILES;
117 break;
119 case ENOENT: case ENOTDIR:
120 ret = ERROR_FILE_NOT_FOUND;
121 break;
123 case ENOSPC:
124 ret = ERROR_HANDLE_DISK_FULL;
125 break;
127 case ENOTEMPTY:
128 ret = ERROR_DIR_NOT_EMPTY;
129 break;
131 case ENOEXEC:
132 ret = ERROR_BAD_FORMAT;
133 break;
135 case ENAMETOOLONG:
136 ret = ERROR_FILENAME_EXCED_RANGE;
137 break;
139 #ifdef EINPROGRESS
140 case EINPROGRESS:
141 ret = ERROR_IO_PENDING;
142 break;
143 #endif
145 case ENOSYS:
146 ret = ERROR_NOT_SUPPORTED;
147 break;
149 case EBADF:
150 ret = ERROR_INVALID_HANDLE;
151 break;
153 case EIO:
154 ret = ERROR_INVALID_HANDLE;
155 break;
157 case EINTR:
158 ret = ERROR_IO_PENDING; /* best match I could find */
159 break;
161 case EPIPE:
162 ret = ERROR_WRITE_FAULT;
163 break;
165 default:
166 g_message ("Unknown errno: %s\n", g_strerror (err));
167 ret = ERROR_GEN_FAILURE;
168 break;
171 return ret;