ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Linux-Inotify2/Inotify2.pm
Revision: 1.5
Committed: Tue Aug 23 02:08:09 2005 UTC (18 years, 11 months ago) by root
Branch: MAIN
Changes since 1.4: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Linux::Inotify2 - scalable directory/file change notification
4
5 =head1 SYNOPSIS
6
7 use Linux::Inotify2;
8
9 # create a new object
10 my $inotify = new Linux::Inotify2
11 or die "Unable to create new inotify object: $!";
12
13 # for Event:
14 Event->io (fd =>$inotify->fileno, poll => 'r', cb => sub { $inotify->poll });
15 # for Glib:
16 add_watch Glib::IO $inotify->fileno, in => sub { $inotify->poll };
17 # manually:
18 1 while $inotify->poll;
19
20 # add watchers
21 $inotify->watch ("/etc/passwd", IN_ACCESS, sub {
22 my $e = shift;
23 my $name = $e->fullname;
24 print "$name was accessed\n" if $e->IN_ACCESS;
25 print "$name is no longer mounted\n" if $e->IN_UNMOUNT;
26 print "$name is gone\n" if $e->IN_IGNORED;
27 print "events for $name have been lost\n" if $e->IN_Q_OVERFLOW;
28
29 # cancel this watcheR: remove no further events
30 $e->w->cancel;
31 });
32
33 =head1 DESCRIPTION
34
35 =head2 The Linux::Inotify2 Class
36
37 This module implements an interface to the Linux 2.6.13 and later Inotify
38 file/directory change notification sytem.
39
40 It has a number of advantages over the Linux::Inotify module:
41
42 - it is portable (Linux::Inotify only works on x86)
43 - the equivalent of fullname works correctly
44 - it is better documented
45 - it has callback-style interface, which is better suited for
46 integration.
47
48 =over 4
49
50 =cut
51
52 package Linux::Inotify2;
53
54 use Carp ();
55 use Scalar::Util ();
56
57 use base 'Exporter';
58
59 BEGIN {
60 $VERSION = 0.2;
61
62 @constants = qw(
63 IN_ACCESS IN_MODIFY IN_ATTRIB IN_CLOSE_WRITE
64 IN_CLOSE_NOWRITE IN_OPEN IN_MOVED_FROM IN_MOVED_TO
65 IN_CREATE IN_DELETE IN_DELETE_SELF
66 IN_ALL_EVENTS
67 IN_UNMOUNT IN_Q_OVERFLOW IN_IGNORED
68 IN_CLOSE IN_MOVE
69 IN_ISDIR IN_ONESHOT
70 );
71
72 @EXPORT = @constants;
73
74 require XSLoader;
75 XSLoader::load Linux::Inotify2, $VERSION;
76 }
77
78 =item my $inotify = new Linux::Inotify2
79
80 Create a new notify object and return it. A notify object is kind of a
81 container that stores watches on filesystem names and is responsible for
82 handling event data.
83
84 On error, C<undef> is returned and C<$!> will be set accordingly. The followign errors
85 are documented:
86
87 ENFILE The system limit on the total number of file descriptors has been reached.
88 EMFILE The user limit on the total number of inotify instances has been reached.
89 ENOMEM Insufficient kernel memory is available.
90
91 Example:
92
93 my $inotify = new Linux::Inotify2
94 or die "Unable to create new inotify object: $!";
95
96 =cut
97
98 sub new {
99 my ($class) = @_;
100
101 my $fd = inotify_init;
102
103 return unless $fd >= 0;
104
105 bless { fd => $fd }, $class
106 }
107
108 =item $watch = $inotify->watch ($name, $mask, $cb)
109
110 Add a new watcher to the given notifier. The watcher will create events
111 on the pathname C<$name> as given in C<$mask>, which can be any of the
112 following constants (all exported by default) ORed together.
113
114 "file" refers to any filesystem object in the watch'ed object (always a
115 directory), that is files, directories, symlinks, device nodes etc., while
116 "object" refers to the object the watch has been set on itself:
117
118 IN_ACCESS object was accessed
119 IN_MODIFY object was modified
120 IN_ATTRIB object metadata changed
121 IN_CLOSE_WRITE writable fd to file / to object was closed
122 IN_CLOSE_NOWRITE readonly fd to file / to object closed
123 IN_OPEN object was opened
124 IN_MOVED_FROM file was moved from this object (directory)
125 IN_MOVED_TO file was moved to this object (directory)
126 IN_CREATE file was created in this object (directory)
127 IN_DELETE file was deleted from this object (directory)
128 IN_DELETE_SELF object itself was deleted
129 IN_ALL_EVENTS all of the above events
130
131 IN_ONESHOT only send event once
132
133 IN_CLOSE same as IN_CLOSE_WRITE | IN_CLOSE_NOWRITE
134 IN_MOVE same as IN_MOVED_FROM | IN_MOVED_TO
135
136 C<$cb> is a perl code reference that is called for each event. It receives
137 a C<Linux::Inotify2::Event> object.
138
139 The returned C<$watch> object is of class C<Linux::Inotify2::Watch>.
140
141 On error, C<undef> is returned and C<$!> will be set accordingly. The
142 following errors are documented:
143
144 EBADF The given file descriptor is not valid.
145 EINVAL The given event mask contains no legal events.
146 ENOMEM Insufficient kernel memory was available.
147 ENOSPC The user limit on the total number of inotify watches was reached or the kernel failed to allocate a needed resource.
148 EACCESS Read access to the given file is not permitted.
149
150 Example, show when C</etc/passwd> gets accessed and/or modified once:
151
152 $inotify->watch ("/etc/passwd", IN_ACCESS | IN_MODIFY, sub {
153 my $e = shift;
154 print "$e->{w}{name} was accessed\n" if $e->IN_ACCESS;
155 print "$e->{w}{name} was modified\n" if $e->IN_MODIFY;
156 print "$e->{w}{name} is no longer mounted\n" if $e->IN_UNMOUNT;
157 print "events for $e->{w}{name} have been lost\n" if $e->IN_Q_OVERFLOW;
158
159 $e->w->cancel;
160 });
161
162 =cut
163
164 sub watch {
165 my ($self, $name, $mask, $cb) = @_;
166
167 my $wd = inotify_add_watch $self->{fd}, $name, $mask;
168
169 return unless $wd >= 0;
170
171 my $w = $self->{w}{$wd} = bless {
172 inotify => $self,
173 wd => $wd,
174 name => $name,
175 mask => $mask,
176 cb => $cb,
177 }, Linux::Inotify2::Watch;
178
179 Scalar::Util::weaken $w->{inotify};
180
181 $w
182 }
183
184 =item $inotify->fileno
185
186 Returns the fileno for this notify object. You are responsible for calling
187 the C<poll> method when this fileno becomes ready for reading.
188
189 =cut
190
191 sub fileno {
192 $_[0]{fd}
193 }
194
195 =item $count = $inotify->poll
196
197 Reads events from the kernel and handles them. If the notify fileno is
198 blocking (the default), then this method waits for at least one event
199 (and thus returns true unless an error occurs). Otherwise it returns
200 immediately when no pending events could be read.
201
202 Returns the count of events that have been handled.
203
204 =cut
205
206 sub poll {
207 my ($self) = @_;
208
209 my @ev = inotify_read $self->{fd};
210
211 for (@ev) {
212 my $w = $_->{w} = $self->{w}{$_->{wd}}
213 or next; # no such watcher
214
215 exists $self->{ignore}{$_->{wd}}
216 and next; # watcher has been canceled
217
218 $w->{cb}->(bless $_, Linux::Inotify2::Event);
219 # TODO: what about IN_ONESHOT?
220 $w->cancel if $_->{mask} & (IN_IGNORED | IN_UNMOUNT);
221 }
222
223 delete $self->{ignore};
224
225 scalar @ev
226 }
227
228 sub DESTROY {
229 inotify_close $_[0]{fd}
230 }
231
232 =back
233
234 =head2 The Linux::Inotify2::Event Class
235
236 Objects of this class are handed as first argument to the watch
237 callback. It has the following members and methods:
238
239 =over 4
240
241 =item $event->w
242
243 =item $event->{w}
244
245 The watcher object for this event.
246
247 =item $event->name
248
249 =item $event->{name}
250
251 The path of the filesystem object, relative to the watch name.
252
253 =item $watch->fullname
254
255 Returns the "full" name of the relevant object, i.e. including the C<name>
256 component of the watcher.
257
258 =item $event->mask
259
260 =item $event->{mask}
261
262 The received event mask. In addition the the events described for
263 C<$inotify->watch>, the following flags (exported by default) can be set:
264
265 IN_ISDIR event object is a directory
266
267 IN_Q_OVERFLOW event queue overflowed
268
269 # when the following flags are set, then watchers are canceled automatically
270 IN_UNMOUNT filesystem for watch'ed object was unmounted
271 IN_IGNORED file was ignored/is gone (no more events are delivered)
272
273 =item $event->IN_xxx
274
275 Returns a boolean that returns true if the event mask matches the
276 event. All of the C<IN_xxx> constants can be used as methods.
277
278 =item $event->cookie
279
280 =item $event->{cookie}
281
282 The event cookie, can be used to synchronize two related events.
283
284 =back
285
286 =cut
287
288 package Linux::Inotify2::Event;
289
290 sub w { $_[0]{w} }
291 sub name { $_[0]{name} }
292 sub mask { $_[0]{mask} }
293 sub cookie { $_[0]{cookie} }
294
295 sub fullname {
296 length $_[0]{name}
297 ? "$_[0]{w}{name}/$_[0]{name}"
298 : $_[0]{w}{name};
299 }
300
301 for my $name (@Linux::Inotify2::constants) {
302 my $mask = &{"Linux::Inotify2::$name"};
303
304 *$name = sub { ($_[0]{mask} & $mask) == $mask };
305 }
306
307 =head2 The Linux::Inotify2::Watch Class
308
309 Watch objects are created by calling the C<watch> method of a notifier.
310
311 It has the following members and methods:
312
313 =item $watch->name
314
315 =item $watch->{name}
316
317 The name as specified in the C<watch> call. For the object itself, this is
318 the empty string. For directory watches, this is the name of the entry
319 without leading path elements.
320
321 =item $watch->mask
322
323 =item $watch->{mask}
324
325 The mask as specified in the C<watch> call.
326
327 =item $watch->cb ([new callback])
328
329 =item $watch->{cb}
330
331 The callback as specified in the C<watch> call. Can optionally be changed.
332
333 =item $watch->cancel
334
335 Cancels/removes this watch. Future events, even if already queued queued,
336 will not be handled and resources will be freed.
337
338 =cut
339
340 package Linux::Inotify2::Watch;
341
342 sub name { $_[0]{name} }
343 sub mask { $_[0]{mask} }
344
345 sub cb {
346 $_[0]{cb} = $_[1] if @_ > 1;
347 $_[0]{cb}
348 }
349
350 sub cancel {
351 my ($self) = @_;
352
353 my $inotify = delete $self->{inotify}
354 or return 1; # already canceled
355
356 delete $inotify->{w}{$self->{wd}}; # we are no longer there
357 $inotify->{ignore}{$self->{wd}} = 1; # ignore further events for one poll
358
359 (Linux::Inotify2::inotify_rm_watch $inotify->{fd}, $self->{wd})
360 ? 1 : undef
361 }
362
363 =head1 SEE ALSO
364
365 L<Linux::Inotify>.
366
367 =head1 AUTHOR
368
369 Marc Lehmann <schmorp@schmorp.de>
370 http://home.schmorp.de/
371
372 =cut
373
374 1