1898184e3Ssthen#!./perl -w 2898184e3Ssthen 3*eac174f2Safresh1use v5.6.1; 4*eac174f2Safresh1use strict; 5*eac174f2Safresh1use warnings; 6*eac174f2Safresh1 7898184e3Ssthenmy $child; 8898184e3Ssthenmy $can_fork; 9898184e3Ssthenmy $has_perlio; 10898184e3Ssthen 11*eac174f2Safresh1our %Config; 12898184e3SsthenBEGIN { 13898184e3Ssthen require Config; import Config; 14898184e3Ssthen $can_fork = $Config{'d_fork'} || $Config{'d_pseudofork'}; 15898184e3Ssthen 16898184e3Ssthen if ($^O eq "hpux" or $Config{'extensions'} !~ /\bSocket\b/ && 17898184e3Ssthen !(($^O eq 'VMS') && $Config{d_socket})) { 18898184e3Ssthen print "1..0\n"; 19898184e3Ssthen exit 0; 20898184e3Ssthen } 21898184e3Ssthen} 22898184e3Ssthen 23898184e3Ssthen{ 24898184e3Ssthen # This was in the BEGIN block, but since Test::More 0.47 added support to 25898184e3Ssthen # detect forking, we don't need to fork before Test::More initialises. 26898184e3Ssthen 27898184e3Ssthen # Too many things in this test will hang forever if something is wrong, 28898184e3Ssthen # so we need a self destruct timer. And IO can hang despite an alarm. 29898184e3Ssthen 30898184e3Ssthen if( $can_fork) { 31898184e3Ssthen my $parent = $$; 32898184e3Ssthen $child = fork; 33898184e3Ssthen die "Fork failed" unless defined $child; 34898184e3Ssthen if (!$child) { 35898184e3Ssthen $SIG{INT} = sub {exit 0}; # You have 60 seconds. Your time starts now. 36898184e3Ssthen my $must_finish_by = time + 60; 37898184e3Ssthen my $remaining; 38898184e3Ssthen while (($remaining = $must_finish_by - time) > 0) { 39898184e3Ssthen sleep $remaining; 40898184e3Ssthen } 41898184e3Ssthen warn "Something unexpectedly hung during testing"; 42898184e3Ssthen kill "INT", $parent or die "Kill failed: $!"; 43b8851fccSafresh1 if( $^O eq "cygwin" ) { 44b8851fccSafresh1 # sometimes the above isn't enough on cygwin 45b8851fccSafresh1 sleep 1; # wait a little, it might have worked after all 46b8851fccSafresh1 system( "/bin/kill -f $parent; echo die $parent" ); 47b8851fccSafresh1 } 48898184e3Ssthen exit 1; 49898184e3Ssthen } 50898184e3Ssthen } 51898184e3Ssthen unless ($has_perlio = PerlIO::Layer->can("find") && PerlIO::Layer->find('perlio')) { 52898184e3Ssthen print <<EOF; 53898184e3Ssthen# Since you don't have perlio you might get failures with UTF-8 locales. 54898184e3SsthenEOF 55898184e3Ssthen } 56898184e3Ssthen} 57898184e3Ssthen 58898184e3Ssthenuse Socket; 59898184e3Ssthenuse Test::More; 60898184e3Ssthenuse strict; 61898184e3Ssthenuse warnings; 62898184e3Ssthenuse Errno; 63898184e3Ssthen 64898184e3Ssthenmy $skip_reason; 65898184e3Ssthen 66898184e3Ssthenif( !$Config{d_alarm} ) { 67898184e3Ssthen plan skip_all => "alarm() not implemented on this platform"; 68898184e3Ssthen} elsif( !$can_fork ) { 69898184e3Ssthen plan skip_all => "fork() not implemented on this platform"; 70898184e3Ssthen} else { 71*eac174f2Safresh1 my ($lefth, $righth); 72898184e3Ssthen # This should fail but not die if there is real socketpair 73*eac174f2Safresh1 eval {socketpair $lefth, $righth, -1, -1, -1}; 74898184e3Ssthen if ($@ =~ /^Unsupported socket function "socketpair" called/ || 75898184e3Ssthen $! =~ /^The operation requested is not supported./) { # Stratus VOS 76898184e3Ssthen plan skip_all => 'No socketpair (real or emulated)'; 77898184e3Ssthen } else { 78898184e3Ssthen eval {AF_UNIX}; 79898184e3Ssthen if ($@ =~ /^Your vendor has not defined Socket macro AF_UNIX/) { 80898184e3Ssthen plan skip_all => 'No AF_UNIX'; 81898184e3Ssthen } else { 82898184e3Ssthen plan tests => 45; 83898184e3Ssthen } 84898184e3Ssthen } 85898184e3Ssthen} 86898184e3Ssthen 87898184e3Ssthen# But we'll install an alarm handler in case any of the races below fail. 88898184e3Ssthen$SIG{ALRM} = sub {die "Unexpected alarm during testing"}; 89898184e3Ssthen 90898184e3Ssthenmy @left = ("hello ", "world\n"); 91898184e3Ssthenmy @right = ("perl ", "rules!"); # Not like I'm trying to bias any survey here. 92898184e3Ssthen 93*eac174f2Safresh1my @gripping = (chr 255, chr 127); 94*eac174f2Safresh1 95*eac174f2Safresh1{ 96*eac174f2Safresh1 my ($lefth, $righth); 97*eac174f2Safresh1 98*eac174f2Safresh1 ok (socketpair ($lefth, $righth, AF_UNIX, SOCK_STREAM, PF_UNSPEC), 99*eac174f2Safresh1 "socketpair (\$lefth, \$righth, AF_UNIX, SOCK_STREAM, PF_UNSPEC)") 100*eac174f2Safresh1 or print STDERR "# \$\! = $!\n"; 101*eac174f2Safresh1 102*eac174f2Safresh1 if ($has_perlio) { 103*eac174f2Safresh1 binmode($lefth, ":bytes"); 104*eac174f2Safresh1 binmode($righth, ":bytes"); 105*eac174f2Safresh1 } 106*eac174f2Safresh1 107898184e3Ssthen foreach (@left) { 108*eac174f2Safresh1 # is (syswrite ($lefth, $_), length $_, "write " . _qq ($_) . " to left"); 109*eac174f2Safresh1 is (syswrite ($lefth, $_), length $_, "syswrite to left"); 110898184e3Ssthen } 111898184e3Ssthen foreach (@right) { 112*eac174f2Safresh1 # is (syswrite ($righth, $_), length $_, "write " . _qq ($_) . " to right"); 113*eac174f2Safresh1 is (syswrite ($righth, $_), length $_, "syswrite to right"); 114898184e3Ssthen } 115898184e3Ssthen 116898184e3Ssthen # stream socket, so our writes will become joined: 117898184e3Ssthen my ($buffer, $expect); 118898184e3Ssthen $expect = join '', @right; 119898184e3Ssthen undef $buffer; 120*eac174f2Safresh1 is (read ($lefth, $buffer, length $expect), length $expect, "read on left"); 121898184e3Ssthen is ($buffer, $expect, "content what we expected?"); 122898184e3Ssthen $expect = join '', @left; 123898184e3Ssthen undef $buffer; 124*eac174f2Safresh1 is (read ($righth, $buffer, length $expect), length $expect, "read on right"); 125898184e3Ssthen is ($buffer, $expect, "content what we expected?"); 126898184e3Ssthen 127*eac174f2Safresh1 ok (shutdown($lefth, SHUT_WR), "shutdown left for writing"); 128898184e3Ssthen # This will hang forever if eof is buggy, and alarm doesn't interrupt system 129898184e3Ssthen # Calls. Hence the child process minder. 130898184e3Ssthen SKIP: { 131898184e3Ssthen skip "SCO Unixware / OSR have a bug with shutdown",2 if $^O =~ /^(?:svr|sco)/; 132898184e3Ssthen local $SIG{ALRM} = sub { warn "EOF on right took over 3 seconds" }; 133898184e3Ssthen local $TODO = "Known problems with unix sockets on $^O" 134898184e3Ssthen if $^O eq 'hpux' || $^O eq 'super-ux'; 135898184e3Ssthen alarm 3; 136898184e3Ssthen $! = 0; 137*eac174f2Safresh1 ok (eof $righth, "right is at EOF"); 138898184e3Ssthen local $TODO = "Known problems with unix sockets on $^O" 139898184e3Ssthen if $^O eq 'unicos' || $^O eq 'unicosmk'; 140898184e3Ssthen is ($!, '', 'and $! should report no error'); 141898184e3Ssthen alarm 60; 142898184e3Ssthen } 143898184e3Ssthen 144898184e3Ssthen my $err = $!; 145898184e3Ssthen $SIG{PIPE} = 'IGNORE'; 146898184e3Ssthen { 147898184e3Ssthen local $SIG{ALRM} = 148898184e3Ssthen sub { warn "syswrite to left didn't fail within 3 seconds" }; 149898184e3Ssthen alarm 3; 150898184e3Ssthen # Split the system call from the is() - is() does IO so 151898184e3Ssthen # (say) a flush may do a seek which on a pipe may disturb errno 152*eac174f2Safresh1 my $ans = syswrite ($lefth, "void"); 153898184e3Ssthen $err = $!; 154898184e3Ssthen is ($ans, undef, "syswrite to shutdown left should fail"); 155898184e3Ssthen alarm 60; 156898184e3Ssthen } 157898184e3Ssthen { 158898184e3Ssthen # This may need skipping on some OSes - restoring value saved above 159898184e3Ssthen # should help 160898184e3Ssthen $! = $err; 161898184e3Ssthen ok (($!{EPIPE} or $!{ESHUTDOWN}), '$! should be EPIPE or ESHUTDOWN') 1629f11ffb7Safresh1 or printf STDERR "# \$\! = %d (%s)\n", $err, $err; 163898184e3Ssthen } 164898184e3Ssthen 165898184e3Ssthen foreach (@gripping) { 166*eac174f2Safresh1 is (syswrite ($righth, $_), length $_, "syswrite to right"); 167898184e3Ssthen } 168898184e3Ssthen 169*eac174f2Safresh1 ok (!eof $lefth, "left is not at EOF"); 170898184e3Ssthen 171898184e3Ssthen $expect = join '', @gripping; 172898184e3Ssthen undef $buffer; 173*eac174f2Safresh1 is (read ($lefth, $buffer, length $expect), length $expect, "read on left"); 174898184e3Ssthen is ($buffer, $expect, "content what we expected?"); 175898184e3Ssthen 176*eac174f2Safresh1 ok (close $lefth, "close left"); 177*eac174f2Safresh1 ok (close $righth, "close right"); 178*eac174f2Safresh1} 179898184e3Ssthen 180898184e3Ssthen 181898184e3Ssthen# And now datagrams 182898184e3Ssthen# I suspect we also need a self destruct time-bomb for these, as I don't see any 183898184e3Ssthen# guarantee that the stack won't drop a UDP packet, even if it is for localhost. 184898184e3Ssthen 185898184e3SsthenSKIP: { 186898184e3Ssthen skip "alarm doesn't interrupt I/O on this Perl", 24 if "$]" < 5.008; 187*eac174f2Safresh1 188*eac174f2Safresh1 my $success = socketpair my $lefth, my $righth, AF_UNIX, SOCK_DGRAM, PF_UNSPEC; 189*eac174f2Safresh1 190*eac174f2Safresh1 skip "No useable SOCK_DGRAM for socketpair", 24 if !$success and 191*eac174f2Safresh1 ($!{EAFNOSUPPORT} or $!{EOPNOTSUPP} or $!{EPROTONOSUPPORT} or $!{EPROTOTYPE}); 192*eac174f2Safresh1 # Maybe this test is redundant now? 193*eac174f2Safresh1 skip "No usable SOCK_DGRAM for socketpair", 24 if ($^O =~ /^(MSWin32|os2)\z/); 194898184e3Ssthen local $TODO = "socketpair not supported on $^O" if $^O eq 'nto'; 195898184e3Ssthen 196*eac174f2Safresh1 ok ($success, "socketpair (\$left, \$righth, AF_UNIX, SOCK_DGRAM, PF_UNSPEC)") 1979f11ffb7Safresh1 or print STDERR "# \$\! = $!\n"; 198898184e3Ssthen 199898184e3Ssthen if ($has_perlio) { 200*eac174f2Safresh1 binmode($lefth, ":bytes"); 201*eac174f2Safresh1 binmode($righth, ":bytes"); 202898184e3Ssthen } 203898184e3Ssthen 204898184e3Ssthen foreach (@left) { 205*eac174f2Safresh1 # is (syswrite ($lefth, $_), length $_, "write " . _qq ($_) . " to left"); 206*eac174f2Safresh1 is (syswrite ($lefth, $_), length $_, "syswrite to left"); 207898184e3Ssthen } 208898184e3Ssthen foreach (@right) { 209*eac174f2Safresh1 # is (syswrite ($righth, $_), length $_, "write " . _qq ($_) . " to right"); 210*eac174f2Safresh1 is (syswrite ($righth, $_), length $_, "syswrite to right"); 211898184e3Ssthen } 212898184e3Ssthen 213898184e3Ssthen # stream socket, so our writes will become joined: 214*eac174f2Safresh1 my ($total, $buffer); 215898184e3Ssthen $total = join '', @right; 216*eac174f2Safresh1 foreach my $expect (@right) { 217898184e3Ssthen undef $buffer; 218*eac174f2Safresh1 is (sysread ($lefth, $buffer, length $total), length $expect, "read on left"); 219898184e3Ssthen is ($buffer, $expect, "content what we expected?"); 220898184e3Ssthen } 221898184e3Ssthen $total = join '', @left; 222*eac174f2Safresh1 foreach my $expect (@left) { 223898184e3Ssthen undef $buffer; 224*eac174f2Safresh1 is (sysread ($righth, $buffer, length $total), length $expect, "read on right"); 225898184e3Ssthen is ($buffer, $expect, "content what we expected?"); 226898184e3Ssthen } 227898184e3Ssthen 228*eac174f2Safresh1 ok (shutdown($lefth, 1), "shutdown left for writing"); 229898184e3Ssthen 230898184e3Ssthen # eof uses buffering. eof is indicated by a sysread of zero. 231898184e3Ssthen # but for a datagram socket there's no way it can know nothing will ever be 232898184e3Ssthen # sent 233898184e3Ssthen SKIP: { 234898184e3Ssthen skip "$^O does length 0 udp reads", 2 if ($^O eq 'os390'); 235898184e3Ssthen 236898184e3Ssthen my $alarmed = 0; 237898184e3Ssthen local $SIG{ALRM} = sub { $alarmed = 1; }; 238898184e3Ssthen print "# Approximate forever as 3 seconds. Wait 'forever'...\n"; 239898184e3Ssthen alarm 3; 240898184e3Ssthen undef $buffer; 241*eac174f2Safresh1 is (sysread ($righth, $buffer, 1), undef, 242898184e3Ssthen "read on right should be interrupted"); 243898184e3Ssthen is ($alarmed, 1, "alarm should have fired"); 244898184e3Ssthen } 245898184e3Ssthen 246898184e3Ssthen alarm 30; 247898184e3Ssthen 248898184e3Ssthen foreach (@gripping) { 249*eac174f2Safresh1 is (syswrite ($righth, $_), length $_, "syswrite to right"); 250898184e3Ssthen } 251898184e3Ssthen 252898184e3Ssthen $total = join '', @gripping; 253*eac174f2Safresh1 foreach my $expect (@gripping) { 254898184e3Ssthen undef $buffer; 255*eac174f2Safresh1 is (sysread ($lefth, $buffer, length $total), length $expect, "read on left"); 256898184e3Ssthen is ($buffer, $expect, "content what we expected?"); 257898184e3Ssthen } 258898184e3Ssthen 259*eac174f2Safresh1 ok (close $lefth, "close left"); 260*eac174f2Safresh1 ok (close $righth, "close right"); 261898184e3Ssthen 262898184e3Ssthen} # end of DGRAM SKIP 263898184e3Ssthen 264898184e3Ssthenkill "INT", $child or warn "Failed to kill child process $child: $!"; 265898184e3Ssthenexit 0; 266