File Coverage

blib/lib/IPC/SharedMem.pm
Criterion Covered Total %
statement 57 57 100.0
branch 17 30 56.6
condition 2 5 40.0
subroutine 15 15 100.0
pod 10 10 100.0
total 101 117 86.3


line stmt bran cond sub pod time code
1             ################################################################################
2             #
3             # Version 2.x, Copyright (C) 2007-2013, Marcus Holland-Moritz .
4             # Version 1.x, Copyright (C) 1997, Graham Barr .
5             #
6             # This program is free software; you can redistribute it and/or
7             # modify it under the same terms as Perl itself.
8             #
9             ################################################################################
10              
11             package IPC::SharedMem;
12              
13 1     1   549 use IPC::SysV qw(IPC_STAT IPC_RMID shmat shmdt memread memwrite);
  1         2  
  1         58  
14 1     1   6 use strict;
  1         2  
  1         22  
15 1     1   5 use vars qw($VERSION);
  1         2  
  1         31  
16 1     1   15 use Carp;
  1         2  
  1         111  
17              
18             $VERSION = '2.09';
19              
20             # Figure out if we have support for native sized types
21             my $N = do { my $foo = eval { pack "L!", 0 }; $@ ? '' : '!' };
22              
23             {
24             package IPC::SharedMem::stat;
25              
26 1     1   529 use Class::Struct qw(struct);
  1         1926  
  1         6  
27              
28             struct 'IPC::SharedMem::stat' => [
29             uid => '$',
30             gid => '$',
31             cuid => '$',
32             cgid => '$',
33             mode => '$',
34             segsz => '$',
35             lpid => '$',
36             cpid => '$',
37             nattch => '$',
38             atime => '$',
39             dtime => '$',
40             ctime => '$',
41             ];
42             }
43              
44             sub new
45             {
46 1 50   1 1 6 @_ == 4 or croak 'IPC::SharedMem->new(KEY, SIZE, FLAGS)';
47 1         5 my($class, $key, $size, $flags) = @_;
48              
49 1         46 my $id = shmget $key, $size, $flags;
50              
51 1 50       5 return undef unless defined $id;
52              
53 1         28 bless { _id => $id, _addr => undef, _isrm => 0 }, $class
54             }
55              
56             sub id
57             {
58 8     8 1 12 my $self = shift;
59 8         191 $self->{_id};
60             }
61              
62             sub addr
63             {
64 19     19 1 29 my $self = shift;
65 19         117 $self->{_addr};
66             }
67              
68             sub stat
69             {
70 2     2 1 1188 my $self = shift;
71 2         5 my $data = '';
72 2 50       6 shmctl $self->id, IPC_STAT, $data or return undef;
73 2         57 IPC::SharedMem::stat->new->unpack($data);
74             }
75              
76             sub attach
77             {
78 1 50 33 1 1 18 @_ >= 1 && @_ <= 2 or croak '$shm->attach([FLAG])';
79 1         4 my($self, $flag) = @_;
80 1 50       3 defined $self->addr and return undef;
81 1   50     3 $self->{_addr} = shmat($self->id, undef, $flag || 0);
82 1         5 defined $self->addr;
83             }
84              
85             sub detach
86             {
87 1     1 1 2 my $self = shift;
88 1 50       4 defined $self->addr or return undef;
89 1         3 my $rv = defined shmdt($self->addr);
90 1 50       7 undef $self->{_addr} if $rv;
91 1         5 $rv;
92             }
93              
94             sub remove
95             {
96 1     1 1 3 my $self = shift;
97 1 50       3 return undef if $self->is_removed;
98 1         4 my $rv = shmctl $self->id, IPC_RMID, 0;
99 1 50       7 $self->{_isrm} = 1 if $rv;
100 1         5 return $rv;
101             }
102              
103             sub is_removed
104             {
105 3     3 1 6 my $self = shift;
106 3         12 $self->{_isrm};
107             }
108              
109             sub read
110             {
111 5 50   5 1 1521 @_ == 3 or croak '$shm->read(POS, SIZE)';
112 5         11 my($self, $pos, $size) = @_;
113 5         8 my $buf = '';
114 5 100       10 if (defined $self->addr) {
115 3 50       6 memread($self->addr, $buf, $pos, $size) or return undef;
116             }
117             else {
118 2 50       5 shmread($self->id, $buf, $pos, $size) or return undef;
119             }
120 5         29 $buf;
121             }
122              
123             sub write
124             {
125 4 50   4 1 1927 @_ == 4 or croak '$shm->write(STRING, POS, SIZE)';
126 4         11 my($self, $str, $pos, $size) = @_;
127 4 100       9 if (defined $self->addr) {
128 2         6 return memwrite($self->addr, $str, $pos, $size);
129             }
130             else {
131 2         7 return shmwrite($self->id, $str, $pos, $size);
132             }
133             }
134              
135             1;
136              
137             __END__