the sysread problem can be corrected with a fairly simple change - just check for the last buffer for the end of line. sample program showing some of the variations:
#
# demonstrate the sysread (and read) problem and correction. we reall
+y only need a small
# file to demonstrate the problem....
#
use strict;
my $test_file="sysread_test_file.txt"; # change name to test siz
+e/length differences
#
# create the test file
#
sub create_test_file
{
return if -e $test_file; # we do not want to create
+if it already exists....
open TOUT,">$test_file";
#
# write a small file with an extra line missing the EOL.
#
for (my $line=0;$line<1000;$line++)
{
print TOUT "qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdf
+ghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890\n";
}
print TOUT "qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk
+lzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890"; # no EO
+L!
close TOUT;
}
sub test_while_variable
{
my $linecount=0;
open TIN,"<$test_file";
while (<TIN>)
{
$linecount++;
}
close TIN;
print "test_while_variable: $linecount\n";
}
sub test_block_read($)
{
my $block_size=$_[0];
open TIN,"<$test_file";
binmode TIN;
my ($data, $n);
my $newlinecount=0;
while ((read TIN, $data, $_[0]) != 0)
{
$newlinecount+=($data =~ tr/\012//);
}
close(TIN);
print "test_block_read: $newlinecount\n";
}
sub test_fixed_block_read($)
{
my $block_size=$_[0];
open TIN,"<$test_file";
binmode TIN;
my ($data, $n);
my $newlinecount=0;
while ((read TIN, $data, $_[0]) != 0)
{
$newlinecount+=($data =~ tr/\012//);
}
close(TIN);
$newlinecount++ if $data !~ /\012$/;
print "test_fixed_block_read: $newlinecount\n";
}
sub test_block_sysread($)
{
my $block_size=$_[0];
open TIN,"<$test_file";
my ($data, $n);
my $newlinecount=0;
while ((sysread TIN, $data, $_[0]) != 0)
{
$newlinecount+=($data =~ tr/\012//);
}
close(TIN);
print "test_block_sysread: $newlinecount\n";
}
sub test_fixed_block_sysread($)
{
my $block_size=$_[0];
open TIN,"<$test_file";
my ($data, $n);
my $newlinecount=0;
while ((sysread TIN, $data, $_[0]) != 0)
{
$newlinecount+=($data =~ tr/\012//);
}
close(TIN);
$newlinecount++ if $data !~ /\012$/;
print "test_fixed_block_sysread: $newlinecount\n";
}
#
# do the test
#
create_test_file; # create the test file if not already presen
+t
test_while_variable;
test_block_read 4096;
test_fixed_block_read 4096;
test_block_sysread 4096;
test_fixed_block_sysread 4096;
exit 0;