#! /usr/bin/perl use strict; use warnings; use IO::Socket::INET6; use Time::HiRes qw(sleep); @ARGV==5 or die "$0 "; my($hostname,$port,$string,$timeout,$tries)=@ARGV; for our $try (1..$tries) { sub ts() { return localtime()." PID=$$ #$try: "; } warn ts()."connect($hostname,$port)...\n"; my $sock=IO::Socket::INET6->new( "Proto" =>"tcp", "PeerAddr"=>$hostname, "PeerPort"=>$port, ); if (!$sock) { warn ts()."connect($hostname,$port)=$!"; sleep $timeout; next; } warn ts()."connect($hostname,$port): done.\n"; my $buf=""; my $remains=$timeout; while ($remains>0) { my $rin=""; vec($rin,fileno($sock),1)=1; my($nfound,$timeleft)=select($rin,"",$rin,$remains); die "select nfound=$nfound: $!" if $nfound<0; die "select timeleft=$timeleft" if $timeleft<0; $remains=$timeleft; if (!$nfound) { $remains==0 or die "remains=$remains"; last; } my $c; my $got=sysread $sock,$c,1; my $fail; if (!defined $got) { warn ts()."sysread: $!"; $fail=1; } if ($got==0) { warn ts()."sysread: EOF"; $fail=1; } if (!$fail) { $got==1 or die "sysread=$got!=1"; length($c)==1 or die "sysread->c=".length($c)."!=1"; $buf.=$c; } last if length($buf)>=length($string); # warn ts()."remains=<$remains> buf=<$buf>\n"; last if $fail; } close $sock or warn ts()."close: $!"; if ($buf eq $string) { warn ts()."PASS\n"; print "PASS\n"; exit 0; } warn ts()."buf=<$buf>, sleep $remains"; sleep $remains or warn ts()."sleep=$!"; } warn ts()."FAIL\n"; print "FAIL\n";