| 1 | #!./perl
|
|---|
| 2 |
|
|---|
| 3 | BEGIN {
|
|---|
| 4 | chdir 't' if -d 't';
|
|---|
| 5 | @INC = '../lib';
|
|---|
| 6 | require './test.pl';
|
|---|
| 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...
|
|---|
| 13 | use Config;
|
|---|
| 14 | use warnings;
|
|---|
| 15 | use 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.
|
|---|
| 20 | my $useperlio = defined $Config{useperlio} ? $Config{useperlio} eq 'define' ? 1 : 0 : 0;
|
|---|
| 21 | my $fflushNULL = defined $Config{fflushNULL} ? $Config{fflushNULL} eq 'define' ? 1 : 0 : 0;
|
|---|
| 22 | my $d_sfio = defined $Config{d_sfio} ? $Config{d_sfio} eq 'define' ? 1 : 0 : 0;
|
|---|
| 23 | my $fflushall = defined $Config{fflushall} ? $Config{fflushall} eq 'define' ? 1 : 0 : 0;
|
|---|
| 24 | my $d_fork = defined $Config{d_fork} ? $Config{d_fork} eq 'define' ? 1 : 0 : 0;
|
|---|
| 25 |
|
|---|
| 26 | if ($useperlio || $fflushNULL || $d_sfio) {
|
|---|
| 27 | print "1..7\n";
|
|---|
| 28 | } else {
|
|---|
| 29 | if ($fflushall) {
|
|---|
| 30 | print "1..7\n";
|
|---|
| 31 | } else {
|
|---|
| 32 | print "1..0 # Skip: fflush(NULL) or equivalent not available\n";
|
|---|
| 33 | exit;
|
|---|
| 34 | }
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
|
|---|
| 38 | $runperl .= qq{ "-I../lib"};
|
|---|
| 39 |
|
|---|
| 40 | my @delete;
|
|---|
| 41 |
|
|---|
| 42 | END {
|
|---|
| 43 | for (@delete) {
|
|---|
| 44 | unlink $_ or warn "unlink $_: $!";
|
|---|
| 45 | }
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | sub file_eq {
|
|---|
| 49 | my $f = shift;
|
|---|
| 50 | my $val = shift;
|
|---|
| 51 |
|
|---|
| 52 | open IN, $f or die "open $f: $!";
|
|---|
| 53 | chomp(my $line = <IN>);
|
|---|
| 54 | close IN;
|
|---|
| 55 |
|
|---|
| 56 | print "# got $line\n";
|
|---|
| 57 | print "# expected $val\n";
|
|---|
| 58 | return $line eq $val;
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | # This script will be used as the command to execute from
|
|---|
| 62 | # child processes
|
|---|
| 63 | open PROG, "> ff-prog" or die "open ff-prog: $!";
|
|---|
| 64 | print PROG <<'EOF';
|
|---|
| 65 | my $f = shift;
|
|---|
| 66 | my $str = shift;
|
|---|
| 67 | open OUT, ">> $f" or die "open $f: $!";
|
|---|
| 68 | print OUT $str;
|
|---|
| 69 | close OUT;
|
|---|
| 70 | EOF
|
|---|
| 71 | ;
|
|---|
| 72 | close PROG or die "close ff-prog: $!";;
|
|---|
| 73 | push @delete, "ff-prog";
|
|---|
| 74 |
|
|---|
| 75 | $| = 0; # we want buffered output
|
|---|
| 76 |
|
|---|
| 77 | # Test flush on fork/exec
|
|---|
| 78 | if (!$d_fork) {
|
|---|
| 79 | print "ok 1 # skipped: no fork\n";
|
|---|
| 80 | } else {
|
|---|
| 81 | my $f = "ff-fork-$$";
|
|---|
| 82 | open OUT, "> $f" or die "open $f: $!";
|
|---|
| 83 | print OUT "Pe";
|
|---|
| 84 | my $pid = fork;
|
|---|
| 85 | if ($pid) {
|
|---|
| 86 | # Parent
|
|---|
| 87 | wait;
|
|---|
| 88 | close OUT or die "close $f: $!";
|
|---|
| 89 | } elsif (defined $pid) {
|
|---|
| 90 | # Kid
|
|---|
| 91 | print OUT "r";
|
|---|
| 92 | my $command = qq{$runperl "ff-prog" "$f" "l"};
|
|---|
| 93 | print "# $command\n";
|
|---|
| 94 | exec $command or die $!;
|
|---|
| 95 | exit;
|
|---|
| 96 | } else {
|
|---|
| 97 | # Bang
|
|---|
| 98 | die "fork: $!";
|
|---|
| 99 | }
|
|---|
| 100 |
|
|---|
| 101 | print file_eq($f, "Perl") ? "ok 1\n" : "not ok 1\n";
|
|---|
| 102 | push @delete, $f;
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | # Test flush on system/qx/pipe open
|
|---|
| 106 | my %subs = (
|
|---|
| 107 | "system" => sub {
|
|---|
| 108 | my $c = shift;
|
|---|
| 109 | system $c;
|
|---|
| 110 | },
|
|---|
| 111 | "qx" => sub {
|
|---|
| 112 | my $c = shift;
|
|---|
| 113 | qx{$c};
|
|---|
| 114 | },
|
|---|
| 115 | "popen" => sub {
|
|---|
| 116 | my $c = shift;
|
|---|
| 117 | open PIPE, "$c|" or die "$c: $!";
|
|---|
| 118 | close PIPE;
|
|---|
| 119 | },
|
|---|
| 120 | );
|
|---|
| 121 | my $t = 2;
|
|---|
| 122 | for (qw(system qx popen)) {
|
|---|
| 123 | my $code = $subs{$_};
|
|---|
| 124 | my $f = "ff-$_-$$";
|
|---|
| 125 | my $command = qq{$runperl "ff-prog" "$f" "rl"};
|
|---|
| 126 | open OUT, "> $f" or die "open $f: $!";
|
|---|
| 127 | print OUT "Pe";
|
|---|
| 128 | close OUT or die "close $f: $!";;
|
|---|
| 129 | print "# $command\n";
|
|---|
| 130 | $code->($command);
|
|---|
| 131 | print file_eq($f, "Perl") ? "ok $t\n" : "not ok $t\n";
|
|---|
| 132 | push @delete, $f;
|
|---|
| 133 | ++$t;
|
|---|
| 134 | }
|
|---|
| 135 |
|
|---|
| 136 | my $cmd = _create_runperl(
|
|---|
| 137 | switches => ['-l'],
|
|---|
| 138 | prog =>
|
|---|
| 139 | sprintf('print qq[ok $_] for (%d..%d)', $t, $t+2));
|
|---|
| 140 | print "# cmd = '$cmd'\n";
|
|---|
| 141 | open my $CMD, "$cmd |" or die "Can't open pipe to '$cmd': $!";
|
|---|
| 142 | while (<$CMD>) {
|
|---|
| 143 | system("$runperl -e 0");
|
|---|
| 144 | print;
|
|---|
| 145 | }
|
|---|
| 146 | close $CMD;
|
|---|
| 147 | $t += 3;
|
|---|