2004-09-06 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / filewatcher.c
1 /*
2  * filewatcher.c: File System Watcher internal calls
3  *
4  * Authors:
5  *      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6  *
7  * (C) 2004 Novell, Inc. (http://www.novell.com)
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <mono/metadata/appdomain.h>
15 #include <mono/metadata/exception.h>
16 #include <mono/metadata/filewatcher.h>
17
18 #if (defined (PLATFORM_WIN32) && WINVER >= 0x0400)
19 /* Supported under windows */
20 gint
21 ves_icall_System_IO_FSW_SupportsFSW (void)
22 {
23         return 1;
24 }
25
26 gpointer
27 ves_icall_System_IO_FSW_OpenDirectory (MonoString *path, gpointer reserved)
28 {
29         gpointer dir;
30         gchar *utf8path;
31
32         MONO_ARCH_SAVE_REGS;
33
34         utf8path = mono_string_to_utf8 (path);
35         dir = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
36                           NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
37         g_free (utf8path);
38
39         return dir;
40 }
41
42 gboolean
43 ves_icall_System_IO_FSW_CloseDirectory (gpointer handle)
44 {
45         MONO_ARCH_SAVE_REGS;
46
47         return CloseHandle (handle);
48 }
49
50 gboolean
51 ves_icall_System_IO_FSW_ReadDirectoryChanges (  gpointer handle,
52                                                 MonoArray *buffer,
53                                                 gboolean includeSubdirs,
54                                                 gint filters,
55                                                 gpointer overlap,
56                                                 gpointer callback)
57 {
58         gpointer dest;
59         gint size;
60         MonoObject *delegate = (MonoObject *) callback;
61         MonoMethod *im;
62         LPOVERLAPPED_COMPLETION_ROUTINE func;
63
64         MONO_ARCH_SAVE_REGS;
65
66         size = mono_array_length (buffer);
67         dest = mono_array_addr_with_size (buffer, 1, 0);
68
69         im = mono_get_delegate_invoke (mono_object_get_class (delegate));
70         func = mono_compile_method (im);
71         return FALSE;
72         /* return ReadDirectoryChanges (handle, dest, size, includeSubdirs, filters,
73                                      NULL, (LPOVERLAPPED) overlap,
74                                      func); */
75 }
76
77 gboolean
78 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
79                                                 MonoString **filename,
80                                                 gint *code,
81                                                 gint *reqnum)
82 {
83         return FALSE;
84 }
85 #else
86
87 static int (*FAMNextEvent) (gpointer, gpointer);
88
89 gint
90 ves_icall_System_IO_FSW_SupportsFSW (void)
91 {
92 #if HAVE_KQUEUE
93         return 3;
94 #else
95         GModule *fam_module;
96         gchar *filename;
97
98         MONO_ARCH_SAVE_REGS;
99
100         filename = g_module_build_path (NULL, "libfam.so.0");
101         fam_module = g_module_open (filename, G_MODULE_BIND_LAZY);
102         g_free (filename);
103         if (fam_module == NULL)
104                 return 0;
105
106         g_module_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
107         if (FAMNextEvent == NULL)
108                 return 0;
109
110         return 2;
111 #endif
112 }
113
114 gpointer
115 ves_icall_System_IO_FSW_OpenDirectory (MonoString *path, gpointer reserved)
116 {
117         return NULL;
118 }
119
120 gboolean
121 ves_icall_System_IO_FSW_CloseDirectory (gpointer handle)
122 {
123         return FALSE;
124 }
125
126 gboolean
127 ves_icall_System_IO_FSW_ReadDirectoryChanges (  gpointer handle,
128                                                 MonoArray *buffer,
129                                                 gboolean includeSubdirs,
130                                                 gint filters,
131                                                 gpointer overlap,
132                                                 gpointer callback)
133 {
134         return FALSE;
135 }
136
137 /* Almost copied from fam.h. Weird, I know */
138 typedef struct {
139         gint reqnum;
140 } FAMRequest;
141
142 typedef struct FAMEvent {
143     gpointer fc;
144     FAMRequest fr;
145     gchar *hostname;
146     gchar filename [PATH_MAX];
147     gpointer userdata;
148     gint code;
149 } FAMEvent;
150
151 gboolean
152 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
153                                                 MonoString **filename,
154                                                 gint *code,
155                                                 gint *reqnum)
156 {
157         FAMEvent ev;
158
159         MONO_ARCH_SAVE_REGS;
160
161         if (FAMNextEvent (conn, &ev) == 1) {
162                 *filename = mono_string_new (mono_domain_get (), ev.filename);
163                 *code = ev.code;
164                 *reqnum = ev.fr.reqnum;
165                 return TRUE;
166         }
167
168         return FALSE;
169 }
170
171 #endif
172