1*0Sstevel@tonic-gateBEGIN { 2*0Sstevel@tonic-gate chdir 't' if -d 't'; 3*0Sstevel@tonic-gate unshift @INC, '../lib'; 4*0Sstevel@tonic-gate} 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gateBEGIN { 7*0Sstevel@tonic-gate use Config; 8*0Sstevel@tonic-gate unless ($Config{d_fork}) { 9*0Sstevel@tonic-gate print "1..0 # Skip: no fork\n"; 10*0Sstevel@tonic-gate exit 0; 11*0Sstevel@tonic-gate } 12*0Sstevel@tonic-gate eval 'use POSIX qw(sys_wait_h)'; 13*0Sstevel@tonic-gate if ($@) { 14*0Sstevel@tonic-gate print "1..0 # Skip: no POSIX sys_wait_h\n"; 15*0Sstevel@tonic-gate exit 0; 16*0Sstevel@tonic-gate } 17*0Sstevel@tonic-gate eval 'use Time::HiRes qw(time)'; 18*0Sstevel@tonic-gate if ($@) { 19*0Sstevel@tonic-gate print "1..0 # Skip: no Time::HiRes\n"; 20*0Sstevel@tonic-gate exit 0; 21*0Sstevel@tonic-gate } 22*0Sstevel@tonic-gate} 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gateuse warnings; 25*0Sstevel@tonic-gateuse strict; 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate$| = 1; 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gateprint "1..1\n"; 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gatesub NEG1_PROHIBITED () { 0x01 } 32*0Sstevel@tonic-gatesub NEG1_REQUIRED () { 0x02 } 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gatemy $count = 0; 35*0Sstevel@tonic-gatemy $max_count = 9; 36*0Sstevel@tonic-gatemy $state = NEG1_PROHIBITED; 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gatemy $child_pid = fork(); 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate# Parent receives a nonzero child PID. 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gateif ($child_pid) { 43*0Sstevel@tonic-gate my $ok = 1; 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate while ($count++ < $max_count) { 46*0Sstevel@tonic-gate my $begin_time = time(); 47*0Sstevel@tonic-gate my $ret = waitpid( -1, WNOHANG ); 48*0Sstevel@tonic-gate my $elapsed_time = time() - $begin_time; 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate printf( "# waitpid(-1,WNOHANG) returned %d after %.2f seconds\n", 51*0Sstevel@tonic-gate $ret, $elapsed_time ); 52*0Sstevel@tonic-gate if ($elapsed_time > 0.5) { 53*0Sstevel@tonic-gate printf( "# %.2f seconds in non-blocking waitpid is too long!\n", 54*0Sstevel@tonic-gate $elapsed_time ); 55*0Sstevel@tonic-gate $ok = 0; 56*0Sstevel@tonic-gate last; 57*0Sstevel@tonic-gate } 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate if ($state & NEG1_PROHIBITED) { 60*0Sstevel@tonic-gate if ($ret == -1) { 61*0Sstevel@tonic-gate print "# waitpid should not have returned -1 here!\n"; 62*0Sstevel@tonic-gate $ok = 0; 63*0Sstevel@tonic-gate last; 64*0Sstevel@tonic-gate } 65*0Sstevel@tonic-gate elsif ($ret == $child_pid) { 66*0Sstevel@tonic-gate $state = NEG1_REQUIRED; 67*0Sstevel@tonic-gate } 68*0Sstevel@tonic-gate } 69*0Sstevel@tonic-gate elsif ($state & NEG1_REQUIRED) { 70*0Sstevel@tonic-gate unless ($ret == -1) { 71*0Sstevel@tonic-gate print "# waitpid should have returned -1 here\n"; 72*0Sstevel@tonic-gate $ok = 0; 73*0Sstevel@tonic-gate } 74*0Sstevel@tonic-gate last; 75*0Sstevel@tonic-gate } 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate sleep(1); 78*0Sstevel@tonic-gate } 79*0Sstevel@tonic-gate print $ok ? "ok 1\n" : "not ok 1\n"; 80*0Sstevel@tonic-gate exit(0); # parent 81*0Sstevel@tonic-gate} else { 82*0Sstevel@tonic-gate # Child receives a zero PID and can request parent's PID with 83*0Sstevel@tonic-gate # getppid(). 84*0Sstevel@tonic-gate sleep(3); 85*0Sstevel@tonic-gate exit(0); 86*0Sstevel@tonic-gate} 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate 89