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
|
#!/usr/bin/perl
use strict;
use Test::More;
use Sys::Syscall qw(:sendfile);
use IO::Socket::INET;
use File::Temp qw(tempdir);
if (Sys::Syscall::sendfile_defined()) {
plan tests => 2;
} else {
plan skip_all => "sendfile not defined";
exit 0;
}
my $ip = "127.0.0.1";
my $port = 60001;
my $child;
my $content = "I am a test file!\n" x (5 * 1024);
my $clen = length($content);
END {
kill 9, $child if $child;
}
# make child to listen and receive
if ($child = fork()) { parent(); }
else { child(); }
exit 0;
sub parent {
my $sock;
my $tries = 0;
while (! $sock && $tries++ < 5) {
$sock = IO::Socket::INET->new(PeerAddr => "$ip:$port");
last if $sock;
select undef, undef, undef, 0.25;
}
die "no socket" unless $sock;
my $dir = tempdir(CLEANUP => 1) or die "couldn't make tempdir";
my $tfile = "$dir/test";
open (F, ">$tfile") or die "couldn't write to test file in $dir: $!";
print F $content;
close F;
is(-s $tfile, $clen, "right size test file");
open (F, $tfile);
my $remain = $clen;
while ($remain) {
my $rv = sendfile(fileno($sock), fileno(F), 1234);
die "got rv = $rv from sendfile" unless $rv > 0;
$remain -= $rv;
die "remain dropped below zero" if $remain < 0;
}
close F;
my $line = <$sock>;
like($line, qr/^OK/, "child got all data") or diag "Child said: $line";
}
sub child {
my $listen = IO::Socket::INET->new(Listen => 5,
LocalAddr => $ip,
LocalPort => $port,
ReuseAddr => 1,
Proto => 'tcp')
or die "couldn't start listening";
while (my $sock = $listen->accept) {
my $ok = sub {
my $send = "OK\n";
syswrite($sock, $send);
exit 0;
};
my $bad = sub {
my $send = "BAD\n";
syswrite($sock, $send);
exit 0;
};
my $got;
my $gotlen;
while (<$sock>) {
$got .= $_;
$gotlen += length($_);
if ($gotlen == $clen) {
$ok->() if $got eq $content;
$bad->();
}
}
$bad->();
}
}
|