Merge pull request #3802 from lambdageek/dev-reference-attr-take3
[mono.git] / mono / io-layer / wapi.c
1
2 #include "wapi.h"
3
4 #include "io-trace.h"
5 #include "io.h"
6 #include "process-private.h"
7 #include "socket-private.h"
8
9 #include "mono/utils/mono-lazy-init.h"
10 #include "mono/metadata/w32handle.h"
11
12 gboolean _wapi_has_shut_down = FALSE;
13
14 void
15 wapi_init (void)
16 {
17         _wapi_io_init ();
18         _wapi_processes_init ();
19         _wapi_socket_init ();
20 }
21
22 void
23 wapi_cleanup (void)
24 {
25         g_assert (_wapi_has_shut_down == FALSE);
26         _wapi_has_shut_down = TRUE;
27
28         _wapi_error_cleanup ();
29         wapi_processes_cleanup ();
30         _wapi_io_cleanup ();
31 }
32
33 /* Use this instead of getpid(), to cope with linuxthreads.  It's a
34  * function rather than a variable lookup because we need to get at
35  * this before share_init() might have been called. */
36 static mono_lazy_init_t _wapi_pid_init_lazy = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED;
37 static pid_t _wapi_pid;
38
39 static void
40 _wapi_pid_init (void)
41 {
42         _wapi_pid = getpid ();
43 }
44
45 pid_t
46 wapi_getpid (void)
47 {
48         mono_lazy_initialize (&_wapi_pid_init_lazy, _wapi_pid_init);
49         return _wapi_pid;
50 }
51
52 /* Lots more to implement here, but this is all we need at the moment */
53 gboolean
54 DuplicateHandle (gpointer srcprocess, gpointer src, gpointer targetprocess, gpointer *target,
55         guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 options G_GNUC_UNUSED)
56 {
57         if (srcprocess != _WAPI_PROCESS_CURRENT || targetprocess != _WAPI_PROCESS_CURRENT) {
58                 /* Duplicating other process's handles is not supported */
59                 SetLastError (ERROR_INVALID_HANDLE);
60                 return FALSE;
61         }
62
63         if (src == _WAPI_PROCESS_CURRENT) {
64                 *target = _wapi_process_duplicate ();
65         } else {
66                 mono_w32handle_ref (src);
67                 *target = src;
68         }
69
70         return TRUE;
71 }
72
73 /**
74  * CloseHandle:
75  * @handle: The handle to release
76  *
77  * Closes and invalidates @handle, releasing any resources it
78  * consumes.  When the last handle to a temporary or non-persistent
79  * object is closed, that object can be deleted.  Closing the same
80  * handle twice is an error.
81  *
82  * Return value: %TRUE on success, %FALSE otherwise.
83  */
84 gboolean CloseHandle(gpointer handle)
85 {
86         if (handle == INVALID_HANDLE_VALUE){
87                 SetLastError (ERROR_INVALID_PARAMETER);
88                 return FALSE;
89         }
90         if (handle == (gpointer)0 && mono_w32handle_get_type (handle) != MONO_W32HANDLE_CONSOLE) {
91                 /* Problem: because we map file descriptors to the
92                  * same-numbered handle we can't tell the difference
93                  * between a bogus handle and the handle to stdin.
94                  * Assume that it's the console handle if that handle
95                  * exists...
96                  */
97                 SetLastError (ERROR_INVALID_PARAMETER);
98                 return FALSE;
99         }
100
101         mono_w32handle_unref (handle);
102         return TRUE;
103 }