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