File Coverage

blib/lib/Linux/Inotify.pm
Criterion Covered Total %
statement 98 113 86.7
branch 3 22 13.6
condition n/a
subroutine 31 33 93.9
pod 0 5 0.0
total 132 173 76.3


line stmt bran cond sub pod time code
1             package Linux::Inotify;
2              
3 1     1   138630 use strict;
  1         2  
  1         35  
4 1     1   4 use warnings;
  1         3  
  1         92  
5 1     1   6 use Carp;
  1         2  
  1         58  
6 1     1   498 use POSIX;
  1         9340  
  1         6  
7 1     1   3405 use Config;
  1         1  
  1         61  
8              
9             # ABSTRACT: Classes for supporting inotify in Linux Kernel >= 2.6.13
10             our $VERSION = '0.06'; # VERSION
11              
12              
13 1     1   5 use constant ACCESS => 0x00000001;
  1         2  
  1         69  
14 1     1   5 use constant MODIFY => 0x00000002;
  1         2  
  1         55  
15 1     1   6 use constant ATTRIB => 0x00000004;
  1         4  
  1         38  
16 1     1   4 use constant CLOSE_WRITE => 0x00000008;
  1         2  
  1         41  
17 1     1   4 use constant CLOSE_NOWRITE => 0x00000010;
  1         2  
  1         35  
18 1     1   5 use constant OPEN => 0x00000020;
  1         2  
  1         43  
19 1     1   11 use constant MOVED_FROM => 0x00000040;
  1         1  
  1         36  
20 1     1   4 use constant MOVED_TO => 0x00000080;
  1         1  
  1         38  
21 1     1   5 use constant CREATE => 0x00000100;
  1         1  
  1         32  
22 1     1   5 use constant DELETE => 0x00000200;
  1         12  
  1         35  
23 1     1   4 use constant DELETE_SELF => 0x00000400;
  1         1  
  1         38  
24 1     1   5 use constant UNMOUNT => 0x00002000;
  1         22  
  1         42  
25 1     1   4 use constant Q_OVERFLOW => 0x00004000;
  1         2  
  1         41  
26 1     1   4 use constant IGNORED => 0x00008000;
  1         2  
  1         34  
27 1     1   4 use constant ISDIR => 0x40000000;
  1         1  
  1         40  
28 1     1   5 use constant ONESHOT => 0x80000000;
  1         2  
  1         43  
29 1     1   5 use constant CLOSE => 0x00000018;
  1         1  
  1         37  
30 1     1   5 use constant MOVE => 0x000000c0;
  1         2  
  1         90  
31 1     1   6 use constant ALL_EVENTS => 0x00000fff;
  1         1  
  1         878  
32              
33             sub _arch_config {
34 1     1   19 my ($arch) = ($Config{archname} =~ m{([^-]+)-});
35 1 50       9 return (253,254,255) if $arch eq 'x86_64';
36 0 0       0 return (26, 27, 28, 0) if $arch eq 'aarch64';
37 0 0       0 return (151, 152, 156) if $arch =~ /^sparc(_64|)\z/;
38 0 0       0 return (444, 445, 446) if $arch eq 'alpha';
39 0 0       0 return (291, 292, 293) if $arch =~ /^i[3456]86\z/;
40 0 0       0 return (1277, 1278, 1279) if $arch eq 'ia64';
41 0 0       0 return (275, 276, 277) if $arch =~ /^powerpc(|64)\z/;
42 0 0       0 return (284, 285, 296) if $arch eq 's390';
43 0         0 die "do not know syscalls for inotify on $arch";
44             }
45              
46             sub syscall_init;
47             sub syscall_add_watch;
48             sub syscall_rm_watch;
49              
50             if(my($init, $add, $remove, @init_args) = _arch_config()) {
51             if(@init_args) {
52             *syscall_init = sub { syscall $init, 0 };
53             } else {
54 1     1   38 *syscall_init = sub { syscall $init };
55             }
56 1     1   45 *syscall_add_watch = sub { syscall $add, @_ };
57 0     0   0 *syscall_rm_watch = sub { syscall $remove, @_ };
58             }
59              
60             sub new {
61 1     1 0 247349 my $class = shift;
62 1         6 my $fd = syscall_init();
63 1 50       7 croak "Linux::Inotify::init() failed: $!" if $fd == -1;
64 1         9 return bless { fd => $fd }, $class;
65             }
66              
67             sub add_watch {
68 1     1 0 22 my $self = shift;
69 1         838 require Linux::Inotify::Watch;
70 1         11 my $watch = Linux::Inotify::Watch->new($self, @_);
71 1         10 $self->{wd}->{$watch->{wd}} = $watch;
72 1         4 return $watch;
73             }
74              
75             sub find {
76 3     3 0 5 my $self = shift;
77 3         5 my $wd = shift;
78 3         13 return $self->{wd}->{$wd};
79             }
80              
81             sub close {
82 0     0 0 0 my $self = shift;
83 0         0 for my $watch (values %{$self->{wd}}) {
  0         0  
84 0         0 $watch->remove;
85             }
86 0         0 my $ret = POSIX::close($self->{fd});
87 0 0       0 croak "Linux::Inotify::close() failed: $!" unless defined $ret;
88             }
89              
90             sub read {
91 2     2 0 580 my $self = shift;
92 2         39 my $bytes = POSIX::read($self->{fd}, my $raw_events, 65536);
93 2 50       11 croak "Linux::Inotify::read: read only $bytes bytes: $!" if $bytes < 16;
94 2         5 my @all_events;
95 2         3 do {
96 3         993 require Linux::Inotify::Event;
97 3         19 my $event = Linux::Inotify::Event->new($self, $raw_events);
98 3         7 push @all_events, $event;
99 3         39 $raw_events = substr($raw_events, 16 + $event->{len});
100             } while(length $raw_events >= 16);
101 2         18 return @all_events;
102             }
103              
104             1;
105              
106             __END__