ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Linux-Inotify2/Inotify2.pm
Revision: 1.10
Committed: Sun Nov 27 12:43:40 2005 UTC (18 years, 7 months ago) by root
Branch: MAIN
CVS Tags: rel-0_8
Changes since 1.9: +9 -7 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     Linux::Inotify2 - scalable directory/file change notification
4    
5     =head1 SYNOPSIS
6    
7     use Linux::Inotify2;
8    
9 root 1.4 # 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 root 1.1 =head1 DESCRIPTION
34    
35 root 1.3 This module implements an interface to the Linux 2.6.13 and later Inotify
36     file/directory change notification sytem.
37 root 1.2
38 root 1.3 It has a number of advantages over the Linux::Inotify module:
39 root 1.2
40     - it is portable (Linux::Inotify only works on x86)
41     - the equivalent of fullname works correctly
42     - it is better documented
43     - it has callback-style interface, which is better suited for
44     integration.
45    
46 root 1.6 =head2 The Linux::Inotify2 Class
47    
48 root 1.1 =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 root 1.10 $VERSION = 0.8;
61 root 1.1
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 root 1.9 IN_CREATE IN_DELETE IN_DELETE_SELF IN_MOVE_SELF
66 root 1.1 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 root 1.4 Example:
92    
93     my $inotify = new Linux::Inotify2
94     or die "Unable to create new inotify object: $!";
95    
96 root 1.1 =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 root 1.4 =item $watch = $inotify->watch ($name, $mask, $cb)
109 root 1.1
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 root 1.4 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 root 1.9 IN_MOVE_SELF object itself was moved
130 root 1.4 IN_ALL_EVENTS all of the above events
131 root 1.1
132     IN_ONESHOT only send event once
133    
134 root 1.4 IN_CLOSE same as IN_CLOSE_WRITE | IN_CLOSE_NOWRITE
135     IN_MOVE same as IN_MOVED_FROM | IN_MOVED_TO
136 root 1.1
137     C<$cb> is a perl code reference that is called for each event. It receives
138     a C<Linux::Inotify2::Event> object.
139    
140     The returned C<$watch> object is of class C<Linux::Inotify2::Watch>.
141    
142     On error, C<undef> is returned and C<$!> will be set accordingly. The
143     following errors are documented:
144    
145     EBADF The given file descriptor is not valid.
146     EINVAL The given event mask contains no legal events.
147     ENOMEM Insufficient kernel memory was available.
148     ENOSPC The user limit on the total number of inotify watches was reached or the kernel failed to allocate a needed resource.
149     EACCESS Read access to the given file is not permitted.
150    
151     Example, show when C</etc/passwd> gets accessed and/or modified once:
152    
153     $inotify->watch ("/etc/passwd", IN_ACCESS | IN_MODIFY, sub {
154     my $e = shift;
155     print "$e->{w}{name} was accessed\n" if $e->IN_ACCESS;
156     print "$e->{w}{name} was modified\n" if $e->IN_MODIFY;
157     print "$e->{w}{name} is no longer mounted\n" if $e->IN_UNMOUNT;
158     print "events for $e->{w}{name} have been lost\n" if $e->IN_Q_OVERFLOW;
159    
160     $e->w->cancel;
161     });
162    
163     =cut
164    
165     sub watch {
166     my ($self, $name, $mask, $cb) = @_;
167    
168     my $wd = inotify_add_watch $self->{fd}, $name, $mask;
169    
170     return unless $wd >= 0;
171    
172     my $w = $self->{w}{$wd} = bless {
173     inotify => $self,
174     wd => $wd,
175     name => $name,
176     mask => $mask,
177     cb => $cb,
178     }, Linux::Inotify2::Watch;
179    
180     Scalar::Util::weaken $w->{inotify};
181    
182     $w
183     }
184    
185 root 1.4 =item $inotify->fileno
186 root 1.1
187     Returns the fileno for this notify object. You are responsible for calling
188     the C<poll> method when this fileno becomes ready for reading.
189    
190     =cut
191    
192     sub fileno {
193     $_[0]{fd}
194     }
195    
196 root 1.4 =item $count = $inotify->poll
197 root 1.1
198 root 1.4 Reads events from the kernel and handles them. If the notify fileno is
199     blocking (the default), then this method waits for at least one event
200     (and thus returns true unless an error occurs). Otherwise it returns
201     immediately when no pending events could be read.
202 root 1.1
203     Returns the count of events that have been handled.
204    
205     =cut
206    
207     sub poll {
208     my ($self) = @_;
209    
210 root 1.4 my @ev = inotify_read $self->{fd};
211    
212     for (@ev) {
213     my $w = $_->{w} = $self->{w}{$_->{wd}}
214 root 1.1 or next; # no such watcher
215 root 1.4
216     exists $self->{ignore}{$_->{wd}}
217     and next; # watcher has been canceled
218    
219     $w->{cb}->(bless $_, Linux::Inotify2::Event);
220 root 1.10 $w->cancel if $_->{mask} & (IN_IGNORED | IN_UNMOUNT | IN_ONESHOT);
221 root 1.1 }
222 root 1.4
223     delete $self->{ignore};
224    
225     scalar @ev
226 root 1.1 }
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 root 1.7 member of the watcher (if the the watch is on a directory and a dir entry
257     is affected), or simply the C<name> member itself when the object is the
258     watch object itself.
259 root 1.1
260     =item $event->mask
261    
262     =item $event->{mask}
263    
264     The received event mask. In addition the the events described for
265     C<$inotify->watch>, the following flags (exported by default) can be set:
266    
267 root 1.4 IN_ISDIR event object is a directory
268     IN_Q_OVERFLOW event queue overflowed
269    
270 root 1.10 # when any of the following flags are set,
271     # then watchers for this event are automatically canceled
272 root 1.4 IN_UNMOUNT filesystem for watch'ed object was unmounted
273     IN_IGNORED file was ignored/is gone (no more events are delivered)
274 root 1.10 IN_ONESHOT only one event was generated
275 root 1.1
276     =item $event->IN_xxx
277    
278     Returns a boolean that returns true if the event mask matches the
279     event. All of the C<IN_xxx> constants can be used as methods.
280    
281     =item $event->cookie
282    
283     =item $event->{cookie}
284    
285 root 1.10 The event cookie to "synchronize two events". Normally zero, this value is
286     set when two events relating to the same file are generated. As far as I
287     know, this only happens for C<IN_MOVED_FROM> and C<IN_MOVED_TO> events, to
288     identify the old and new name of a file.
289 root 1.1
290     =back
291    
292     =cut
293    
294     package Linux::Inotify2::Event;
295    
296     sub w { $_[0]{w} }
297     sub name { $_[0]{name} }
298     sub mask { $_[0]{mask} }
299     sub cookie { $_[0]{cookie} }
300    
301     sub fullname {
302     length $_[0]{name}
303     ? "$_[0]{w}{name}/$_[0]{name}"
304     : $_[0]{w}{name};
305     }
306    
307     for my $name (@Linux::Inotify2::constants) {
308     my $mask = &{"Linux::Inotify2::$name"};
309    
310     *$name = sub { ($_[0]{mask} & $mask) == $mask };
311     }
312    
313     =head2 The Linux::Inotify2::Watch Class
314    
315     Watch objects are created by calling the C<watch> method of a notifier.
316    
317     It has the following members and methods:
318    
319     =item $watch->name
320    
321     =item $watch->{name}
322    
323     The name as specified in the C<watch> call. For the object itself, this is
324     the empty string. For directory watches, this is the name of the entry
325     without leading path elements.
326    
327     =item $watch->mask
328    
329     =item $watch->{mask}
330    
331     The mask as specified in the C<watch> call.
332    
333     =item $watch->cb ([new callback])
334    
335     =item $watch->{cb}
336    
337     The callback as specified in the C<watch> call. Can optionally be changed.
338    
339     =item $watch->cancel
340    
341     Cancels/removes this watch. Future events, even if already queued queued,
342     will not be handled and resources will be freed.
343    
344     =cut
345    
346     package Linux::Inotify2::Watch;
347    
348     sub name { $_[0]{name} }
349     sub mask { $_[0]{mask} }
350    
351     sub cb {
352     $_[0]{cb} = $_[1] if @_ > 1;
353     $_[0]{cb}
354     }
355    
356     sub cancel {
357     my ($self) = @_;
358    
359 root 1.4 my $inotify = delete $self->{inotify}
360     or return 1; # already canceled
361    
362     delete $inotify->{w}{$self->{wd}}; # we are no longer there
363     $inotify->{ignore}{$self->{wd}} = 1; # ignore further events for one poll
364    
365     (Linux::Inotify2::inotify_rm_watch $inotify->{fd}, $self->{wd})
366 root 1.1 ? 1 : undef
367     }
368    
369     =head1 SEE ALSO
370    
371     L<Linux::Inotify>.
372    
373     =head1 AUTHOR
374    
375     Marc Lehmann <schmorp@schmorp.de>
376     http://home.schmorp.de/
377    
378     =cut
379    
380     1