xref: /openbsd/gnu/usr.bin/perl/t/io/fflush.t (revision 5759b3d2)
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