1 /**
2  * \file
3  */
4 
5 #include "w32error.h"
6 
7 #include "utils/mono-lazy-init.h"
8 
9 static mono_lazy_init_t error_key_once = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
10 
11 static pthread_key_t error_key;
12 
13 static void
error_key_init(void)14 error_key_init (void)
15 {
16 	gint ret;
17 	ret = pthread_key_create (&error_key, NULL);
18 	g_assert (ret == 0);
19 }
20 
21 guint32
mono_w32error_get_last(void)22 mono_w32error_get_last (void)
23 {
24 	mono_lazy_initialize (&error_key_once, error_key_init);
25 	return GPOINTER_TO_UINT (pthread_getspecific (error_key));
26 }
27 
28 void
mono_w32error_set_last(guint32 error)29 mono_w32error_set_last (guint32 error)
30 {
31 	gint ret;
32 	mono_lazy_initialize (&error_key_once, error_key_init);
33 	ret = pthread_setspecific (error_key, GUINT_TO_POINTER (error));
34 	g_assert (ret == 0);
35 }
36 
37 guint32
mono_w32error_unix_to_win32(guint32 error)38 mono_w32error_unix_to_win32 (guint32 error)
39 {
40 	/* mapping ideas borrowed from wine. they may need some work */
41 
42 	switch (error) {
43 	case EACCES:
44 	case EPERM:
45 	case EROFS: return ERROR_ACCESS_DENIED;
46 	case EAGAIN: return ERROR_SHARING_VIOLATION;
47 	case EBUSY: return ERROR_LOCK_VIOLATION;
48 	case EEXIST: return ERROR_FILE_EXISTS;
49 	case EINVAL:
50 	case ESPIPE: return ERROR_SEEK;
51 	case EISDIR: return ERROR_CANNOT_MAKE;
52 	case ENFILE:
53 	case EMFILE: return ERROR_TOO_MANY_OPEN_FILES;
54 	case ENOENT:
55 	case ENOTDIR: return ERROR_FILE_NOT_FOUND;
56 	case ENOSPC: return ERROR_HANDLE_DISK_FULL;
57 	case ENOTEMPTY: return ERROR_DIR_NOT_EMPTY;
58 	case ENOEXEC: return ERROR_BAD_FORMAT;
59 	case ENAMETOOLONG: return ERROR_FILENAME_EXCED_RANGE;
60 #ifdef EINPROGRESS
61 	case EINPROGRESS: return ERROR_IO_PENDING;
62 #endif
63 	case ENOSYS: return ERROR_NOT_SUPPORTED;
64 	case EBADF: return ERROR_INVALID_HANDLE;
65 	case EIO: return ERROR_INVALID_HANDLE;
66 	case EINTR: return ERROR_IO_PENDING; /* best match I could find */
67 	case EPIPE: return ERROR_WRITE_FAULT;
68 	case ELOOP: return ERROR_CANT_RESOLVE_FILENAME;
69 #ifdef ENODEV
70 	case ENODEV: return ERROR_DEV_NOT_EXIST;
71 #endif
72 #ifdef ENXIO
73 	case ENXIO: return ERROR_DEV_NOT_EXIST;
74 #endif
75 #ifdef ENOTCONN
76 	case ENOTCONN: return ERROR_DEV_NOT_EXIST;
77 #endif
78 #ifdef EHOSTDOWN
79 	case EHOSTDOWN: return ERROR_DEV_NOT_EXIST;
80 #endif
81 
82 	default:
83 		g_warning ("%s: unknown error (%d) \"%s\"", __FILE__, error, g_strerror (error));
84 		return ERROR_NOT_SUPPORTED;
85 	}
86 }
87