swerling-sinotify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ pkg/
2
+ ext/Makefile
3
+ ext/mkmf.log
4
+ ext/*.o
5
+ ext/*.so
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.0.1 / 2009-07-07
2
+
3
+ * Initial release
data/README.rdoc ADDED
@@ -0,0 +1,139 @@
1
+ sinotify
2
+ by Steven Swerling
3
+ http://tab-a.slot-z.net
4
+
5
+ == DESCRIPTION:
6
+
7
+ ALPHA Alert -- just uploaded initial release.
8
+
9
+
10
+ Linux inotify is a means to receive events describing file system activity (create, modify, delete, close, etc).
11
+
12
+ Sinotify was derived from aredridel's package (http://raa.ruby-lang.org/project/ruby-inotify/), with the addition of
13
+ Paul Boon's tweak for making the event_check thread more polite (see
14
+ http://www.mindbucket.com/2009/02/24/ruby-daemons-verifying-good-behavior/)
15
+
16
+ In sinotify, the classes Sinotify::PrimNotifier and Sinotify::PrimEvent provide a low level wrapper to inotify, with
17
+ the ability to establish 'watches' and then listen for inotify events using one of inotify's synchronous event loops,
18
+ and providing access to the events' masks (see 'man inotify' for details). Sinotify::PrimEvent class adds a little semantic sugar
19
+ to the event in to the form of 'etypes', which are just ruby symbols that describe the event mask. If the event has a
20
+ raw mask of (DELETE_SELF & IS_DIR), then the etypes array would be [:delete_self, :is_dir].
21
+
22
+ In addition to the 'straight' wrapper in inotify, sinotify provides an asynchronous implementation of the 'observer
23
+ pattern' for notification. In other words, Sinotify::Notifier listens in the background for inotify events, adapting
24
+ them into instances of Sinotify::Event as they come in and immediately placing them in a concurrent queue, from which
25
+ they are 'announced' to 'subscribers' of the event. [Sinotify uses the 'cosell' implementation of the Announcements
26
+ event notification framework, hence the terminology 'subscribe' and 'announce' rather then 'listen' and 'trigger' used
27
+ in the standard event observer pattern. See the 'cosell' package on github for details.]
28
+
29
+ A variety of 'knobs' are provided for controlling the behavior of the notifier: whether a watch should apply to a
30
+ single directory or should recurse into subdirectores, how fast it should broadcast queued events, etc (see
31
+ Sinotify::Notifier, and the example in the synopsis section below). An event 'spy' can also be setup to log all
32
+ Sinotify::PrimEvents and Sinotify::Events.
33
+
34
+ Sinotify::Event simplifies inotify's muddled event model, sending events only for those files/directories that have
35
+ changed. That's not to say you can't setup a notifier that recurses into subdirectories, just that any individual
36
+ event will apply to a single file, and not to its children. Also, event types are identified using words (in the form
37
+ of ruby :symbols) instead of inotify's event masks. See Sinotify::Event for more explanation.
38
+
39
+ The README for inotify:
40
+
41
+ http://www.kernel.org/pub/linux/kernel/people/rml/inotify/README
42
+
43
+ Selected quotes from the README for inotify:
44
+
45
+ * "Rumor is that the 'd' in 'dnotify' does not stand for 'directory' but for 'suck.'"
46
+
47
+ * "The 'i' in inotify does not stand for 'suck' but for 'inode' -- the logical
48
+ choice since inotify is inode-based."
49
+
50
+ (The 's' in 'sinotify' does in fact stand for 'suck.')
51
+
52
+
53
+ == FEATURES/PROBLEMS:
54
+
55
+ * None known. But it's still early.
56
+
57
+ == SYNOPSIS:
58
+
59
+ Try this:
60
+
61
+ $ mkdir /tmp/sinotify_test
62
+ $ irb
63
+ require 'sinotify'
64
+ notifier = Sinotify::Notifier.new('/tmp/sinotify_test', :recurse => true, :etypes => [:create, :modify, :delete])
65
+ notifier.spy!(:logger => Logger.new('/tmp/inotify_spy.log')) # optional event spy
66
+ notifier.when_announcing(Sinotify::Event) do |sinotify_event|
67
+ puts "Event happened at #{sinotify_event.timestamp} on #{sinotify_event.path}, etypes => #{sinotify_event.etypes.inspect}"
68
+ end
69
+ notifier.when_announcing(Sinotify::Event) do |sinotify_event|
70
+ puts " --> demonstrate that multiple subscribers can be setup: #{sinotify_event.etypes.inspect}"
71
+ end
72
+ notifier.watch! # don't forget to start the watch
73
+
74
+ Then in another linux console:
75
+
76
+ $ touch /tmp/sinotify_test/hi && sleep 1 && echo 'hello' >> /tmp/sinotify_test/hi && sleep 1 && rm -r /tmp/sinotify_test
77
+
78
+ Back in irb you will see:
79
+
80
+ Event happened at Sat Jul 11 12:29:18 -0400 2009 on /tmp/sinotify_test/hi, etypes => [:create]
81
+ --> demonstrate that multiple subscribers can be setup: [:create]
82
+ Event happened at Sat Jul 11 12:29:19 -0400 2009 on /tmp/sinotify_test/hi, etypes => [:modify]
83
+ --> demonstrate that multiple subscribers can be setup: [:modify]
84
+ Event happened at Sat Jul 11 12:29:20 -0400 2009 on /tmp/sinotify_test/hi, etypes => [:delete]
85
+ --> demonstrate that multiple subscribers can be setup: [:delete]
86
+ Event happened at Sat Jul 11 12:29:20 -0400 2009 on /tmp/sinotify_test, etypes => [:delete]
87
+ --> demonstrate that multiple subscribers can be setup: [:delete]
88
+
89
+
90
+ tail -n 50 -f /tmp/inotify_spy.log:
91
+
92
+ ...
93
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => 'hi', :etypes => [:create], :mask => 100 ...
94
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test/hi', dir? => false, :etypes => ...
95
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => 'hi', :etypes => [:modify], :mask => 2 ...
96
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test/hi', dir? => false, :etypes => ...
97
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => 'hi', :etypes => [:delete], :mask => 200 ...
98
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test/hi', dir? => false, :etypes => ...
99
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => '', :etypes => [:delete_self], :mask => 400 ...
100
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test', dir? => true, :etypes => [:delete]...
101
+ etc.
102
+
103
+
104
+
105
+ == REQUIREMENTS:
106
+
107
+ * linux inotify dev libs
108
+ * cosell announcements framework gem
109
+
110
+ == INSTALL:
111
+
112
+ * Todo: install instruction
113
+ * sudo gem install cosell...
114
+ * sudo gem install sinotify...
115
+
116
+ == LICENSE:
117
+
118
+ (The MIT License)
119
+
120
+ Copyright (c) 2008 FIXME (different license?)
121
+
122
+ Permission is hereby granted, free of charge, to any person obtaining
123
+ a copy of this software and associated documentation files (the
124
+ 'Software'), to deal in the Software without restriction, including
125
+ without limitation the rights to use, copy, modify, merge, publish,
126
+ distribute, sublicense, and/or sell copies of the Software, and to
127
+ permit persons to whom the Software is furnished to do so, subject to
128
+ the following conditions:
129
+
130
+ The above copyright notice and this permission notice shall be
131
+ included in all copies or substantial portions of the Software.
132
+
133
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
134
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
135
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
136
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
137
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
138
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
139
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.txt ADDED
@@ -0,0 +1,139 @@
1
+ sinotify
2
+ by Steven Swerling
3
+ http://tab-a.slot-z.net
4
+
5
+ == DESCRIPTION:
6
+
7
+ ALPHA Alert -- just uploaded initial release.
8
+
9
+
10
+ Linux inotify is a means to receive events describing file system activity (create, modify, delete, close, etc).
11
+
12
+ Sinotify was derived from aredridel's package (http://raa.ruby-lang.org/project/ruby-inotify/), with the addition of
13
+ Paul Boon's tweak for making the event_check thread more polite (see
14
+ http://www.mindbucket.com/2009/02/24/ruby-daemons-verifying-good-behavior/)
15
+
16
+ In sinotify, the classes Sinotify::PrimNotifier and Sinotify::PrimEvent provide a low level wrapper to inotify, with
17
+ the ability to establish 'watches' and then listen for inotify events using one of inotify's synchronous event loops,
18
+ and providing access to the events' masks (see 'man inotify' for details). Sinotify::PrimEvent class adds a little semantic sugar
19
+ to the event in to the form of 'etypes', which are just ruby symbols that describe the event mask. If the event has a
20
+ raw mask of (DELETE_SELF & IS_DIR), then the etypes array would be [:delete_self, :is_dir].
21
+
22
+ In addition to the 'straight' wrapper in inotify, sinotify provides an asynchronous implementation of the 'observer
23
+ pattern' for notification. In other words, Sinotify::Notifier listens in the background for inotify events, adapting
24
+ them into instances of Sinotify::Event as they come in and immediately placing them in a concurrent queue, from which
25
+ they are 'announced' to 'subscribers' of the event. [Sinotify uses the 'cosell' implementation of the Announcements
26
+ event notification framework, hence the terminology 'subscribe' and 'announce' rather then 'listen' and 'trigger' used
27
+ in the standard event observer pattern. See the 'cosell' package on github for details.]
28
+
29
+ A variety of 'knobs' are provided for controlling the behavior of the notifier: whether a watch should apply to a
30
+ single directory or should recurse into subdirectores, how fast it should broadcast queued events, etc (see
31
+ Sinotify::Notifier, and the example in the synopsis section below). An event 'spy' can also be setup to log all
32
+ Sinotify::PrimEvents and Sinotify::Events.
33
+
34
+ Sinotify::Event simplifies inotify's muddled event model, sending events only for those files/directories that have
35
+ changed. That's not to say you can't setup a notifier that recurses into subdirectories, just that any individual
36
+ event will apply to a single file, and not to its children. Also, event types are identified using words (in the form
37
+ of ruby :symbols) instead of inotify's event masks. See Sinotify::Event for more explanation.
38
+
39
+ The README for inotify:
40
+
41
+ http://www.kernel.org/pub/linux/kernel/people/rml/inotify/README
42
+
43
+ Selected quotes from the README for inotify:
44
+
45
+ * "Rumor is that the 'd' in 'dnotify' does not stand for 'directory' but for 'suck.'"
46
+
47
+ * "The 'i' in inotify does not stand for 'suck' but for 'inode' -- the logical
48
+ choice since inotify is inode-based."
49
+
50
+ (The 's' in 'sinotify' does in fact stand for 'suck.')
51
+
52
+
53
+ == FEATURES/PROBLEMS:
54
+
55
+ * None known. But it's still early.
56
+
57
+ == SYNOPSIS:
58
+
59
+ Try this:
60
+
61
+ $ mkdir /tmp/sinotify_test
62
+ $ irb
63
+ require 'sinotify'
64
+ notifier = Sinotify::Notifier.new('/tmp/sinotify_test', :recurse => true, :etypes => [:create, :modify, :delete])
65
+ notifier.spy!(:logger => Logger.new('/tmp/inotify_spy.log')) # optional event spy
66
+ notifier.when_announcing(Sinotify::Event) do |sinotify_event|
67
+ puts "Event happened at #{sinotify_event.timestamp} on #{sinotify_event.path}, etypes => #{sinotify_event.etypes.inspect}"
68
+ end
69
+ notifier.when_announcing(Sinotify::Event) do |sinotify_event|
70
+ puts " --> demonstrate that multiple subscribers can be setup: #{sinotify_event.etypes.inspect}"
71
+ end
72
+ notifier.watch! # don't forget to start the watch
73
+
74
+ Then in another linux console:
75
+
76
+ $ touch /tmp/sinotify_test/hi && sleep 1 && echo 'hello' >> /tmp/sinotify_test/hi && sleep 1 && rm -r /tmp/sinotify_test
77
+
78
+ Back in irb you will see:
79
+
80
+ Event happened at Sat Jul 11 12:29:18 -0400 2009 on /tmp/sinotify_test/hi, etypes => [:create]
81
+ --> demonstrate that multiple subscribers can be setup: [:create]
82
+ Event happened at Sat Jul 11 12:29:19 -0400 2009 on /tmp/sinotify_test/hi, etypes => [:modify]
83
+ --> demonstrate that multiple subscribers can be setup: [:modify]
84
+ Event happened at Sat Jul 11 12:29:20 -0400 2009 on /tmp/sinotify_test/hi, etypes => [:delete]
85
+ --> demonstrate that multiple subscribers can be setup: [:delete]
86
+ Event happened at Sat Jul 11 12:29:20 -0400 2009 on /tmp/sinotify_test, etypes => [:delete]
87
+ --> demonstrate that multiple subscribers can be setup: [:delete]
88
+
89
+
90
+ tail -n 50 -f /tmp/inotify_spy.log:
91
+
92
+ ...
93
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => 'hi', :etypes => [:create], :mask => 100 ...
94
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test/hi', dir? => false, :etypes => ...
95
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => 'hi', :etypes => [:modify], :mask => 2 ...
96
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test/hi', dir? => false, :etypes => ...
97
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => 'hi', :etypes => [:delete], :mask => 200 ...
98
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test/hi', dir? => false, :etypes => ...
99
+ ... INFO -- : Sinotify::Notifier Prim Event Spy: <Sinotify::PrimEvent :name => '', :etypes => [:delete_self], :mask => 400 ...
100
+ ... INFO -- : Sinotify::Notifier Event Spy <Sinotify::Event :path => '/tmp/sinotify_test', dir? => true, :etypes => [:delete]...
101
+ etc.
102
+
103
+
104
+
105
+ == REQUIREMENTS:
106
+
107
+ * linux inotify dev libs
108
+ * cosell announcements framework gem
109
+
110
+ == INSTALL:
111
+
112
+ * Todo: install instruction
113
+ * sudo gem install cosell...
114
+ * sudo gem install sinotify...
115
+
116
+ == LICENSE:
117
+
118
+ (The MIT License)
119
+
120
+ Copyright (c) 2008 FIXME (different license?)
121
+
122
+ Permission is hereby granted, free of charge, to any person obtaining
123
+ a copy of this software and associated documentation files (the
124
+ 'Software'), to deal in the Software without restriction, including
125
+ without limitation the rights to use, copy, modify, merge, publish,
126
+ distribute, sublicense, and/or sell copies of the Software, and to
127
+ permit persons to whom the Software is furnished to do so, subject to
128
+ the following conditions:
129
+
130
+ The above copyright notice and this permission notice shall be
131
+ included in all copies or substantial portions of the Software.
132
+
133
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
134
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
135
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
136
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
137
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
138
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
139
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ begin
6
+ require 'bones'
7
+ Bones.setup
8
+ rescue LoadError
9
+ begin
10
+ load 'tasks/setup.rb'
11
+ rescue LoadError
12
+ raise RuntimeError, '### please install the "bones" gem ###'
13
+ end
14
+ end
15
+
16
+ #ensure_in_path 'lib'
17
+
18
+ require File.join(File.dirname(__FILE__), 'lib/sinotify_info')
19
+
20
+ # bones gem settings
21
+ PROJ.name = 'sinotify'
22
+ PROJ.authors = 'Steven Swerling'
23
+ PROJ.email = 'sswerling@yahoo.com'
24
+ PROJ.url = 'http://tab-a.slot-z.net'
25
+ PROJ.version = Sinotify::VERSION
26
+ PROJ.rubyforge.name = 'sinotify'
27
+ PROJ.gem.extentions = FileList['ext/**/extconf.rb']
28
+ PROJ.gem.dependencies = ['cosell']
29
+ PROJ.spec.opts << '--color'
30
+ PROJ.rdoc.opts = ["--inline-source"]
31
+ PROJ.rdoc.exclude = ["^tasks/setup\.rb$", "\.[ch]$"]
32
+
33
+ task :default => 'spec:run'
34
+ task :myclobber => [:clobber] do
35
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'pkg')}"
36
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'doc')}"
37
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.log')}"
38
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.o')}"
39
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.so')}"
40
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/Makefile')}"
41
+ end
42
+ task :mypackage => [:myclobber] do
43
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'pkg')}"
44
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'doc')}"
45
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.log')}"
46
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.o')}"
47
+ sh "rm -rf #{File.join(File.dirname(__FILE__), 'ext/*.so')}"
48
+ Rake::Task['gem:package'].invoke
49
+ end
50
+
@@ -0,0 +1,30 @@
1
+ #!usr/bin/ruby
2
+
3
+ require 'sinotify'
4
+ require 'find'
5
+
6
+ i = Inotify.new
7
+
8
+ t = Thread.new do
9
+ i.each_event do |ev|
10
+ p ev.name
11
+ p ev.mask
12
+ end
13
+ end
14
+
15
+ raise("Specify a directory") if !ARGV[0]
16
+
17
+ Find.find(ARGV[0]) do |e|
18
+ if ['.svn', 'CVS', 'RCS'].include? File.basename(e) or !File.directory? e
19
+ Find.prune
20
+ else
21
+ begin
22
+ puts "Adding #{e}"
23
+ i.add_watch(e, Inotify::CREATE | Inotify::DELETE | Inotify::MOVE | Inotify::MODIFY)
24
+ rescue
25
+ puts "Skipping #{e}: #{$!}"
26
+ end
27
+ end
28
+ end
29
+
30
+ t.join
data/ext/extconf.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'mkmf'
2
+
3
+ dir = File.join(File.dirname(__FILE__))
4
+
5
+ if RUBY_VERSION =~ /1.9/ then
6
+ $CPPFLAGS += " -DRUBY_19"
7
+ end
8
+
9
+ have_header('linux/inotify.h')
10
+ # this was in the original inotify, but I don't know what it is for:
11
+ # have_header("version.h")
12
+ create_makefile('sinotify', 'src')
@@ -0,0 +1,24 @@
1
+ #ifndef _LINUX_INOTIFY_SYSCALLS_H
2
+ #define _LINUX_INOTIFY_SYSCALLS_H
3
+
4
+ #if defined(__i386__)
5
+ # define __NR_inotify_init 291
6
+ # define __NR_inotify_add_watch 292
7
+ # define __NR_inotify_rm_watch 293
8
+ #elif defined(__x86_64__)
9
+ # define __NR_inotify_init 253
10
+ # define __NR_inotify_add_watch 254
11
+ # define __NR_inotify_rm_watch 255
12
+ #elif defined(__ppc__)
13
+ # define __NR_inotify_init 275
14
+ # define __NR_inotify_add_watch 276
15
+ # define __NR_inotify_rm_watch 277
16
+ #elif defined (__ia64__)
17
+ # define __NR_inotify_init 1277
18
+ # define __NR_inotify_add_watch 1278
19
+ # define __NR_inotify_rm_watch 1279
20
+ #else
21
+ # error "Unsupported architecture!"
22
+ #endif
23
+
24
+ #endif /* _LINUX_INOTIFY_SYSCALLS_H */
data/ext/src/inotify.h ADDED
@@ -0,0 +1,113 @@
1
+ /*
2
+ * Inode based directory notification for Linux
3
+ *
4
+ * Copyright (C) 2005 John McCutchan
5
+ */
6
+
7
+ #ifndef _LINUX_INOTIFY_H
8
+ #define _LINUX_INOTIFY_H
9
+
10
+ #include <linux/types.h>
11
+
12
+ /*
13
+ * struct inotify_event - structure read from the inotify device for each event
14
+ *
15
+ * When you are watching a directory, you will receive the filename for events
16
+ * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
17
+ */
18
+ struct inotify_event {
19
+ __s32 wd; /* watch descriptor */
20
+ __u32 mask; /* watch mask */
21
+ __u32 cookie; /* cookie to synchronize two events */
22
+ __u32 len; /* length (including nulls) of name */
23
+ char name[0]; /* stub for possible name */
24
+ };
25
+
26
+ /* the following are legal, implemented events that user-space can watch for */
27
+ #define IN_ACCESS 0x00000001 /* File was accessed */
28
+ #define IN_MODIFY 0x00000002 /* File was modified */
29
+ #define IN_ATTRIB 0x00000004 /* Metadata changed */
30
+ #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
31
+ #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
32
+ #define IN_OPEN 0x00000020 /* File was opened */
33
+ #define IN_MOVED_FROM 0x00000040 /* File was moved from X */
34
+ #define IN_MOVED_TO 0x00000080 /* File was moved to Y */
35
+ #define IN_CREATE 0x00000100 /* Subfile was created */
36
+ #define IN_DELETE 0x00000200 /* Subfile was deleted */
37
+ #define IN_DELETE_SELF 0x00000400 /* Self was deleted */
38
+ #define IN_MOVE_SELF 0x00000800 /* Self was moved */
39
+
40
+ /* the following are legal events. they are sent as needed to any watch */
41
+ #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
42
+ #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
43
+ #define IN_IGNORED 0x00008000 /* File was ignored */
44
+
45
+ /* helper events */
46
+ #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
47
+ #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
48
+
49
+ /* special flags */
50
+ #define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */
51
+ #define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */
52
+ #define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */
53
+ #define IN_ISDIR 0x40000000 /* event occurred against dir */
54
+ #define IN_ONESHOT 0x80000000 /* only send event once */
55
+
56
+ /*
57
+ * All of the events - we build the list by hand so that we can add flags in
58
+ * the future and not break backward compatibility. Apps will get only the
59
+ * events that they originally wanted. Be sure to add new events here!
60
+ */
61
+ #define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
62
+ IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
63
+ IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \
64
+ IN_MOVE_SELF)
65
+
66
+ #ifdef __KERNEL__
67
+
68
+ #include <linux/dcache.h>
69
+ #include <linux/fs.h>
70
+ #include <linux/config.h>
71
+
72
+ #ifdef CONFIG_INOTIFY
73
+
74
+ extern void inotify_inode_queue_event(struct inode *, __u32, __u32,
75
+ const char *);
76
+ extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32,
77
+ const char *);
78
+ extern void inotify_unmount_inodes(struct list_head *);
79
+ extern void inotify_inode_is_dead(struct inode *);
80
+ extern u32 inotify_get_cookie(void);
81
+
82
+ #else
83
+
84
+ static inline void inotify_inode_queue_event(struct inode *inode,
85
+ __u32 mask, __u32 cookie,
86
+ const char *filename)
87
+ {
88
+ }
89
+
90
+ static inline void inotify_dentry_parent_queue_event(struct dentry *dentry,
91
+ __u32 mask, __u32 cookie,
92
+ const char *filename)
93
+ {
94
+ }
95
+
96
+ static inline void inotify_unmount_inodes(struct list_head *list)
97
+ {
98
+ }
99
+
100
+ static inline void inotify_inode_is_dead(struct inode *inode)
101
+ {
102
+ }
103
+
104
+ static inline u32 inotify_get_cookie(void)
105
+ {
106
+ return 0;
107
+ }
108
+
109
+ #endif /* CONFIG_INOTIFY */
110
+
111
+ #endif /* __KERNEL __ */
112
+
113
+ #endif /* _LINUX_INOTIFY_H */