line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Linux::Inotify; |
2
|
|
|
|
|
|
|
our $VERSION = '0.05'; |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=pod |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Linux::Inotify - Classes for supporting inotify in Linux Kernel >= 2.6.13 |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 SYNOPSIS |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Linux::Inotify supports the new inotify interface of Linux which is a |
13
|
|
|
|
|
|
|
replacement of dnotify. Beside the class Linux::Inotify there two helper |
14
|
|
|
|
|
|
|
classes -- Linux::Inotify::Watch and Linux::Inotify::Event. |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 DESCRIPTION |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head2 class Linux::Inotify |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
The following code |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use Linux::Inotify; |
23
|
|
|
|
|
|
|
my $notifier = Linux::Inotify->new(); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
returns a new notifier. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $watch = $notifier->add_watch('filename', Linux::Inotify::MASK); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
adds a watch to filename (see below), where MASK is one of ACCESS, MODIFY, |
30
|
|
|
|
|
|
|
ATTRIB, CLOSE_WRITE, CLOSE_NOWRITE, OPEN, MOVED_FROM, MOVED_TO, CREATE, DELETE, |
31
|
|
|
|
|
|
|
DELETE_SELF, UNMOUNT, Q_OVERFLOW, IGNORED, ISDIR, ONESHOT, CLOSE, MOVE or |
32
|
|
|
|
|
|
|
ALL_EVENTS. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my @events = $notifier->read(); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
reads and decodes all available data and returns an array of |
37
|
|
|
|
|
|
|
Linux::Inotify::Event objects (see below). |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
$notifier->close(); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
destroys the notifier and closes the associated file descriptor. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head2 class Linux::Inotify::Watch |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
The constructor new is usually not called directly but via the add_watch method |
46
|
|
|
|
|
|
|
of the notifier. An alternative contructor |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
my $watch_clone = $watch->clone('filename'); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
creates an new watch for filename but shares the same $notifier and MASK. This |
51
|
|
|
|
|
|
|
is indirectly used for recursing into subdirectories (see below). The |
52
|
|
|
|
|
|
|
destructor |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
$watch->remove() |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
destroys the watch safely. It does not matter if the kernel has already removed |
57
|
|
|
|
|
|
|
the watch itself, which may happen when the watched object has been deleted. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head2 class Linux::Inotify::Event |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
The constructor is not called directly but through the read method of |
62
|
|
|
|
|
|
|
Linux::Inotify that returns an array of event objects. An |
63
|
|
|
|
|
|
|
Linux::Inotify::Event object has some interesting data members: mask, cookie |
64
|
|
|
|
|
|
|
and name. The method |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
$event->fullname(); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
returns the full name of the file or directory not only the name relative to |
69
|
|
|
|
|
|
|
the watch like the name member does contain. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
$event->print(); |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
prints the event to stdout in a human readable form. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
my $new_watch = $event->add_watch(); |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
creates a new watch for the file/directory of the event and shares the notifier |
78
|
|
|
|
|
|
|
and MASK of the original watch, that has generated the event. That is useful |
79
|
|
|
|
|
|
|
for recursing into subdirectories. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=head1 AUTHOR |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Copyright 2005 by Torsten Werner . The code is licensed |
85
|
|
|
|
|
|
|
under the same license as perl: L or L. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=cut |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
|
90
|
1
|
|
|
1
|
|
58989
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
30
|
|
91
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
26
|
|
92
|
1
|
|
|
1
|
|
4
|
use Carp; |
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
50
|
|
93
|
1
|
|
|
1
|
|
751
|
use POSIX; |
|
1
|
|
|
|
|
7631
|
|
|
1
|
|
|
|
|
6
|
|
94
|
1
|
|
|
1
|
|
2876
|
use Config; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
294
|
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
my %syscall_init = ( |
97
|
|
|
|
|
|
|
alpha => 444, |
98
|
|
|
|
|
|
|
arm => 316, |
99
|
|
|
|
|
|
|
i386 => 291, |
100
|
|
|
|
|
|
|
ia64 => 1277, |
101
|
|
|
|
|
|
|
powerpc => 275, |
102
|
|
|
|
|
|
|
powerpc64 => 275, |
103
|
|
|
|
|
|
|
s390 => 284, |
104
|
|
|
|
|
|
|
sh => 290, |
105
|
|
|
|
|
|
|
sparc => 151, |
106
|
|
|
|
|
|
|
sparc_64 => 151, |
107
|
|
|
|
|
|
|
x86_64 => 253, |
108
|
|
|
|
|
|
|
); |
109
|
|
|
|
|
|
|
my ($arch) = ($Config{archname} =~ m{([^-]+)-}); |
110
|
|
|
|
|
|
|
die "unsupported architecture: $arch\n" unless exists $syscall_init{$arch}; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub syscall_init { |
113
|
1
|
|
|
1
|
0
|
19
|
syscall $syscall_init{$arch}; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub syscall_add_watch { |
117
|
1
|
|
|
1
|
0
|
25
|
syscall $syscall_init{$arch} + 1, @_; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub syscall_rm_watch { |
121
|
0
|
0
|
|
0
|
0
|
0
|
unless ($arch =~ m{sparc}) { |
122
|
0
|
|
|
|
|
0
|
syscall $syscall_init{$arch} + 2, @_; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
else { |
125
|
|
|
|
|
|
|
# that's my favourite syscall: |
126
|
0
|
|
|
|
|
0
|
syscall $syscall_init{$arch} + 5, @_; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
sub new($) { |
131
|
1
|
|
|
1
|
0
|
731
|
my $class = shift; |
132
|
1
|
|
|
|
|
5
|
my $self = { |
133
|
|
|
|
|
|
|
fd => syscall_init |
134
|
|
|
|
|
|
|
}; |
135
|
1
|
50
|
|
|
|
29
|
croak "Linux::Inotify::init() failed: $!" if $self->{fd} == -1; |
136
|
1
|
|
|
|
|
5
|
return bless $self, $class; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub add_watch($$$) { |
140
|
1
|
|
|
1
|
0
|
24
|
my $self = shift; |
141
|
1
|
|
|
1
|
|
580
|
use Linux::Inotify::Watch; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
215
|
|
142
|
1
|
|
|
|
|
10
|
my $watch = Linux::Inotify::Watch->new($self, @_); |
143
|
1
|
|
|
|
|
6
|
$self->{wd}->{$watch->{wd}} = $watch; |
144
|
1
|
|
|
|
|
3
|
return $watch; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub find($$) { |
148
|
3
|
|
|
3
|
0
|
4
|
my $self = shift; |
149
|
3
|
|
|
|
|
4
|
my $wd = shift; |
150
|
3
|
|
|
|
|
11
|
return $self->{wd}->{$wd}; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub close($) { |
154
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
155
|
0
|
|
|
|
|
0
|
for my $watch (values %{$self->{wd}}) { |
|
0
|
|
|
|
|
0
|
|
156
|
0
|
|
|
|
|
0
|
$watch->remove; |
157
|
|
|
|
|
|
|
} |
158
|
0
|
|
|
|
|
0
|
my $ret = POSIX::close($self->{fd}); |
159
|
0
|
0
|
|
|
|
0
|
croak "Linux::Inotify::close() failed: $!" unless defined $ret; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
use constant { |
163
|
1
|
|
|
|
|
273
|
ACCESS => 0x00000001, |
164
|
|
|
|
|
|
|
MODIFY => 0x00000002, |
165
|
|
|
|
|
|
|
ATTRIB => 0x00000004, |
166
|
|
|
|
|
|
|
CLOSE_WRITE => 0x00000008, |
167
|
|
|
|
|
|
|
CLOSE_NOWRITE => 0x00000010, |
168
|
|
|
|
|
|
|
OPEN => 0x00000020, |
169
|
|
|
|
|
|
|
MOVED_FROM => 0x00000040, |
170
|
|
|
|
|
|
|
MOVED_TO => 0x00000080, |
171
|
|
|
|
|
|
|
CREATE => 0x00000100, |
172
|
|
|
|
|
|
|
DELETE => 0x00000200, |
173
|
|
|
|
|
|
|
DELETE_SELF => 0x00000400, |
174
|
|
|
|
|
|
|
UNMOUNT => 0x00002000, |
175
|
|
|
|
|
|
|
Q_OVERFLOW => 0x00004000, |
176
|
|
|
|
|
|
|
IGNORED => 0x00008000, |
177
|
|
|
|
|
|
|
ISDIR => 0x40000000, |
178
|
|
|
|
|
|
|
ONESHOT => 0x80000000, |
179
|
|
|
|
|
|
|
CLOSE => 0x00000018, |
180
|
|
|
|
|
|
|
MOVE => 0x000000c0, |
181
|
|
|
|
|
|
|
ALL_EVENTS => 0x00000fff |
182
|
1
|
|
|
1
|
|
4
|
}; |
|
1
|
|
|
|
|
12
|
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub read($) { |
185
|
2
|
|
|
2
|
0
|
346
|
my $self = shift; |
186
|
2
|
|
|
|
|
33
|
my $bytes = POSIX::read($self->{fd}, my $raw_events, 65536); |
187
|
2
|
50
|
|
|
|
7
|
croak "Linux::Inotify::read: read only $bytes bytes: $!" if $bytes < 16; |
188
|
2
|
|
|
|
|
4
|
my @all_events; |
189
|
2
|
|
|
|
|
2
|
do { |
190
|
1
|
|
|
1
|
|
461
|
use Linux::Inotify::Event; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
114
|
|
191
|
3
|
|
|
|
|
16
|
my $event = Linux::Inotify::Event->new($self, $raw_events); |
192
|
3
|
|
|
|
|
4
|
push @all_events, $event; |
193
|
3
|
|
|
|
|
16
|
$raw_events = substr($raw_events, 16 + $event->{len}); |
194
|
|
|
|
|
|
|
} while(length $raw_events >= 16); |
195
|
2
|
|
|
|
|
15
|
return @all_events; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
1; |
199
|
|
|
|
|
|
|
|