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   419 use IPC::SysV qw(IPC_STAT IPC_RMID shmat shmdt memread memwrite);
  1         6  
  1         46  
14 1     1   3 use strict;
  1         1  
  1         16  
15 1     1   3 use vars qw($VERSION);
  1         0  
  1         29  
16 1     1   3 use Carp;
  1         0  
  1         74  
17              
18             $VERSION = '2.07';
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   519 use Class::Struct qw(struct);
  1         1293  
  1         4  
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 25 @_ == 4 or croak 'IPC::SharedMem->new(KEY, SIZE, FLAGS)';
47 1         2 my($class, $key, $size, $flags) = @_;
48              
49 1         22 my $id = shmget $key, $size, $flags;
50              
51 1 50       2 return undef unless defined $id;
52              
53 1         12 bless { _id => $id, _addr => undef, _isrm => 0 }, $class
54             }
55              
56             sub id
57             {
58 8     8 1 6 my $self = shift;
59 8         115 $self->{_id};
60             }
61              
62             sub addr
63             {
64 19     19 1 15 my $self = shift;
65 19         74 $self->{_addr};
66             }
67              
68             sub stat
69             {
70 2     2 1 320 my $self = shift;
71 2         2 my $data = '';
72 2 50       3 shmctl $self->id, IPC_STAT, $data or return undef;
73 2         38 IPC::SharedMem::stat->new->unpack($data);
74             }
75              
76             sub attach
77             {
78 1 50 33 1 1 6 @_ >= 1 && @_ <= 2 or croak '$shm->attach([FLAG])';
79 1         2 my($self, $flag) = @_;
80 1 50       3 defined $self->addr and return undef;
81 1   50     2 $self->{_addr} = shmat($self->id, undef, $flag || 0);
82 1         2 defined $self->addr;
83             }
84              
85             sub detach
86             {
87 1     1 1 2 my $self = shift;
88 1 50       2 defined $self->addr or return undef;
89 1         2 my $rv = defined shmdt($self->addr);
90 1 50       3 undef $self->{_addr} if $rv;
91 1         4 $rv;
92             }
93              
94             sub remove
95             {
96 1     1 1 1 my $self = shift;
97 1 50       5 return undef if $self->is_removed;
98 1         2 my $rv = shmctl $self->id, IPC_RMID, 0;
99 1 50       3 $self->{_isrm} = 1 if $rv;
100 1         3 return $rv;
101             }
102              
103             sub is_removed
104             {
105 3     3 1 3 my $self = shift;
106 3         8 $self->{_isrm};
107             }
108              
109             sub read
110             {
111 5 50   5 1 765 @_ == 3 or croak '$shm->read(POS, SIZE)';
112 5         5 my($self, $pos, $size) = @_;
113 5         3 my $buf = '';
114 5 100       8 if (defined $self->addr) {
115 3 50       3 memread($self->addr, $buf, $pos, $size) or return undef;
116             }
117             else {
118 2 50       3 shmread($self->id, $buf, $pos, $size) or return undef;
119             }
120 5         16 $buf;
121             }
122              
123             sub write
124             {
125 4 50   4 1 965 @_ == 4 or croak '$shm->write(STRING, POS, SIZE)';
126 4         6 my($self, $str, $pos, $size) = @_;
127 4 100       7 if (defined $self->addr) {
128 2         6 return memwrite($self->addr, $str, $pos, $size);
129             }
130             else {
131 2         3 return shmwrite($self->id, $str, $pos, $size);
132             }
133             }
134              
135             1;
136              
137             __END__