X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ffilewatcher.c;h=40f44364990b603d6c6c6a28d726bc4dcf7fe3a3;hb=bf484297f1e88a8906894e6e0bf4bcd10ba43802;hp=7f8deeaceeed5d6de2498dbafc17df014802f575;hpb=7e18ed47c9606f3981e7b18cbc238d6781843153;p=mono.git diff --git a/mono/metadata/filewatcher.c b/mono/metadata/filewatcher.c index 7f8deeaceee..40f44364990 100644 --- a/mono/metadata/filewatcher.c +++ b/mono/metadata/filewatcher.c @@ -4,7 +4,7 @@ * 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 @@ -14,7 +14,8 @@ #include #include #include - +#include +#include #if (defined (PLATFORM_WIN32) && WINVER >= 0x0400) /* @@ -27,63 +28,6 @@ ves_icall_System_IO_FSW_SupportsFSW (void) return 1; } -gpointer -ves_icall_System_IO_FSW_OpenDirectory (MonoString *path, gpointer reserved) -{ - return NULL; - /* - gpointer dir; - gchar *utf8path; - - MONO_ARCH_SAVE_REGS; - - dir = CreateFile (path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - - return dir; - */ -} - -gboolean -ves_icall_System_IO_FSW_CloseDirectory (gpointer handle) -{ - return FALSE; - /* - MONO_ARCH_SAVE_REGS; - - return CloseHandle (handle); - */ -} - -gboolean -ves_icall_System_IO_FSW_ReadDirectoryChanges (gpointer handle, - MonoArray *buffer, - gboolean includeSubdirs, - gint filters, - gpointer overlap, - gpointer callback) -{ - return FALSE; - /* - gpointer dest; - gint size; - MonoObject *delegate = (MonoObject *) callback; - MonoMethod *im; - LPOVERLAPPED_COMPLETION_ROUTINE func; - - MONO_ARCH_SAVE_REGS; - - size = mono_array_length (buffer); - dest = mono_array_addr_with_size (buffer, 1, 0); - - im = mono_get_delegate_invoke (mono_object_get_class (delegate)); - func = mono_compile_method (im); - return FALSE; - * return ReadDirectoryChanges (handle, dest, size, includeSubdirs, filters, - NULL, (LPOVERLAPPED) overlap, - func); */ -} - gboolean ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn, MonoString **filename, @@ -92,6 +36,7 @@ ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn, { return FALSE; } + #else static int (*FAMNextEvent) (gpointer, gpointer); @@ -102,48 +47,40 @@ ves_icall_System_IO_FSW_SupportsFSW (void) #if HAVE_KQUEUE return 3; #else - GModule *fam_module; - gchar *filename; + MonoDl *fam_module; + int lib_used = 4; /* gamin */ + int inotify_instance; + void *iter; + char *err; MONO_ARCH_SAVE_REGS; - filename = g_module_build_path (NULL, "libfam.so.0"); - fam_module = g_module_open (filename, G_MODULE_BIND_LAZY); - g_free (filename); + inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance (); + if (inotify_instance != -1) { + close (inotify_instance); + return 5; /* inotify */ + } + + iter = NULL; + fam_module = mono_dl_open ("libgamin-1.so", MONO_DL_LAZY, NULL); + if (fam_module == NULL) { + lib_used = 2; /* FAM */ + iter = NULL; + fam_module = mono_dl_open ("libfam.so", MONO_DL_LAZY, NULL); + } + if (fam_module == NULL) return 0; - g_module_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent); + err = mono_dl_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent); + g_free (err); if (FAMNextEvent == NULL) return 0; - return 2; + return lib_used; #endif } -gpointer -ves_icall_System_IO_FSW_OpenDirectory (MonoString *path, gpointer reserved) -{ - return NULL; -} - -gboolean -ves_icall_System_IO_FSW_CloseDirectory (gpointer handle) -{ - return FALSE; -} - -gboolean -ves_icall_System_IO_FSW_ReadDirectoryChanges (gpointer handle, - MonoArray *buffer, - gboolean includeSubdirs, - gint filters, - gpointer overlap, - gpointer callback) -{ - return FALSE; -} - /* Almost copied from fam.h. Weird, I know */ typedef struct { gint reqnum; @@ -177,6 +114,107 @@ ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn, 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 +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