[io-layer] Extract file (#4255)
[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 #include "mono/utils/mono-lazy-init.h"
18
19 static pthread_key_t error_key;
20 static mono_lazy_init_t error_key_once = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
21
22 static void error_init(void)
23 {
24         int ret;
25         
26         ret = pthread_key_create(&error_key, NULL);
27         g_assert (ret == 0);
28 }
29
30 /**
31  * GetLastError:
32  *
33  * Retrieves the last error that occurred in the calling thread.
34  *
35  * Return value: The error code for the last error that happened on
36  * the calling thread.
37  */
38 guint32 GetLastError(void)
39 {
40         guint32 err;
41         void *errptr;
42
43         mono_lazy_initialize(&error_key_once, error_init);
44         errptr=pthread_getspecific(error_key);
45         err=GPOINTER_TO_UINT(errptr);
46         
47         return(err);
48 }
49
50 /**
51  * SetLastError:
52  * @code: The error code.
53  *
54  * Sets the error code in the calling thread.
55  */
56 void SetLastError(guint32 code)
57 {
58         int ret;
59         
60         /* Set the thread-local error code */
61         mono_lazy_initialize(&error_key_once, error_init);
62         ret = pthread_setspecific(error_key, GUINT_TO_POINTER(code));
63         g_assert (ret == 0);
64 }
65
66 gint
67 _wapi_get_win32_file_error (gint err)
68 {
69         gint ret;
70         /* mapping ideas borrowed from wine. they may need some work */
71
72         switch (err) {
73         case EACCES: case EPERM: case EROFS:
74                 ret = ERROR_ACCESS_DENIED;
75                 break;
76         
77         case EAGAIN:
78                 ret = ERROR_SHARING_VIOLATION;
79                 break;
80         
81         case EBUSY:
82                 ret = ERROR_LOCK_VIOLATION;
83                 break;
84         
85         case EEXIST:
86                 ret = ERROR_FILE_EXISTS;
87                 break;
88         
89         case EINVAL: case ESPIPE:
90                 ret = ERROR_SEEK;
91                 break;
92         
93         case EISDIR:
94                 ret = ERROR_CANNOT_MAKE;
95                 break;
96         
97         case ENFILE: case EMFILE:
98                 ret = ERROR_TOO_MANY_OPEN_FILES;
99                 break;
100
101         case ENOENT: case ENOTDIR:
102                 ret = ERROR_FILE_NOT_FOUND;
103                 break;
104         
105         case ENOSPC:
106                 ret = ERROR_HANDLE_DISK_FULL;
107                 break;
108         
109         case ENOTEMPTY:
110                 ret = ERROR_DIR_NOT_EMPTY;
111                 break;
112
113         case ENOEXEC:
114                 ret = ERROR_BAD_FORMAT;
115                 break;
116
117         case ENAMETOOLONG:
118                 ret = ERROR_FILENAME_EXCED_RANGE;
119                 break;
120         
121 #ifdef EINPROGRESS
122         case EINPROGRESS:
123                 ret = ERROR_IO_PENDING;
124                 break;
125 #endif
126         
127         case ENOSYS:
128                 ret = ERROR_NOT_SUPPORTED;
129                 break;
130         
131         case EBADF:
132                 ret = ERROR_INVALID_HANDLE;
133                 break;
134                 
135         case EIO:
136                 ret = ERROR_INVALID_HANDLE;
137                 break;
138                 
139         case EINTR:
140                 ret = ERROR_IO_PENDING;         /* best match I could find */
141                 break;
142                 
143         case EPIPE:
144                 ret = ERROR_WRITE_FAULT;
145                 break;
146                 
147         default:
148                 g_message ("Unknown errno: %s\n", g_strerror (err));
149                 ret = ERROR_GEN_FAILURE;
150                 break;
151         }
152
153         return ret;
154 }
155