• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2   Copyright (c) 2011, 2012 Dmitry Matveev <me@dmitrymatveev.co.uk>
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy
5   of this software and associated documentation files (the "Software"), to deal
6   in the Software without restriction, including without limitation the rights
7   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   copies of the Software, and to permit persons to whom the Software is
9   furnished to do so, subject to the following conditions:
10 
11   The above copyright notice and this permission notice shall be included in
12   all copies or substantial portions of the Software.
13 
14   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   THE SOFTWARE.
21 *******************************************************************************/
22 
23 #include "config.h"
24 
25 #include <sys/types.h>
26 #include <sys/event.h>
27 #include <sys/time.h>
28 #include <sys/socket.h>
29 #include <sys/stat.h>
30 
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <string.h>
34 
35 #include <glib-object.h>
36 #include <glib/gfileutils.h>
37 #include <gio/gfilemonitor.h>
38 #include <gio/glocalfilemonitor.h>
39 #include <gio/giomodule.h>
40 #include <gio/gpollfilemonitor.h>
41 #include <gio/gfile.h>
42 #include <glib-unix.h>
43 #include "glib-private.h"
44 
45 #include "kqueue-helper.h"
46 #include "dep-list.h"
47 
48 G_LOCK_DEFINE_STATIC (kq_lock);
49 static GSource       *kq_source;
50 static int	      kq_queue = -1;
51 
52 #define G_TYPE_KQUEUE_FILE_MONITOR	(g_kqueue_file_monitor_get_type ())
53 #define G_KQUEUE_FILE_MONITOR(inst)	(G_TYPE_CHECK_INSTANCE_CAST ((inst), \
54 					G_TYPE_KQUEUE_FILE_MONITOR, GKqueueFileMonitor))
55 
56 /* C11 allows type redefinition, but GLib is configured to use C89, which causes
57  * clang to show warnings when we use a C11 feature. Since the C89 requirement
58  * is mostly used to support MSVC, we simply ignore the warning here because
59  * this file is never going to be useful on Windows. */
60 #ifdef __clang__
61 #pragma clang diagnostic push
62 #pragma clang diagnostic ignored "-Wtypedef-redefinition"
63 #endif
64 
65 typedef GLocalFileMonitorClass GKqueueFileMonitorClass;
66 
67 /* When the file we are monitoring is a directory, sub_dir is subscribed to the
68  * directory itself and sub_file is NULL.
69  *
70  * When the file we are monitoring is a regular file, sub_dir is subscribed to
71  * the directory containing the file and sub_file is subscribed to the file
72  * being monitored. We have to monitor both because it is possible that the
73  * file chosen for monitoring doesn't exist when the file monitor is started.
74  * We monitor on its parent in order to get notification when it is created.
75  *
76  * To distinguish between a directory monitor and a regular file monitor, check
77  * whether sub_file is NULL. */
78 struct _GKqueueFileMonitor
79 {
80   GLocalFileMonitor parent_instance;
81 
82   kqueue_sub *sub_dir;
83   kqueue_sub *sub_file;
84 #ifndef O_EVTONLY
85   GFileMonitor *fallback;
86   GFile *fbfile;
87 #endif
88 };
89 
90 #ifdef __clang__
91 #pragma clang diagnostic pop
92 #endif
93 
94 GType g_kqueue_file_monitor_get_type (void);
95 G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
96 	g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
97 		g_define_type_id,
98                 "kqueue",
99 		20))
100 
101 #ifndef O_EVTONLY
102 #define O_KQFLAG O_RDONLY
103 #else
104 #define O_KQFLAG O_EVTONLY
105 #endif
106 
107 static inline unsigned int
note_all(void)108 note_all (void)
109 {
110   unsigned int notes = NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE;
111 #ifdef NOTE_TRUNCATE
112   notes |= NOTE_TRUNCATE;
113 #endif
114 #ifdef NOTE_CLOSE_WRITE
115   notes |= NOTE_CLOSE_WRITE;
116 #endif
117   return notes;
118 }
119 
120 static gboolean g_kqueue_file_monitor_cancel (GFileMonitor* monitor);
121 static gboolean g_kqueue_file_monitor_is_supported (void);
122 
123 static kqueue_sub	*_kqsub_new (gchar *, gchar *, GKqueueFileMonitor *, GFileMonitorSource *);
124 static void		 _kqsub_free (kqueue_sub *);
125 static void		 _kqsub_cancel (kqueue_sub *);
126 
127 
128 #ifndef O_EVTONLY
129 static void
_fallback_callback(GFileMonitor * unused,GFile * first,GFile * second,GFileMonitorEvent event,gpointer udata)130 _fallback_callback (GFileMonitor      *unused,
131                     GFile             *first,
132                     GFile             *second,
133                     GFileMonitorEvent  event,
134                     gpointer           udata)
135 {
136   GKqueueFileMonitor *kq_mon = G_KQUEUE_FILE_MONITOR (udata);
137 
138   g_file_monitor_emit_event (G_FILE_MONITOR (kq_mon), first, second, event);
139 }
140 
141 /*
142  * _ke_is_excluded:
143  * @full_path - a path to file to check.
144  *
145  * Returns: TRUE if the file should be excluded from the kqueue-powered
146  *      monitoring, FALSE otherwise.
147  **/
148 static gboolean
_ke_is_excluded(const char * full_path)149 _ke_is_excluded (const char *full_path)
150 {
151   GFile *f = NULL;
152   GMount *mount = NULL;
153 
154   f = g_file_new_for_path (full_path);
155 
156   if (f != NULL) {
157     mount = g_file_find_enclosing_mount (f, NULL, NULL);
158     g_object_unref (f);
159   }
160 
161   if (mount != NULL && (g_str_has_prefix (full_path, "/media/") || g_str_has_prefix (full_path, "/run/media/")))
162   {
163     g_warning ("Excluding %s from kernel notification, falling back to poll", full_path);
164     if (mount)
165       g_object_unref (mount);
166     return TRUE;
167   }
168 
169   return FALSE;
170 }
171 #endif /* !O_EVTONLY */
172 
173 static void
g_kqueue_file_monitor_finalize(GObject * object)174 g_kqueue_file_monitor_finalize (GObject *object)
175 {
176   GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (object);
177 
178   if (kqueue_monitor->sub_dir)
179     {
180       _kqsub_cancel (kqueue_monitor->sub_dir);
181       _kqsub_free (kqueue_monitor->sub_dir);
182       kqueue_monitor->sub_dir = NULL;
183     }
184 
185   if (kqueue_monitor->sub_file)
186     {
187       _kqsub_cancel (kqueue_monitor->sub_file);
188       _kqsub_free (kqueue_monitor->sub_file);
189       kqueue_monitor->sub_file = NULL;
190     }
191 
192 #ifndef O_EVTONLY
193   if (kqueue_monitor->fallback)
194     g_object_unref (kqueue_monitor->fallback);
195 
196   if (kqueue_monitor->fbfile)
197     g_object_unref (kqueue_monitor->fbfile);
198 #endif
199 
200   if (G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize)
201     (*G_OBJECT_CLASS (g_kqueue_file_monitor_parent_class)->finalize) (object);
202 }
203 
204 static void
g_kqueue_file_monitor_start(GLocalFileMonitor * local_monitor,const gchar * dirname,const gchar * basename,const gchar * filename,GFileMonitorSource * source)205 g_kqueue_file_monitor_start (GLocalFileMonitor *local_monitor,
206                              const gchar *dirname,
207                              const gchar *basename,
208                              const gchar *filename,
209                              GFileMonitorSource *source)
210 {
211   GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (local_monitor);
212   kqueue_sub *sub_dir = NULL, *sub_file = NULL;
213   gchar *path_dir, *path_file, *file_basename;
214 
215   /* There are three possible cases here:
216    *
217    *  1. Directory: dirname != NULL, basename == NULL, filename == NULL
218    *  2. Regular file: dirname != NULL, basename != NULL, filename == NULL
219    *  3. Hard links: dirname == NULL, basename == NULL, filename != NULL
220    *
221    *  Note that we don't distinguish between case 2 and 3. Kqueue monitors
222    *  files based on file descriptors, so we always receive events come from
223    *  hard links.
224    */
225   if (filename != NULL)
226     {
227       path_dir = g_path_get_dirname (filename);
228       path_file = g_strdup (filename);
229       file_basename = g_path_get_basename (filename);
230     }
231   else
232     {
233       path_dir = g_strdup (dirname);
234       if (basename != NULL)
235         {
236           path_file = g_build_filename (dirname, basename, NULL);
237           file_basename = g_strdup (basename);
238         }
239       else
240         {
241           path_file = NULL;
242           file_basename = NULL;
243         }
244     }
245 
246 #ifndef O_EVTONLY
247   if (_ke_is_excluded (path_dir))
248     {
249       GFile *file;
250       if (path_file != NULL)
251         file = g_file_new_for_path (path_file);
252       else
253         file = g_file_new_for_path (path_dir);
254       g_free (path_dir);
255       g_free (path_file);
256       g_free (file_basename);
257       kqueue_monitor->fbfile = file;
258       kqueue_monitor->fallback = _g_poll_file_monitor_new (file);
259       g_signal_connect (kqueue_monitor->fallback, "changed",
260 			G_CALLBACK (_fallback_callback), kqueue_monitor);
261       return;
262     }
263 #endif
264 
265   /* For a directory monitor, create a subscription object anyway.
266    * It will be used for directory diff calculation routines.
267    * Wait, directory diff in a GKqueueFileMonitor?
268    * Yes, it is. When a file monitor is started on a non-existent
269    * file, GIO uses a GKqueueFileMonitor object for that. If a directory
270    * will be created under that path, GKqueueFileMonitor will have to
271    * handle the directory notifications. */
272   sub_dir = _kqsub_new (g_steal_pointer (&path_dir), NULL,
273                         kqueue_monitor, source);
274   if (!_kqsub_start_watching (sub_dir))
275     _km_add_missing (sub_dir);
276 
277   /* Unlike GInotifyFileMonitor, which always uses a directory monitor
278    * regardless of the type of the file being monitored, kqueue doesn't
279    * give us events generated by files under it when we are monitoring
280    * a directory. We have to monitor the file itself to know changes which
281    * was made to the file itself. */
282   if (path_file != NULL)
283     {
284       sub_file = _kqsub_new (g_steal_pointer (&path_file),
285                              g_steal_pointer (&file_basename),
286                              kqueue_monitor, source);
287       if (!_kqsub_start_watching (sub_file))
288         _km_add_missing (sub_file);
289     }
290 
291   kqueue_monitor->sub_dir = sub_dir;
292   kqueue_monitor->sub_file = sub_file;
293   g_clear_pointer (&path_dir, g_free);
294   g_clear_pointer (&path_file, g_free);
295   g_clear_pointer (&file_basename, g_free);
296 }
297 
298 static void
g_kqueue_file_monitor_class_init(GKqueueFileMonitorClass * klass)299 g_kqueue_file_monitor_class_init (GKqueueFileMonitorClass *klass)
300 {
301   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
302   GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass);
303   GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass);
304 
305   gobject_class->finalize = g_kqueue_file_monitor_finalize;
306   file_monitor_class->cancel = g_kqueue_file_monitor_cancel;
307 
308   local_file_monitor_class->is_supported = g_kqueue_file_monitor_is_supported;
309   local_file_monitor_class->start = g_kqueue_file_monitor_start;
310   local_file_monitor_class->mount_notify = TRUE; /* TODO: ??? */
311 }
312 
313 static void
g_kqueue_file_monitor_init(GKqueueFileMonitor * monitor)314 g_kqueue_file_monitor_init (GKqueueFileMonitor *monitor)
315 {
316 }
317 
318 static gboolean
g_kqueue_file_monitor_callback(gint fd,GIOCondition condition,gpointer user_data)319 g_kqueue_file_monitor_callback (gint fd, GIOCondition condition, gpointer user_data)
320 {
321   gint64 now = g_source_get_time (kq_source);
322   kqueue_sub *sub;
323   GFileMonitorSource *source;
324   struct kevent ev;
325   struct timespec ts;
326 
327   memset (&ts, 0, sizeof(ts));
328 
329   /* We must hold the global lock before accessing any kqueue_sub because it is
330    * possible for other threads to call g_kqueue_file_monitor_cancel, which may
331    * free the kqueue_sub struct we are accessing. */
332   G_LOCK (kq_lock);
333 
334   while (kevent(fd, NULL, 0, &ev, 1, &ts) > 0)
335     {
336         if (ev.filter != EVFILT_VNODE || ev.udata == NULL)
337           continue;
338 
339         sub = ev.udata;
340         source = sub->source;
341 
342         /* When we are monitoring a regular file which already exists, ignore
343          * events generated by its parent directory. This has to be the first
344          * check to prevent the following code to emit useless events */
345         if (sub->is_dir && sub->mon->sub_file != NULL && sub->mon->sub_file->fd != -1)
346           continue;
347 
348         if (ev.flags & EV_ERROR)
349           ev.fflags = NOTE_REVOKE;
350 
351         if (sub->is_dir && ev.fflags & (NOTE_WRITE | NOTE_EXTEND))
352           {
353             /* If we are monitoring on a non-existent regular file, trigger the
354              * rescan of missing files immediately so we don't have to wait for
355              * 4 seconds for discovering missing files. We pass the sub_file
356              * corresponding to the GKqueueFileMonitor to 'check_this_sub_only'
357              * argument to prevent _km_scan_missing from emitting 'CREATED'
358              * events because _kh_dir_diff will do it for us. */
359             if (sub->mon->sub_file != NULL && sub->mon->sub_file->fd == -1)
360               _km_scan_missing (sub->mon->sub_file);
361 
362             /* If we are monitoring a regular file, don't emit 'DELETED' events
363              * from the directory monitor because it will be emitted from the
364              * file itself when a NOTE_DELETE is reported on sub_file. */
365             _kh_dir_diff (sub, sub->mon->sub_file == NULL);
366 
367 #ifdef NOTE_TRUNCATE
368             ev.fflags &= ~(NOTE_WRITE | NOTE_EXTEND | NOTE_TRUNCATE);
369 #else
370             ev.fflags &= ~(NOTE_WRITE | NOTE_EXTEND);
371 #endif
372           }
373 
374         /* Here starts the long section of mapping kqueue events to
375          * GFileMonitorEvent. Since kqueue can return multiple events in a
376          * single kevent struct, we must use 'if' instead of 'else if'. */
377         if (ev.fflags & NOTE_DELETE)
378           {
379             struct stat st;
380             if (fstat (sub->fd, &st) < 0)
381               st.st_nlink = 0;
382 
383             g_file_monitor_source_handle_event (source,
384                                                 G_FILE_MONITOR_EVENT_DELETED,
385                                                 sub->basename, NULL, NULL, now);
386 
387             /* If the last reference to the file was removed, delete the
388              * subscription from kqueue and add it to the missing list.
389              * If you are monitoring a file which has hard link count higher
390              * than 1, it is possible for the same file to emit 'DELETED'
391              * events multiple times. */
392             if (st.st_nlink == 0)
393               {
394                 _kqsub_cancel (sub);
395                 _km_add_missing (sub);
396               }
397           }
398          if (ev.fflags & NOTE_REVOKE)
399            {
400              g_file_monitor_source_handle_event (source,
401                                                  G_FILE_MONITOR_EVENT_UNMOUNTED,
402                                                  sub->basename, NULL, NULL, now);
403              _kqsub_cancel (sub);
404              _km_add_missing (sub);
405            }
406         if (ev.fflags & NOTE_ATTRIB)
407           {
408             g_file_monitor_source_handle_event (source,
409                                                 G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED,
410                                                 sub->basename, NULL, NULL, now);
411           }
412 #ifdef NOTE_TRUNCATE
413         if (ev.fflags & (NOTE_WRITE | NOTE_EXTEND | NOTE_TRUNCATE))
414 #else
415         if (ev.fflags & (NOTE_WRITE | NOTE_EXTEND))
416 #endif
417           {
418             g_file_monitor_source_handle_event (source,
419                                                 G_FILE_MONITOR_EVENT_CHANGED,
420                                                 sub->basename, NULL, NULL, now);
421           }
422         if (ev.fflags & NOTE_RENAME)
423           {
424             /* Since there’s apparently no way to get the new name of the
425              * file out of kqueue(), all we can do is say that this one has
426              * been deleted. */
427             g_file_monitor_source_handle_event (source,
428                                                 G_FILE_MONITOR_EVENT_DELETED,
429                                                 sub->basename, NULL, NULL, now);
430           }
431 #ifdef NOTE_CLOSE_WRITE
432         if (ev.fflags & NOTE_CLOSE_WRITE)
433           {
434             g_file_monitor_source_handle_event (source,
435                                                 G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT,
436                                                 sub->basename, NULL, NULL, now);
437           }
438 #endif
439 
440         /* Handle the case when a file is created again shortly after it was
441          * deleted. It has to be the last check because 'DELETED' must happen
442          * before 'CREATED'. */
443         if (ev.fflags & (NOTE_DELETE | NOTE_REVOKE))
444           _km_scan_missing (NULL);
445     }
446 
447   G_UNLOCK (kq_lock);
448 
449   return TRUE;
450 }
451 
452 static gboolean
g_kqueue_file_monitor_is_supported(void)453 g_kqueue_file_monitor_is_supported (void)
454 {
455   int errsv;
456 
457   G_LOCK (kq_lock);
458 
459   if (kq_queue == -1)
460     {
461       kq_queue = kqueue ();
462       errsv = errno;
463 
464       if (kq_queue == -1)
465         {
466           g_warning ("Unable to create a kqueue: %s", g_strerror (errsv));
467           G_UNLOCK (kq_lock);
468           return FALSE;
469         }
470 
471       kq_source = g_unix_fd_source_new (kq_queue, G_IO_IN);
472       g_source_set_callback (kq_source, (GSourceFunc) g_kqueue_file_monitor_callback, NULL, NULL);
473       g_source_attach (kq_source, GLIB_PRIVATE_CALL (g_get_worker_context) ());
474     }
475 
476   G_UNLOCK (kq_lock);
477 
478   return TRUE;
479 }
480 
481 static gboolean
g_kqueue_file_monitor_cancel(GFileMonitor * monitor)482 g_kqueue_file_monitor_cancel (GFileMonitor *monitor)
483 {
484   GKqueueFileMonitor *kqueue_monitor = G_KQUEUE_FILE_MONITOR (monitor);
485 
486   /* We must hold the global lock before calling _kqsub_cancel. However, we
487    * cannot call G_LOCK in _kqsub_cancel because it is also used by
488    * g_kqueue_file_monitor_callback, which already holds the lock itself. */
489   G_LOCK (kq_lock);
490 
491   if (kqueue_monitor->sub_dir)
492     {
493       _kqsub_cancel (kqueue_monitor->sub_dir);
494       _kqsub_free (kqueue_monitor->sub_dir);
495       kqueue_monitor->sub_dir = NULL;
496     }
497   if (kqueue_monitor->sub_file)
498     {
499       _kqsub_cancel (kqueue_monitor->sub_file);
500       _kqsub_free (kqueue_monitor->sub_file);
501       kqueue_monitor->sub_file = NULL;
502     }
503 
504   G_UNLOCK (kq_lock);
505 
506 #ifndef O_EVTONLY
507   if (kqueue_monitor->fallback)
508     {
509       g_signal_handlers_disconnect_by_func (kqueue_monitor->fallback, _fallback_callback, kqueue_monitor);
510       g_file_monitor_cancel (kqueue_monitor->fallback);
511     }
512 #endif
513 
514   if (G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel)
515     (*G_FILE_MONITOR_CLASS (g_kqueue_file_monitor_parent_class)->cancel) (monitor);
516 
517   return TRUE;
518 }
519 
520 static kqueue_sub *
_kqsub_new(gchar * filename,gchar * basename,GKqueueFileMonitor * mon,GFileMonitorSource * source)521 _kqsub_new (gchar *filename, gchar *basename, GKqueueFileMonitor *mon, GFileMonitorSource *source)
522 {
523   kqueue_sub *sub;
524 
525   sub = g_slice_new (kqueue_sub);
526   sub->filename = filename;
527   sub->basename = basename;
528   sub->mon = mon;
529   g_source_ref ((GSource *) source);
530   sub->source = source;
531   sub->fd = -1;
532   sub->deps = NULL;
533   sub->is_dir = 0;
534 
535   return sub;
536 }
537 
538 static void
_kqsub_free(kqueue_sub * sub)539 _kqsub_free (kqueue_sub *sub)
540 {
541   g_assert (sub->deps == NULL);
542   g_assert (sub->fd == -1);
543 
544   g_source_unref ((GSource *) sub->source);
545   g_free (sub->filename);
546   g_free (sub->basename);
547   g_slice_free (kqueue_sub, sub);
548 }
549 
550 static void
_kqsub_cancel(kqueue_sub * sub)551 _kqsub_cancel (kqueue_sub *sub)
552 {
553   /* WARNING: Before calling this function, you must hold a lock on kq_lock
554    * or you will cause use-after-free in g_kqueue_file_monitor_callback. */
555 
556   struct kevent ev;
557 
558   /* Remove the event and close the file descriptor to automatically
559    * delete pending events. */
560   if (sub->fd != -1)
561     {
562       EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_DELETE, note_all (), 0, sub);
563       if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1)
564         {
565           g_warning ("Unable to remove event for %s: %s", sub->filename, g_strerror (errno));
566         }
567       close (sub->fd);
568       sub->fd = -1;
569     }
570 
571   _km_remove (sub);
572 
573   if (sub->deps)
574     {
575       dl_free (sub->deps);
576       sub->deps = NULL;
577     }
578 }
579 
580 gboolean
_kqsub_start_watching(kqueue_sub * sub)581 _kqsub_start_watching (kqueue_sub *sub)
582 {
583   struct stat st;
584   struct kevent ev;
585 
586   sub->fd = open (sub->filename, O_KQFLAG);
587   if (sub->fd == -1)
588       return FALSE;
589 
590   if (fstat (sub->fd, &st) == -1)
591     {
592       g_warning ("fstat failed for %s: %s", sub->filename, g_strerror (errno));
593       close (sub->fd);
594       sub->fd = -1;
595       return FALSE;
596     }
597 
598   sub->is_dir = (st.st_mode & S_IFDIR) ? 1 : 0;
599   if (sub->is_dir)
600     {
601       if (sub->deps)
602         dl_free (sub->deps);
603 
604       sub->deps = dl_listing (sub->filename);
605     }
606 
607   EV_SET (&ev, sub->fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, note_all (), 0, sub);
608   if (kevent (kq_queue, &ev, 1, NULL, 0, NULL) == -1)
609     {
610       g_warning ("Unable to add event for %s: %s", sub->filename, g_strerror (errno));
611       close (sub->fd);
612       sub->fd = -1;
613       return FALSE;
614     }
615 
616   return TRUE;
617 }
618