2 * filewatcher.c: File System Watcher internal calls
5 * Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 * (C) 2004,2005,2006 Novell, Inc. (http://www.novell.com)
14 #include <mono/metadata/appdomain.h>
15 #include <mono/metadata/exception.h>
16 #include <mono/metadata/filewatcher.h>
17 #include <mono/metadata/marshal.h>
18 #if (defined (PLATFORM_WIN32) && WINVER >= 0x0400)
22 * We use the managed watcher on windows, so the code inside this #if is never used
25 ves_icall_System_IO_FSW_SupportsFSW (void)
31 ves_icall_System_IO_FSW_OpenDirectory (MonoString *path, gpointer reserved)
40 dir = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
41 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
48 ves_icall_System_IO_FSW_CloseDirectory (gpointer handle)
54 return CloseHandle (handle);
59 ves_icall_System_IO_FSW_ReadDirectoryChanges (gpointer handle,
61 gboolean includeSubdirs,
70 MonoObject *delegate = (MonoObject *) callback;
72 LPOVERLAPPED_COMPLETION_ROUTINE func;
76 size = mono_array_length (buffer);
77 dest = mono_array_addr_with_size (buffer, 1, 0);
79 im = mono_get_delegate_invoke (mono_object_get_class (delegate));
80 func = mono_compile_method (im);
82 * return ReadDirectoryChanges (handle, dest, size, includeSubdirs, filters,
83 NULL, (LPOVERLAPPED) overlap,
88 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
89 MonoString **filename,
98 static int (*FAMNextEvent) (gpointer, gpointer);
101 ves_icall_System_IO_FSW_SupportsFSW (void)
108 int lib_used = 4; /* gamin */
109 int inotify_instance;
113 inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
114 if (inotify_instance != -1) {
115 close (inotify_instance);
116 return 5; /* inotify */
119 filename = g_module_build_path (NULL, "libgamin-1.so.0");
120 fam_module = g_module_open (filename, G_MODULE_BIND_LAZY);
122 if (fam_module == NULL) {
123 lib_used = 2; /* FAM */
124 filename = g_module_build_path (NULL, "libfam.so.0");
125 fam_module = g_module_open (filename, G_MODULE_BIND_LAZY);
129 if (fam_module == NULL)
132 g_module_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
133 if (FAMNextEvent == NULL)
141 ves_icall_System_IO_FSW_OpenDirectory (MonoString *path, gpointer reserved)
147 ves_icall_System_IO_FSW_CloseDirectory (gpointer handle)
153 ves_icall_System_IO_FSW_ReadDirectoryChanges (gpointer handle,
155 gboolean includeSubdirs,
163 /* Almost copied from fam.h. Weird, I know */
168 typedef struct FAMEvent {
172 gchar filename [PATH_MAX];
178 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
179 MonoString **filename,
187 if (FAMNextEvent (conn, &ev) == 1) {
188 *filename = mono_string_new (mono_domain_get (), ev.filename);
190 *reqnum = ev.fr.reqnum;
198 #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) && !defined(__NR_inotify_init)
199 # if defined(__i386__)
200 # define __NR_inotify_init 291
201 # elif defined(__x86_64__)
202 # define __NR_inotify_init 253
203 # elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
204 # define __NR_inotify_init 275
205 # elif defined (__s390__) || defined (__s390x__)
206 # define __NR_inotify_init 284
207 # elif defined(__sparc__) || defined (__sparc64__)
208 # define __NR_inotify_init 151
209 # elif defined (__ia64__)
210 # define __NR_inotify_init 1277
211 # elif defined (__arm__)
212 # define __NR_inotify_init 316
213 # elif defined(__alpha__)
214 # define __NR_inotify_init 444
216 #ifdef __NR_inotify_init
217 # ifndef __NR_inotify_add_watch
218 # define __NR_inotify_add_watch (__NR_inotify_init + 1)
220 # ifndef __NR_inotify_rm_watch
221 # define __NR_inotify_rm_watch (__NR_inotify_init + 2)
226 #if !defined(__linux__) || !defined(__NR_inotify_init)
227 int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
232 int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *directory, gint32 mask)
237 int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, int watch_descriptor)
245 ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
247 return syscall (__NR_inotify_init);
251 ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *name, gint32 mask)
261 str = mono_string_to_utf8 (name);
262 retval = syscall (__NR_inotify_add_watch, fd, str, mask);
266 errno = ERROR_ACCESS_DENIED;
269 errno = ERROR_INVALID_HANDLE;
272 errno = ERROR_INVALID_ACCESS;
275 errno = ERROR_INVALID_DATA;
278 errno = ERROR_NOT_ENOUGH_MEMORY;
281 errno = ERROR_TOO_MANY_OPEN_FILES;
284 errno = ERROR_GEN_FAILURE;
287 mono_marshal_set_last_error ();
294 ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
296 return syscall (__NR_inotify_rm_watch, fd, watch_descriptor);