Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / FileSystemQueryable / InotifyBackend.cs
bloba657196a99231ae13f9dfd83aa400fde2155057d
1 //
2 // InotifyEventBackend.cs
3 //
4 // Copyright (C) 2005 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.IO;
31 using Beagle.Util;
32 using Beagle.Daemon;
34 namespace Beagle.Daemon.FileSystemQueryable {
36 public class InotifyBackend : IFileEventBackend {
38 FileSystemQueryable queryable;
40 public object CreateWatch (string path)
42 object watch = null;
43 try {
44 watch = Inotify.Subscribe (path, OnInotifyEvent,
45 Inotify.EventType.Create
46 | Inotify.EventType.Delete
47 | Inotify.EventType.CloseWrite
48 | Inotify.EventType.MovedFrom
49 | Inotify.EventType.MovedTo);
52 catch (IOException) {
53 // We can race and files can disappear. No big deal.
55 return watch;
58 public bool ForgetWatch (object watch_handle)
60 try {
61 ((Inotify.Watch) watch_handle).Unsubscribe ();
62 } catch (Exception ex) {
63 Logger.Log.Error ("Caught exception while doing ForgetWatch");
64 Logger.Log.Error (ex);
65 return false;
67 return true;
70 public void Start (FileSystemQueryable queryable)
72 this.queryable = queryable;
75 private void OnInotifyEvent (Inotify.Watch watch,
76 string path,
77 string subitem,
78 string srcpath,
79 Inotify.EventType type)
81 bool is_directory;
82 is_directory = (type & Inotify.EventType.IsDirectory) != 0;
84 queryable.ReportEventInDirectory (path);
86 // The case of matched move events
87 if ((type & Inotify.EventType.MovedTo) != 0 && srcpath != null) {
88 queryable.HandleMoveEvent (Path.GetDirectoryName (srcpath),
89 Path.GetFileName (srcpath),
90 path, subitem, is_directory);
91 return;
94 // Then this must be an unmatched moveto
95 // An unmatched MovedTo is like a create
96 if ((type & Inotify.EventType.MovedTo) != 0) {
98 // Synthesize the appropriate Create event. Note that we could check for the
99 // IsDirectory event here, but this also shrinks the race window.
100 if (is_directory)
101 type |= Inotify.EventType.Create;
102 else
103 type |= Inotify.EventType.CloseWrite;
104 Logger.Log.Debug ("Synthesizing event on unpaired MoveTo", type);
107 // An unmatched MovedFrom is like a delete
108 if ((type & Inotify.EventType.MovedFrom) != 0) {
109 type |= Inotify.EventType.Delete;
110 Logger.Log.Debug ("Synthesizing event on unpaired MoveFrom", type);
113 if ((type & Inotify.EventType.Delete) != 0) {
114 queryable.HandleRemoveEvent (path, subitem, is_directory);
115 return;
118 if ((type & Inotify.EventType.Create) != 0) {
119 if (is_directory)
120 queryable.HandleAddEvent (path, subitem, is_directory);
121 return;
124 if ((type & Inotify.EventType.CloseWrite) != 0) {
125 queryable.HandleAddEvent (path, subitem, is_directory);
126 return;
129 if ((type & Inotify.EventType.QueueOverflow) != 0) {
130 Logger.Log.Warn ("Inotify queue overflowed: file system is in an unknown state");
131 queryable.HandleOverflowEvent ();
132 return;