1#!./perl 2 3BEGIN { 4 chdir 't' if -d 't'; 5 require './test.pl'; 6 set_up_inc('../lib'); 7} 8 9# Script to test auto flush on fork/exec/system/qx. The idea is to 10# print "Pe" to a file from a parent process and "rl" to the same file 11# from a child process. If buffers are flushed appropriately, the 12# file should contain "Perl". We'll see... 13use Config; 14use warnings; 15use strict; 16 17# This attempts to mirror the #ifdef forest found in perl.h so that we 18# know when to run these tests. If that forest ever changes, change 19# it here too or expect test gratuitous test failures. 20my $useperlio = defined $Config{useperlio} ? $Config{useperlio} eq 'define' ? 1 : 0 : 0; 21my $fflushNULL = defined $Config{fflushNULL} ? $Config{fflushNULL} eq 'define' ? 1 : 0 : 0; 22my $fflushall = defined $Config{fflushall} ? $Config{fflushall} eq 'define' ? 1 : 0 : 0; 23my $d_fork = defined $Config{d_fork} ? $Config{d_fork} eq 'define' ? 1 : 0 : 0; 24 25skip_all('fflush(NULL) or equivalent not available') 26 unless $useperlio || $fflushNULL || $fflushall; 27 28plan(tests => 7); 29 30my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X; 31$runperl .= qq{ "-I../lib"}; 32 33sub file_eq { 34 my $f = shift; 35 my $val = shift; 36 37 open IN, $f or die "open $f: $!"; 38 chomp(my $line = <IN>); 39 close IN; 40 41 print "# got $line\n"; 42 print "# expected $val\n"; 43 return $line eq $val; 44} 45 46# This script will be used as the command to execute from 47# child processes 48my $ffprog = tempfile(); 49open PROG, "> $ffprog" or die "open $ffprog: $!"; 50print PROG <<'EOF'; 51my $f = shift; 52my $str = shift; 53open OUT, ">> $f" or die "open $f: $!"; 54print OUT $str; 55close OUT; 56EOF 57 ; 58close PROG or die "close $ffprog: $!";; 59 60$| = 0; # we want buffered output 61 62# Test flush on fork/exec 63if (!$d_fork) { 64 print "ok 1 # skipped: no fork\n"; 65} else { 66 my $f = tempfile(); 67 open OUT, "> $f" or die "open $f: $!"; 68 print OUT "Pe"; 69 my $pid = fork; 70 if ($pid) { 71 # Parent 72 wait; 73 close OUT or die "close $f: $!"; 74 } elsif (defined $pid) { 75 # Kid 76 print OUT "r"; 77 my $command = qq{$runperl "$ffprog" "$f" "l"}; 78 print "# $command\n"; 79 exec $command or die $!; 80 exit; 81 } else { 82 # Bang 83 die "fork: $!"; 84 } 85 86 print file_eq($f, "Perl") ? "ok 1\n" : "not ok 1\n"; 87} 88 89# Test flush on system/qx/pipe open 90my %subs = ( 91 "system" => sub { 92 my $c = shift; 93 system $c; 94 }, 95 "qx" => sub { 96 my $c = shift; 97 qx{$c}; 98 }, 99 "popen" => sub { 100 my $c = shift; 101 open PIPE, "$c|" or die "$c: $!"; 102 close PIPE; 103 }, 104 ); 105my $t = 2; 106for (qw(system qx popen)) { 107 my $code = $subs{$_}; 108 my $f = tempfile(); 109 my $command = qq{$runperl $ffprog "$f" "rl"}; 110 open OUT, "> $f" or die "open $f: $!"; 111 print OUT "Pe"; 112 close OUT or die "close $f: $!";; 113 print "# $command\n"; 114 $code->($command); 115 print file_eq($f, "Perl") ? "ok $t\n" : "not ok $t\n"; 116 ++$t; 117} 118 119my $cmd = _create_runperl( 120 switches => ['-l'], 121 prog => 122 sprintf('print qq[ok $_] for (%d..%d)', $t, $t+2)); 123print "# cmd = '$cmd'\n"; 124open my $CMD, "$cmd |" or die "Can't open pipe to '$cmd': $!"; 125while (<$CMD>) { 126 system("$runperl -e 0"); 127 print; 128} 129close $CMD; 130$t += 3; 131curr_test($t); 132