This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Capitalise magic descriptions consistently
[perl5.git] / t / io / fflush.t
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 $fflushall = defined $Config{fflushall} ? $Config{fflushall} eq 'define' ? 1 : 0 : 0;
23 my $d_fork = defined $Config{d_fork} ? $Config{d_fork} eq 'define' ? 1 : 0 : 0;
24
25 skip_all('fflush(NULL) or equivalent not available')
26     unless $useperlio || $fflushNULL || $fflushall;
27
28 plan(tests => 7);
29
30 my $runperl = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
31 $runperl .= qq{ "-I../lib"};
32
33 sub 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
48 my $ffprog = tempfile();
49 open PROG, "> $ffprog" or die "open $ffprog: $!";
50 print PROG <<'EOF';
51 my $f = shift;
52 my $str = shift;
53 open OUT, ">> $f" or die "open $f: $!";
54 print OUT $str;
55 close OUT;
56 EOF
57     ;
58 close PROG or die "close $ffprog: $!";;
59
60 $| = 0; # we want buffered output
61
62 # Test flush on fork/exec
63 if (!$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
90 my %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             );
105 my $t = 2;
106 for (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
119 my $cmd = _create_runperl(
120                           switches => ['-l'],
121                           prog =>
122                           sprintf('print qq[ok $_] for (%d..%d)', $t, $t+2));
123 print "# cmd = '$cmd'\n";
124 open my $CMD, "$cmd |" or die "Can't open pipe to '$cmd': $!";
125 while (<$CMD>) {
126     system("$runperl -e 0");
127     print;
128 }
129 close $CMD;
130 $t += 3;
131 curr_test($t);