2 * filewatcher.c: File System Watcher internal calls
5 * Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 * Copyright 2004-2009 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>
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)
51 int lib_used
= 4; /* gamin */
58 inotify_instance
= ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
59 if (inotify_instance
!= -1) {
60 close (inotify_instance
);
61 return 5; /* inotify */
65 fam_module
= mono_dl_open ("libgamin-1.so", MONO_DL_LAZY
, NULL
);
66 if (fam_module
== NULL
) {
67 lib_used
= 2; /* FAM */
69 fam_module
= mono_dl_open ("libfam.so", MONO_DL_LAZY
, NULL
);
72 if (fam_module
== NULL
)
75 err
= mono_dl_symbol (fam_module
, "FAMNextEvent", (gpointer
*) &FAMNextEvent
);
77 if (FAMNextEvent
== NULL
)
84 /* Almost copied from fam.h. Weird, I know */
89 typedef struct FAMEvent
{
93 gchar filename
[PATH_MAX
];
99 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn
,
100 MonoString
**filename
,
108 if (FAMNextEvent (conn
, &ev
) == 1) {
109 *filename
= mono_string_new (mono_domain_get (), ev
.filename
);
111 *reqnum
= ev
.fr
.reqnum
;
119 #if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) && !defined(__NR_inotify_init)
120 # if defined(__i386__)
121 # define __NR_inotify_init 291
122 # elif defined(__x86_64__)
123 # define __NR_inotify_init 253
124 # elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
125 # define __NR_inotify_init 275
126 # elif defined (__s390__) || defined (__s390x__)
127 # define __NR_inotify_init 284
128 # elif defined(__sparc__) || defined (__sparc64__)
129 # define __NR_inotify_init 151
130 # elif defined (__ia64__)
131 # define __NR_inotify_init 1277
132 # elif defined (__arm__)
133 # define __NR_inotify_init 316
134 # elif defined(__alpha__)
135 # define __NR_inotify_init 444
137 #ifdef __NR_inotify_init
138 # ifndef __NR_inotify_add_watch
139 # define __NR_inotify_add_watch (__NR_inotify_init + 1)
141 # ifndef __NR_inotify_rm_watch
142 # define __NR_inotify_rm_watch (__NR_inotify_init + 2)
147 #if !defined(__linux__) || !defined(__NR_inotify_init)
148 int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
153 int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd
, MonoString
*directory
, gint32 mask
)
158 int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd
, int watch_descriptor
)
166 ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
168 return syscall (__NR_inotify_init
);
172 ves_icall_System_IO_InotifyWatcher_AddWatch (int fd
, MonoString
*name
, gint32 mask
)
182 str
= mono_string_to_utf8 (name
);
183 retval
= syscall (__NR_inotify_add_watch
, fd
, str
, mask
);
187 errno
= ERROR_ACCESS_DENIED
;
190 errno
= ERROR_INVALID_HANDLE
;
193 errno
= ERROR_INVALID_ACCESS
;
196 errno
= ERROR_INVALID_DATA
;
199 errno
= ERROR_NOT_ENOUGH_MEMORY
;
202 errno
= ERROR_TOO_MANY_OPEN_FILES
;
205 errno
= ERROR_GEN_FAILURE
;
208 mono_marshal_set_last_error ();
215 ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd
, gint32 watch_descriptor
)
217 return syscall (__NR_inotify_rm_watch
, fd
, watch_descriptor
);