/usr/share/perl5/File/Queue.pm is in libfile-queue-perl 1.01a-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | package File::Queue;
use strict;
use IO::File;
use Fcntl 'SEEK_END', 'SEEK_SET', 'O_CREAT', 'O_RDWR';
use Carp qw(carp croak);
our $VERSION = '1.01';
sub new
{
my $class = shift;
my $mi = $class . '->new()';
croak "$mi requires an even number of parameters" if (@_ & 1);
my %params = @_;
# convert to lower case
while( my($key, $val) = each %params)
{
delete $params{$key};
$params{ lc($key) } = $val;
}
croak "$mi needs an File parameter" unless exists $params{file};
my $queue_file = delete $params{file};
my $idx_file = $queue_file . '.idx';
$queue_file .= '.dat';
my $self;
my $mode = delete $params{mode} || '0600';
$self->{block_size} = delete $params{blocksize} || 64;
$self->{seperator} = delete $params{seperator} || "\n";
$self->{sep_length} = length $self->{seperator};
croak "Seperator length cannot be greater than BlockSize" if ($self->{sep_length} > $self->{block_size});
$self->{queue_file} = $queue_file;
$self->{idx_file} = $idx_file;
$self->{queue} = new IO::File $queue_file, O_CREAT | O_RDWR, $mode or croak $!;
$self->{idx} = new IO::File $idx_file, O_CREAT | O_RDWR, $mode or croak $!;
### Default ptr to 0, replace it with value in idx file if one exists
$self->{idx}->sysseek(0, SEEK_SET);
$self->{idx}->sysread($self->{ptr}, 1024);
$self->{ptr} = '0' unless $self->{ptr};
if($self->{ptr} > -s $queue_file)
{
carp "Ptr is greater than queue file size, resetting ptr to '0'";
$self->{idx}->truncate(0) or croak "Could not truncate idx: $!";
$self->{idx}->sysseek(0, SEEK_SET);
$self->{idx}->syswrite('0') or croak "Could not syswrite to idx: $!";
}
bless $self, $class;
return $self;
}
sub enq
{
my ($self, $element) = @_;
$self->{queue}->sysseek(0, SEEK_END);
if(ref $element)
{
croak 'Cannot handle references';
}
if($element =~ s/$self->{seperator}//g)
{
carp "Removed illegal seperator(s) from $element";
}
$self->{queue}->syswrite("$element$self->{seperator}") or croak "Could not syswrite to queue: $!";
}
sub deq
{
my $self = shift;
my $element;
$self->{queue}->sysseek($self->{ptr}, SEEK_SET);
my $i;
while($self->{queue}->sysread($_, $self->{block_size}))
{
$i = index($_, $self->{seperator});
if($i != -1)
{
$element .= substr($_, 0, $i);
$self->{ptr} += $i + $self->{sep_length};
$self->{queue}->sysseek($self->{ptr}, SEEK_SET);
last;
}
else
{
## If seperator isn't found, go back 'sep_length' spaces to ensure we don't miss it between reads
$element .= substr($_, 0, -$self->{sep_length}, '');
$self->{ptr} += $self->{block_size} - $self->{sep_length};
$self->{queue}->sysseek($self->{ptr}, SEEK_SET);
}
}
## If queue seek pointer is at the EOF, truncate the queue file
if($self->{queue}->sysread($_, 1) == 0)
{
$self->{queue}->truncate(0) or croak "Could not truncate queue: $!";
$self->{queue}->sysseek($self->{ptr} = 0, SEEK_SET);
}
## Set idx file contents to point to the current seek position in queue file
$self->{idx}->truncate(0) or croak "Could not truncate idx: $!";
$self->{idx}->sysseek(0, SEEK_SET);
$self->{idx}->syswrite($self->{ptr}) or croak "Could not syswrite to idx: $!";
return $element;
}
sub peek
{
my ($self, $count) = @_;
croak "Invalid argument to peek ($count)" unless $count > 0;
my $elements;
$self->{queue}->sysseek($self->{ptr}, SEEK_SET);
my (@items, $remainder);
GATHER:
while($self->{queue}->sysread($_, $self->{block_size}))
{
if(defined $remainder)
{
$_ = $remainder . $_;
}
@items = split /$self->{seperator}/, $_, -1;
$remainder = pop @items;
foreach (@items)
{
push @$elements, $_;
last GATHER if $count == @$elements;
}
}
return $elements;
}
sub reset
{
my $self = shift;
$self->{idx}->truncate(0) or croak "Could not truncate idx: $!";
$self->{idx}->sysseek(0, SEEK_SET);
$self->{idx}->syswrite('0') or croak "Could not syswrite to idx: $!";
$self->{queue}->sysseek($self->{ptr} = 0, SEEK_SET);
}
sub close
{
my $self = shift;
$self->{idx}->close();
$self->{queue}->close();
}
sub delete
{
my $self = shift;
$self->close();
unlink $self->{queue_file};
unlink $self->{idx_file};
}
1;
|