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 #include <mono/utils/mono-dl.h>
19 #if (defined (PLATFORM_WIN32) && WINVER >= 0x0400)
23 * We use the managed watcher on windows, so the code inside this #if is never used
26 ves_icall_System_IO_FSW_SupportsFSW (void)
32 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
33 MonoString **filename,
42 static int (*FAMNextEvent) (gpointer, gpointer);
45 ves_icall_System_IO_FSW_SupportsFSW (void)
52 int lib_used = 4; /* gamin */
59 inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
60 if (inotify_instance != -1) {
61 close (inotify_instance);
62 return 5; /* inotify */
66 /* the build_path calls here should be avoided, since we provide the full name */
67 filename = mono_dl_build_path (NULL, "libgamin-1.so.0", &iter);
68 fam_module = mono_dl_open (filename, MONO_DL_LAZY, NULL);
70 if (fam_module == NULL) {
71 lib_used = 2; /* FAM */
73 filename = mono_dl_build_path (NULL, "libfam.so.0", &iter);
74 fam_module = mono_dl_open (filename, MONO_DL_LAZY, NULL);
78 if (fam_module == NULL)
81 err = mono_dl_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
83 if (FAMNextEvent == NULL)
90 /* Almost copied from fam.h. Weird, I know */
95 typedef struct FAMEvent {
99 gchar filename [PATH_MAX];
105 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
106 MonoString **filename,
114 if (FAMNextEvent (conn, &ev) == 1) {
115 *filename = mono_string_new (mono_domain_get (), ev.filename);
117 *reqnum = ev.fr.reqnum;
125 #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) && !defined(__NR_inotify_init)
126 # if defined(__i386__)
127 # define __NR_inotify_init 291
128 # elif defined(__x86_64__)
129 # define __NR_inotify_init 253
130 # elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
131 # define __NR_inotify_init 275
132 # elif defined (__s390__) || defined (__s390x__)
133 # define __NR_inotify_init 284
134 # elif defined(__sparc__) || defined (__sparc64__)
135 # define __NR_inotify_init 151
136 # elif defined (__ia64__)
137 # define __NR_inotify_init 1277
138 # elif defined (__arm__)
139 # define __NR_inotify_init 316
140 # elif defined(__alpha__)
141 # define __NR_inotify_init 444
143 #ifdef __NR_inotify_init
144 # ifndef __NR_inotify_add_watch
145 # define __NR_inotify_add_watch (__NR_inotify_init + 1)
147 # ifndef __NR_inotify_rm_watch
148 # define __NR_inotify_rm_watch (__NR_inotify_init + 2)
153 #if !defined(__linux__) || !defined(__NR_inotify_init)
154 int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
159 int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *directory, gint32 mask)
164 int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, int watch_descriptor)
172 ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
174 return syscall (__NR_inotify_init);
178 ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *name, gint32 mask)
188 str = mono_string_to_utf8 (name);
189 retval = syscall (__NR_inotify_add_watch, fd, str, mask);
193 errno = ERROR_ACCESS_DENIED;
196 errno = ERROR_INVALID_HANDLE;
199 errno = ERROR_INVALID_ACCESS;
202 errno = ERROR_INVALID_DATA;
205 errno = ERROR_NOT_ENOUGH_MEMORY;
208 errno = ERROR_TOO_MANY_OPEN_FILES;
211 errno = ERROR_GEN_FAILURE;
214 mono_marshal_set_last_error ();
221 ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
223 return syscall (__NR_inotify_rm_watch, fd, watch_descriptor);