sub O_ACCMODE () { O_RDONLY | O_RDWR | O_WRONLY }
-$VERSION = "0.95";
+$VERSION = "0.97_01";
my $DEFAULT_MEMORY_SIZE = 1<<21; # 2 megabytes
my $DEFAULT_AUTODEFER_THRESHHOLD = 3; # 3 records
my $DEFAULT_AUTODEFER_FILELEN_THRESHHOLD = 65536; # 16 disk blocksful
my %good_opt = map {$_ => 1, "-$_" => 1}
qw(memory dw_size mode recsep discipline
- autodefer autochomp autodefer_threshhold);
+ autodefer autochomp autodefer_threshhold concurrent);
sub TIEARRAY {
if (@_ % 2 != 0) {
}
}
+ if ($opts{concurrent}) {
+ croak("$pack: concurrent access not supported yet\n");
+ }
+
unless (defined $opts{memory}) {
# default is the larger of the default cache size and the
# deferred-write buffer size (if specified)
unless (seek $file, 1, SEEK_SET) {
croak "$pack: your filehandle does not appear to be seekable";
}
- seek $file, 0, SEEK_SET # put it back
+ seek $file, 0, SEEK_SET; # put it back
$fh = $file; # setting binmode is the user's problem
} elsif (ref $file) {
croak "usage: tie \@array, $pack, filename, [option => value]...";
} else {
- $fh = \do { local *FH }; # only works in 5.005 and later
+ # $fh = \do { local *FH }; # XXX this is buggy
+ if ($] < 5.006) {
+ # perl 5.005 and earlier don't autovivify filehandles
+ require Symbol;
+ $fh = Symbol::gensym();
+ }
sysopen $fh, $file, $opts{mode}, 0666 or return;
binmode $fh;
++$opts{ourfh};
if (@_) {
$unwritten = $self->_downcopy($data, $end, $_[1] - $end);
} else {
- # Make the file longer to accomodate the last segment that doesn'
+ # Make the file longer to accommodate the last segment that doesn'
$unwritten = $self->_downcopy($data, $end);
}
}
# moving everything in the block forwards to make room.
# Instead of writing the last length($data) bytes from the block
# (because there isn't room for them any longer) return them.
+#
+# Undefined $len means 'until the end of the file'
sub _downcopy {
my $blocksize = 8192;
my ($self, $data, $pos, $len) = @_;
: $len > $blocksize? $blocksize : $len;
$self->_seekb($pos);
read $fh, my($old), $readsize;
+ my $last_read_was_short = length($old) < $readsize;
$data .= $old;
- $self->_seekb($pos);
- my $writable = substr($data, 0, $readsize, "");
+ my $writable;
+ if ($last_read_was_short) {
+ # If last read was short, then $data now contains the entire rest
+ # of the file, so there's no need to write only one block of it
+ $writable = $data;
+ $data = "";
+ } else {
+ $writable = substr($data, 0, $readsize, "");
+ }
last if $writable eq "";
+ $self->_seekb($pos);
$self->_write_record($writable);
+ last if $last_read_was_short && $data eq "";
$len -= $readsize if defined $len;
$pos += $readsize;
}
$rec = <$fh>;
}
return unless defined $rec;
- if (! $self->{sawlastrec} &&
- substr($rec, -$self->{recseplen}) ne $self->{recsep}) {
+ if (substr($rec, -$self->{recseplen}) ne $self->{recsep}) {
# improperly terminated final record --- quietly fix it.
# my $ac = substr($rec, -$self->{recseplen});
# $ac =~ s/\n/\\n/g;
=head1 SYNOPSIS
- # This file documents Tie::File version 0.95
+ # This file documents Tie::File version 0.97
use Tie::File;
tie @array, 'Tie::File', filename or die ...;
=head1 CONCURRENT ACCESS TO FILES
Caching and deferred writing are inappropriate if you want the same
-file to be accessed simultaneously from more than one process. You
-will want to disable these features. You should do that by including
-the C<memory =E<gt> 0> option in your C<tie> calls; this will inhibit
-caching and deferred writing.
+file to be accessed simultaneously from more than one process. Other
+optimizations performed internally by this module are also
+incompatible with concurrent access. A future version of this module will
+support a C<concurrent =E<gt> 1> option that enables safe concurrent access.
-You will also want to lock the file while reading or writing it. You
-can use the C<-E<gt>flock> method for this. A future version of this
-module may provide an 'autolocking' mode.
+Previous versions of this documentation suggested using C<memory
+=E<gt> 0> for safe concurrent access. This was mistaken. Tie::File
+will not support safe concurrent access before version 0.98.
=head1 CAVEATS
=head1 LICENSE
-C<Tie::File> version 0.95 is copyright (C) 2002 Mark Jason Dominus.
+C<Tie::File> version 0.97 is copyright (C) 2003 Mark Jason Dominus.
This library is free software; you may redistribute it and/or modify
it under the same terms as Perl itself.
=head1 WARRANTY
-C<Tie::File> version 0.95 comes with ABSOLUTELY NO WARRANTY.
+C<Tie::File> version 0.97 comes with ABSOLUTELY NO WARRANTY.
For details, see the license.
=head1 THANKS
Additional thanks to:
Edward Avis /
Mattia Barbon /
+Tom Christiansen /
Gerrit Haase /
+Gurusamy Sarathy /
Jarkko Hietaniemi (again) /
Nikola Knezevic /
John Kominetz /