1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
################################################################################
#
# $Revision: 3 $
# $Author: mhx $
# $Date: 2008/11/26 23:12:27 +0100 $
#
################################################################################
#
# Version 2.x, Copyright (C) 2007, Marcus Holland-Moritz <mhx@cpan.org>.
# Version 1.x, Copyright (C) 1997, Graham Barr <gbarr@pobox.com>.
#
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
################################################################################
package IPC::SharedMem;
use IPC::SysV qw(IPC_STAT IPC_RMID shmat shmdt memread memwrite);
use strict;
use vars qw($VERSION);
use Carp;
$VERSION = do { my @r = '$Snapshot: /IPC-SysV/2.00_02 $' =~ /(\d+\.\d+(?:_\d+)?)/; @r ? $r[0] : '9.99' };
$VERSION = eval $VERSION;
# Figure out if we have support for native sized types
my $N = do { my $foo = eval { pack "L!", 0 }; $@ ? '' : '!' };
{
package IPC::SharedMem::stat;
use Class::Struct qw(struct);
struct 'IPC::SharedMem::stat' => [
uid => '$',
gid => '$',
cuid => '$',
cgid => '$',
mode => '$',
segsz => '$',
lpid => '$',
cpid => '$',
nattch => '$',
atime => '$',
dtime => '$',
ctime => '$',
];
}
sub new
{
@_ == 4 or croak 'IPC::SharedMem->new(KEY, SIZE, FLAGS)';
my($class, $key, $size, $flags) = @_;
my $id = shmget $key, $size, $flags;
return undef unless defined $id;
bless { _id => $id, _addr => undef, _isrm => 0 }, $class
}
sub id
{
my $self = shift;
$self->{_id};
}
sub addr
{
my $self = shift;
$self->{_addr};
}
sub stat
{
my $self = shift;
my $data = '';
shmctl $self->id, IPC_STAT, $data or return undef;
IPC::SharedMem::stat->new->unpack($data);
}
sub attach
{
@_ >= 1 && @_ <= 2 or croak '$shm->attach([FLAG])';
my($self, $flag) = @_;
defined $self->addr and return undef;
$self->{_addr} = shmat($self->id, undef, $flag || 0);
defined $self->addr;
}
sub detach
{
my $self = shift;
defined $self->addr or return undef;
my $rv = defined shmdt($self->addr);
undef $self->{_addr} if $rv;
$rv;
}
sub remove
{
my $self = shift;
return undef if $self->is_removed;
my $rv = shmctl $self->id, IPC_RMID, 0;
$self->{_isrm} = 1 if $rv;
return $rv;
}
sub is_removed
{
my $self = shift;
$self->{_isrm};
}
sub read
{
@_ == 3 or croak '$shm->read(POS, SIZE)';
my($self, $pos, $size) = @_;
my $buf = '';
if (defined $self->addr) {
memread($self->addr, $buf, $pos, $size) or return undef;
}
else {
shmread($self->id, $buf, $pos, $size) or return undef;
}
$buf;
}
sub write
{
@_ == 4 or croak '$shm->write(STRING, POS, SIZE)';
my($self, $str, $pos, $size) = @_;
if (defined $self->addr) {
return memwrite($self->addr, $str, $pos, $size);
}
else {
return shmwrite($self->id, $str, $pos, $size);
}
}
1;
__END__
=head1 NAME
IPC::SharedMem - SysV Shared Memory IPC object class
=head1 SYNOPSIS
use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR);
use IPC::SharedMem;
$shm = IPC::SharedMem->new(IPC_PRIVATE, 8, S_IRWXU);
$shm->write(pack("S", 4711), 2, 2);
$data = $shm->read(0, 2);
$ds = $shm->stat;
$shm->remove;
=head1 DESCRIPTION
A class providing an object based interface to SysV IPC shared memory.
=head1 METHODS
=over 4
=item new ( KEY , SIZE , FLAGS )
Creates a new shared memory segment associated with C<KEY>. A new
segment is created if
=over 4
=item *
C<KEY> is equal to C<IPC_PRIVATE>
=item *
C<KEY> does not already have a shared memory segment associated
with it, and C<I<FLAGS> & IPC_CREAT> is true.
=back
On creation of a new shared memory segment C<FLAGS> is used to
set the permissions. Be careful not to set any flags that the
Sys V IPC implementation does not allow: in some systems setting
execute bits makes the operations fail.
=item id
Returns the shared memory identifier.
=item read ( POS, SIZE )
Read C<SIZE> bytes from the shared memory segment at C<POS>. Returns
the string read, or C<undef> if there was an error. The return value
becomes tainted. See L<shmread>.
=item write ( STRING, POS, SIZE )
Write C<SIZE> bytes to the shared memory segment at C<POS>. Returns
true if successful, or false if there is an error. See L<shmwrite>.
=item remove
Remove the shared memory segment from the system or mark it as
removed as long as any processes are still attached to it.
=item is_removed
Returns true if the shared memory segment has been removed or
marked for removal.
=item stat
Returns an object of type C<IPC::SharedMem::stat> which is a sub-class
of C<Class::Struct>. It provides the following fields. For a description
of these fields see you system documentation.
uid
gid
cuid
cgid
mode
segsz
lpid
cpid
nattach
atime
dtime
ctime
=item attach ( [FLAG] )
Permanently attach to the shared memory segment. When a C<IPC::SharedMem>
object is attached, it will use L<memread> and L<memwrite> instead of
L<shmread> and L<shmwrite> for accessing the shared memory segment.
Returns true if successful, or false on error. See L<shmat>.
=item detach
Detach from the shared memory segment that previously has been attached
to. Returns true if successful, or false on error. See L<shmdt>.
=item addr
Returns the address of the shared memory that has been attached to in a
format suitable for use with C<pack('P')>. Returns C<undef> if the shared
memory has not been attached.
=back
=head1 SEE ALSO
L<IPC::SysV>, L<Class::Struct>
=head1 AUTHORS
Marcus Holland-Moritz <mhx@cpan.org>
=head1 COPYRIGHT
Version 2.x, Copyright (C) 2007, Marcus Holland-Moritz.
Version 1.x, Copyright (c) 1997, Graham Barr.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut
|