File: 02-sendfile.t

package info (click to toggle)
libsys-syscall-perl 0.25-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 228 kB
  • sloc: perl: 338; makefile: 7
file content (94 lines) | stat: -rw-r--r-- 2,335 bytes parent folder | download | duplicates (7)
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->();
    }
}