1 /* GIO - GLib Input, Output and Streaming Library 2 * 3 * Copyright (C) 2006-2007 Red Hat, Inc. 4 * Copyright (C) 2007 Sebastian Drge. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General 17 * Public License along with this library; if not, write to the 18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 19 * Boston, MA 02111-1307, USA. 20 * 21 * Authors: Alexander Larsson <alexl (at) redhat.com> 22 * John McCutchan <john (at) johnmccutchan.com> 23 * Sebastian Drge <slomo (at) circular-chaos.org> 24 */ 25 26 #include "config.h" 27 28 #include "ginotifydirectorymonitor.h" 29 #include "giomodule.h" 30 31 #define USE_INOTIFY 1 32 #include "inotify-helper.h" 33 34 #include "gioalias.h" 35 36 struct _GInotifyDirectoryMonitor 37 { 38 GLocalDirectoryMonitor parent_instance; 39 inotify_sub *sub; 40 }; 41 42 static gboolean g_inotify_directory_monitor_cancel (GFileMonitor* monitor); 43 44 #define g_inotify_directory_monitor_get_type _g_inotify_directory_monitor_get_type 45 G_DEFINE_TYPE_WITH_CODE (GInotifyDirectoryMonitor, g_inotify_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR, 46 g_io_extension_point_implement (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME, 47 g_define_type_id, 48 "inotify", 49 20)) 50 51 static void 52 g_inotify_directory_monitor_finalize (GObject *object) 53 { 54 GInotifyDirectoryMonitor *inotify_monitor = G_INOTIFY_DIRECTORY_MONITOR (object); 55 inotify_sub *sub = inotify_monitor->sub; 56 57 if (sub) 58 { 59 _ih_sub_cancel (sub); 60 _ih_sub_free (sub); 61 inotify_monitor->sub = NULL; 62 } 63 64 if (G_OBJECT_CLASS (g_inotify_directory_monitor_parent_class)->finalize) 65 (*G_OBJECT_CLASS (g_inotify_directory_monitor_parent_class)->finalize) (object); 66 } 67 68 static GObject * 69 g_inotify_directory_monitor_constructor (GType type, 70 guint n_construct_properties, 71 GObjectConstructParam *construct_properties) 72 { 73 GObject *obj; 74 GInotifyDirectoryMonitorClass *klass; 75 GObjectClass *parent_class; 76 GInotifyDirectoryMonitor *inotify_monitor; 77 const gchar *dirname = NULL; 78 inotify_sub *sub = NULL; 79 80 klass = G_INOTIFY_DIRECTORY_MONITOR_CLASS (g_type_class_peek (G_TYPE_INOTIFY_DIRECTORY_MONITOR)); 81 parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); 82 obj = parent_class->constructor (type, 83 n_construct_properties, 84 construct_properties); 85 86 inotify_monitor = G_INOTIFY_DIRECTORY_MONITOR (obj); 87 88 dirname = G_LOCAL_DIRECTORY_MONITOR (obj)->dirname; 89 g_assert (dirname != NULL); 90 91 /* Will never fail as is_supported() should be called before instanciating 92 * anyway */ 93 g_assert (_ih_startup ()); 94 95 sub = _ih_sub_new (dirname, NULL, inotify_monitor); 96 /* FIXME: what to do about errors here? we can't return NULL or another 97 * kind of error and an assertion is probably too hard */ 98 g_assert (sub != NULL); 99 g_assert (_ih_sub_add (sub)); 100 101 inotify_monitor->sub = sub; 102 103 return obj; 104 } 105 106 static gboolean 107 g_inotify_directory_monitor_is_supported (void) 108 { 109 return _ih_startup (); 110 } 111 112 static void 113 g_inotify_directory_monitor_class_init (GInotifyDirectoryMonitorClass* klass) 114 { 115 GObjectClass* gobject_class = G_OBJECT_CLASS (klass); 116 GFileMonitorClass *directory_monitor_class = G_FILE_MONITOR_CLASS (klass); 117 GLocalDirectoryMonitorClass *local_directory_monitor_class = G_LOCAL_DIRECTORY_MONITOR_CLASS (klass); 118 119 gobject_class->finalize = g_inotify_directory_monitor_finalize; 120 gobject_class->constructor = g_inotify_directory_monitor_constructor; 121 directory_monitor_class->cancel = g_inotify_directory_monitor_cancel; 122 123 local_directory_monitor_class->mount_notify = TRUE; 124 local_directory_monitor_class->is_supported = g_inotify_directory_monitor_is_supported; 125 } 126 127 static void 128 g_inotify_directory_monitor_init (GInotifyDirectoryMonitor* monitor) 129 { 130 } 131 132 static gboolean 133 g_inotify_directory_monitor_cancel (GFileMonitor* monitor) 134 { 135 GInotifyDirectoryMonitor *inotify_monitor = G_INOTIFY_DIRECTORY_MONITOR (monitor); 136 inotify_sub *sub = inotify_monitor->sub; 137 138 if (sub) 139 { 140 _ih_sub_cancel (sub); 141 _ih_sub_free (sub); 142 inotify_monitor->sub = NULL; 143 } 144 145 if (G_FILE_MONITOR_CLASS (g_inotify_directory_monitor_parent_class)->cancel) 146 (*G_FILE_MONITOR_CLASS (g_inotify_directory_monitor_parent_class)->cancel) (monitor); 147 148 return TRUE; 149 } 150 151