[utils] Explicitly check if the system has mincore instead of relying on mmap been...
[mono-project.git] / mono / metadata / filewatcher.c
blob7b971aa6fc92ba06e56b1d6efd1796899a51c21b
1 /*
2 * filewatcher.c: File System Watcher internal calls
4 * Authors:
5 * Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
8 */
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
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 #include <mono/utils/mono-io-portability.h>
20 #ifdef HOST_WIN32
23 * TODO:
24 * We use the managed watcher on windows, so the code inside this #if is never used
26 gint
27 ves_icall_System_IO_FSW_SupportsFSW (void)
29 return 1;
32 gboolean
33 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
34 MonoString **filename,
35 gint *code,
36 gint *reqnum)
38 return FALSE;
41 #else
43 static int (*FAMNextEvent) (gpointer, gpointer);
45 gint
46 ves_icall_System_IO_FSW_SupportsFSW (void)
48 #if HAVE_KQUEUE
49 return 3;
50 #else
51 MonoDl *fam_module;
52 int lib_used = 4; /* gamin */
53 int inotify_instance;
54 void *iter;
55 char *err;
57 MONO_ARCH_SAVE_REGS;
59 inotify_instance = ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ();
60 if (inotify_instance != -1) {
61 close (inotify_instance);
62 return 5; /* inotify */
65 iter = NULL;
66 fam_module = mono_dl_open ("libgamin-1.so", MONO_DL_LAZY, NULL);
67 if (fam_module == NULL) {
68 lib_used = 2; /* FAM */
69 iter = NULL;
70 fam_module = mono_dl_open ("libfam.so", MONO_DL_LAZY, NULL);
73 if (fam_module == NULL)
74 return 0;
76 err = mono_dl_symbol (fam_module, "FAMNextEvent", (gpointer *) &FAMNextEvent);
77 g_free (err);
78 if (FAMNextEvent == NULL)
79 return 0;
81 return lib_used;
82 #endif
85 /* Almost copied from fam.h. Weird, I know */
86 typedef struct {
87 gint reqnum;
88 } FAMRequest;
90 typedef struct FAMEvent {
91 gpointer fc;
92 FAMRequest fr;
93 gchar *hostname;
94 gchar filename [PATH_MAX];
95 gpointer userdata;
96 gint code;
97 } FAMEvent;
99 gboolean
100 ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
101 MonoString **filename,
102 gint *code,
103 gint *reqnum)
105 FAMEvent ev;
107 MONO_ARCH_SAVE_REGS;
109 if (FAMNextEvent (conn, &ev) == 1) {
110 *filename = mono_string_new (mono_domain_get (), ev.filename);
111 *code = ev.code;
112 *reqnum = ev.fr.reqnum;
113 return TRUE;
116 return FALSE;
118 #endif
120 #ifndef HAVE_SYS_INOTIFY_H
121 int ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
123 return -1;
126 int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *directory, gint32 mask)
128 return -1;
131 int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
133 return -1;
135 #else
136 #include <sys/inotify.h>
137 #include <errno.h>
140 ves_icall_System_IO_InotifyWatcher_GetInotifyInstance ()
142 return inotify_init ();
146 ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *name, gint32 mask)
148 char *str, *path;
149 int retval;
151 MONO_ARCH_SAVE_REGS;
153 if (name == NULL)
154 return -1;
156 str = mono_string_to_utf8 (name);
157 path = mono_portability_find_file (str, TRUE);
158 if (!path)
159 path = str;
161 retval = inotify_add_watch (fd, path, mask);
162 if (retval < 0) {
163 switch (errno) {
164 case EACCES:
165 errno = ERROR_ACCESS_DENIED;
166 break;
167 case EBADF:
168 errno = ERROR_INVALID_HANDLE;
169 break;
170 case EFAULT:
171 errno = ERROR_INVALID_ACCESS;
172 break;
173 case EINVAL:
174 errno = ERROR_INVALID_DATA;
175 break;
176 case ENOMEM:
177 errno = ERROR_NOT_ENOUGH_MEMORY;
178 break;
179 case ENOSPC:
180 errno = ERROR_TOO_MANY_OPEN_FILES;
181 break;
182 default:
183 errno = ERROR_GEN_FAILURE;
184 break;
186 mono_marshal_set_last_error ();
188 if (path != str)
189 g_free (path);
190 g_free (str);
191 return retval;
195 ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor)
197 return inotify_rm_watch (fd, watch_descriptor);
199 #endif