ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Linux-Inotify2/Inotify2.pm
Revision: 1.4
Committed: Tue Aug 23 01:57:32 2005 UTC (18 years, 11 months ago) by root
Branch: MAIN
Changes since 1.3: +83 -32 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 $w->cancel if $_->{mask} & (IN_IGNORED | IN_UNMOUNT);
220 }
221
222 delete $self->{ignore};
223
224 scalar @ev
225 }
226
227 sub DESTROY {
228 inotify_close $_[0]{fd}
229 }
230
231 =back
232
233 =head2 The Linux::Inotify2::Event Class
234
235 Objects of this class are handed as first argument to the watch
236 callback. It has the following members and methods:
237
238 =over 4
239
240 =item $event->w
241
242 =item $event->{w}
243
244 The watcher object for this event.
245
246 =item $event->name
247
248 =item $event->{name}
249
250 The path of the filesystem object, relative to the watch name.
251
252 =item $watch->fullname
253
254 Returns the "full" name of the relevant object, i.e. including the C<name>
255 component of the watcher.
256
257 =item $event->mask
258
259 =item $event->{mask}
260
261 The received event mask. In addition the the events described for
262 C<$inotify->watch>, the following flags (exported by default) can be set:
263
264 IN_ISDIR event object is a directory
265
266 IN_Q_OVERFLOW event queue overflowed
267
268 # when the following flags are set, then watchers are canceled automatically
269 IN_UNMOUNT filesystem for watch'ed object was unmounted
270 IN_IGNORED file was ignored/is gone (no more events are delivered)
271
272 =item $event->IN_xxx
273
274 Returns a boolean that returns true if the event mask matches the
275 event. All of the C<IN_xxx> constants can be used as methods.
276
277 =item $event->cookie
278
279 =item $event->{cookie}
280
281 The event cookie, can be used to synchronize two related events.
282
283 =back
284
285 =cut
286
287 package Linux::Inotify2::Event;
288
289 sub w { $_[0]{w} }
290 sub name { $_[0]{name} }
291 sub mask { $_[0]{mask} }
292 sub cookie { $_[0]{cookie} }
293
294 sub fullname {
295 length $_[0]{name}
296 ? "$_[0]{w}{name}/$_[0]{name}"
297 : $_[0]{w}{name};
298 }
299
300 for my $name (@Linux::Inotify2::constants) {
301 my $mask = &{"Linux::Inotify2::$name"};
302
303 *$name = sub { ($_[0]{mask} & $mask) == $mask };
304 }
305
306 =head2 The Linux::Inotify2::Watch Class
307
308 Watch objects are created by calling the C<watch> method of a notifier.
309
310 It has the following members and methods:
311
312 =item $watch->name
313
314 =item $watch->{name}
315
316 The name as specified in the C<watch> call. For the object itself, this is
317 the empty string. For directory watches, this is the name of the entry
318 without leading path elements.
319
320 =item $watch->mask
321
322 =item $watch->{mask}
323
324 The mask as specified in the C<watch> call.
325
326 =item $watch->cb ([new callback])
327
328 =item $watch->{cb}
329
330 The callback as specified in the C<watch> call. Can optionally be changed.
331
332 =item $watch->cancel
333
334 Cancels/removes this watch. Future events, even if already queued queued,
335 will not be handled and resources will be freed.
336
337 =cut
338
339 package Linux::Inotify2::Watch;
340
341 sub name { $_[0]{name} }
342 sub mask { $_[0]{mask} }
343
344 sub cb {
345 $_[0]{cb} = $_[1] if @_ > 1;
346 $_[0]{cb}
347 }
348
349 sub cancel {
350 my ($self) = @_;
351
352 my $inotify = delete $self->{inotify}
353 or return 1; # already canceled
354
355 delete $inotify->{w}{$self->{wd}}; # we are no longer there
356 $inotify->{ignore}{$self->{wd}} = 1; # ignore further events for one poll
357
358 (Linux::Inotify2::inotify_rm_watch $inotify->{fd}, $self->{wd})
359 ? 1 : undef
360 }
361
362 =head1 SEE ALSO
363
364 L<Linux::Inotify>.
365
366 =head1 AUTHOR
367
368 Marc Lehmann <schmorp@schmorp.de>
369 http://home.schmorp.de/
370
371 =cut
372
373 1