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 "ginotifyfilemonitor.h" 29 #include <gio/giomodule.h> 30 31 #define USE_INOTIFY 1 32 #include "inotify-helper.h" 33 34 #include "gioalias.h" 35 36 struct _GInotifyFileMonitor 37 { 38 GLocalFileMonitor parent_instance; 39 gchar *filename; 40 gchar *dirname; 41 inotify_sub *sub; 42 }; 43 44 static gboolean g_inotify_file_monitor_cancel (GFileMonitor* monitor); 45 46 #define g_inotify_file_monitor_get_type _g_inotify_file_monitor_get_type 47 G_DEFINE_TYPE_WITH_CODE (GInotifyFileMonitor, g_inotify_file_monitor, G_TYPE_LOCAL_FILE_MONITOR, 48 g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME, 49 g_define_type_id, 50 "inotify", 51 20)) 52 53 static void 54 g_inotify_file_monitor_finalize (GObject *object) 55 { 56 GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (object); 57 inotify_sub *sub = inotify_monitor->sub; 58 59 if (sub) 60 { 61 _ih_sub_cancel (sub); 62 _ih_sub_free (sub); 63 inotify_monitor->sub = NULL; 64 } 65 66 if (inotify_monitor->filename) 67 { 68 g_free (inotify_monitor->filename); 69 inotify_monitor->filename = NULL; 70 } 71 72 if (inotify_monitor->dirname) 73 { 74 g_free (inotify_monitor->dirname); 75 inotify_monitor->dirname = NULL; 76 } 77 78 if (G_OBJECT_CLASS (g_inotify_file_monitor_parent_class)->finalize) 79 (*G_OBJECT_CLASS (g_inotify_file_monitor_parent_class)->finalize) (object); 80 } 81 82 static GObject * 83 g_inotify_file_monitor_constructor (GType type, 84 guint n_construct_properties, 85 GObjectConstructParam *construct_properties) 86 { 87 GObject *obj; 88 GInotifyFileMonitorClass *klass; 89 GObjectClass *parent_class; 90 GInotifyFileMonitor *inotify_monitor; 91 const gchar *filename = NULL; 92 inotify_sub *sub = NULL; 93 94 klass = G_INOTIFY_FILE_MONITOR_CLASS (g_type_class_peek (G_TYPE_INOTIFY_FILE_MONITOR)); 95 parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); 96 obj = parent_class->constructor (type, 97 n_construct_properties, 98 construct_properties); 99 100 inotify_monitor = G_INOTIFY_FILE_MONITOR (obj); 101 102 filename = G_LOCAL_FILE_MONITOR (obj)->filename; 103 104 g_assert (filename != NULL); 105 106 inotify_monitor->filename = g_path_get_basename (filename); 107 inotify_monitor->dirname = g_path_get_dirname (filename); 108 109 /* Will never fail as is_supported() should be called before instanciating 110 * anyway */ 111 g_assert (_ih_startup ()); 112 113 sub = _ih_sub_new (inotify_monitor->dirname, inotify_monitor->filename, inotify_monitor); 114 115 /* FIXME: what to do about errors here? we can't return NULL or another 116 * kind of error and an assertion is probably too hard */ 117 g_assert (sub != NULL); 118 g_assert (_ih_sub_add (sub)); 119 120 inotify_monitor->sub = sub; 121 122 return obj; 123 } 124 125 static gboolean 126 g_inotify_file_monitor_is_supported (void) 127 { 128 return _ih_startup (); 129 } 130 131 static void 132 g_inotify_file_monitor_class_init (GInotifyFileMonitorClass* klass) 133 { 134 GObjectClass* gobject_class = G_OBJECT_CLASS (klass); 135 GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass); 136 GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass); 137 138 gobject_class->finalize = g_inotify_file_monitor_finalize; 139 gobject_class->constructor = g_inotify_file_monitor_constructor; 140 file_monitor_class->cancel = g_inotify_file_monitor_cancel; 141 142 local_file_monitor_class->is_supported = g_inotify_file_monitor_is_supported; 143 } 144 145 static void 146 g_inotify_file_monitor_init (GInotifyFileMonitor* monitor) 147 { 148 } 149 150 static gboolean 151 g_inotify_file_monitor_cancel (GFileMonitor* monitor) 152 { 153 GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (monitor); 154 inotify_sub *sub = inotify_monitor->sub; 155 156 if (sub) 157 { 158 _ih_sub_cancel (sub); 159 _ih_sub_free (sub); 160 inotify_monitor->sub = NULL; 161 } 162 163 if (G_FILE_MONITOR_CLASS (g_inotify_file_monitor_parent_class)->cancel) 164 (*G_FILE_MONITOR_CLASS (g_inotify_file_monitor_parent_class)->cancel) (monitor); 165 166 return TRUE; 167 } 168 169