* Authors:
* Gonzalo Paniagua Javier (gonzalo@ximian.com)
*
- * (C) 2004 Novell, Inc. (http://www.novell.com)
+ * (C) 2004,2005,2006 Novell, Inc. (http://www.novell.com)
*/
#ifdef HAVE_CONFIG_H
#include <mono/metadata/appdomain.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/filewatcher.h>
-
+#include <mono/metadata/marshal.h>
#if (defined (PLATFORM_WIN32) && WINVER >= 0x0400)
-/* TODO:
+
+/*
+ * TODO:
* We use the managed watcher on windows, so the code inside this #if is never used
*/
gint
}
gboolean
-ves_icall_System_IO_FSW_ReadDirectoryChanges ( gpointer handle,
- MonoArray *buffer,
- gboolean includeSubdirs,
- gint filters,
- gpointer overlap,
- gpointer callback)
+ves_icall_System_IO_FSW_ReadDirectoryChanges (gpointer handle,
+ MonoArray *buffer,
+ gboolean includeSubdirs,
+ gint filters,
+ gpointer overlap,
+ gpointer callback)
{
return FALSE;
/*
gboolean
ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
- MonoString **filename,
- gint *code,
- gint *reqnum)
+ MonoString **filename,
+ gint *code,
+ gint *reqnum)
{
return FALSE;
}
+
#else
static int (*FAMNextEvent) (gpointer, gpointer);
#else
GModule *fam_module;
gchar *filename;
+ int lib_used = 4; /* gamin */
+ int inotify_instance;
MONO_ARCH_SAVE_REGS;
- filename = g_module_build_path (NULL, "libfam.so.0");
+ inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
+ if (inotify_instance != -1) {
+ close (inotify_instance);
+ return 5; /* inotify */
+ }
+
+ filename = g_module_build_path (NULL, "libgamin-1.so.0");
fam_module = g_module_open (filename, G_MODULE_BIND_LAZY);
g_free (filename);
+ if (fam_module == NULL) {
+ lib_used = 2; /* FAM */
+ filename = g_module_build_path (NULL, "libfam.so.0");
+ fam_module = g_module_open (filename, G_MODULE_BIND_LAZY);
+ g_free (filename);
+ }
+
if (fam_module == NULL)
return 0;
if (FAMNextEvent == NULL)
return 0;
- return 2;
+ return lib_used;
#endif
}
}
gboolean
-ves_icall_System_IO_FSW_ReadDirectoryChanges ( gpointer handle,
- MonoArray *buffer,
- gboolean includeSubdirs,
- gint filters,
- gpointer overlap,
- gpointer callback)
+ves_icall_System_IO_FSW_ReadDirectoryChanges (gpointer handle,
+ MonoArray *buffer,
+ gboolean includeSubdirs,
+ gint filters,
+ gpointer overlap,
+ gpointer callback)
{
return FALSE;
}
} FAMRequest;
typedef struct FAMEvent {
- gpointer fc;
- FAMRequest fr;
- gchar *hostname;
- gchar filename [PATH_MAX];
- gpointer userdata;
- gint code;
+ gpointer fc;
+ FAMRequest fr;
+ gchar *hostname;
+ gchar filename [PATH_MAX];
+ gpointer userdata;
+ gint code;
} FAMEvent;
gboolean
ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
- MonoString **filename,
- gint *code,
- gint *reqnum)
+ MonoString **filename,
+ gint *code,
+ gint *reqnum)
{
FAMEvent ev;
return FALSE;
}
+#endif
+
+#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H) && !defined(__NR_inotify_init)
+# if defined(__i386__)
+# define __NR_inotify_init 291
+# elif defined(__x86_64__)
+# define __NR_inotify_init 253
+# elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
+# define __NR_inotify_init 275
+# elif defined (__s390__) || defined (__s390x__)
+# define __NR_inotify_init 284
+# elif defined(__sparc__) || defined (__sparc64__)
+# define __NR_inotify_init 151
+# elif defined (__ia64__)
+# define __NR_inotify_init 1277
+# elif defined (__arm__)
+# define __NR_inotify_init 316
+# elif defined(__alpha__)
+# define __NR_inotify_init 444
+# endif
+#ifdef __NR_inotify_init
+# ifndef __NR_inotify_add_watch
+# define __NR_inotify_add_watch (__NR_inotify_init + 1)
+# endif
+# ifndef __NR_inotify_rm_watch
+# define __NR_inotify_rm_watch (__NR_inotify_init + 2)
+# endif
+#endif
+#endif
+
+#if !defined(__linux__) || !defined(__NR_inotify_init)
+int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
+{
+ return -1;
+}
+
+int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *directory, gint32 mask)
+{
+ return -1;
+}
+int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, int watch_descriptor)
+{
+ return -1;
+}
+#else
+#include <errno.h>
+
+int
+ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
+{
+ return syscall (__NR_inotify_init);
+}
+
+int
+ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *name, gint32 mask)
+{
+ char *str;
+ int retval;
+
+ MONO_ARCH_SAVE_REGS;
+
+ if (name == NULL)
+ return -1;
+
+ str = mono_string_to_utf8 (name);
+ retval = syscall (__NR_inotify_add_watch, fd, str, mask);
+ if (retval < 0) {
+ switch (errno) {
+ case EACCES:
+ errno = ERROR_ACCESS_DENIED;
+ break;
+ case EBADF:
+ errno = ERROR_INVALID_HANDLE;
+ break;
+ case EFAULT:
+ errno = ERROR_INVALID_ACCESS;
+ break;
+ case EINVAL:
+ errno = ERROR_INVALID_DATA;
+ break;
+ case ENOMEM:
+ errno = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ case ENOSPC:
+ errno = ERROR_TOO_MANY_OPEN_FILES;
+ break;
+ default:
+ errno = ERROR_GEN_FAILURE;
+ break;
+ }
+ mono_marshal_set_last_error ();
+ }
+ g_free (str);
+ return retval;
+}
+
+int
+ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
+{
+ return syscall (__NR_inotify_rm_watch, fd, watch_descriptor);
+}
#endif