5 require Config; import Config;
9 if (!$Config{'d_fork'}) {
10 skip_all("fork required to pipe");
16 my $Perl = which_perl();
21 open(PIPE, "|-") || exec $Perl, '-pe', 'tr/YX/ko/';
23 printf PIPE "Xk %d - open |- || exec\n", curr_test();
25 printf PIPE "oY %d - again\n", curr_test();
30 if (open(PIPE, "-|")) {
35 close PIPE; # avoid zombies
38 printf STDOUT "not ok %d - open -|\n", curr_test();
42 exec $Perl, '-le', "print q{not ok $tnum - again}";
45 # This has to be *outside* the fork
48 my $raw = "abc\nrst\rxyz\r\nfoo\n";
49 if (open(PIPE, "-|")) {
51 (my $raw1 = $_) =~ s/not ok \d+ - //;
52 my @r = map ord, split //, $raw;
53 my @r1 = map ord, split //, $raw1;
55 s/^not (ok \d+ -) .*/$1 '@r1' passes through '-|'\n/s;
57 s/^(not ok \d+ -) .*/$1 expect '@r', got '@r1'\n/s;
60 close PIPE; # avoid zombies
63 printf STDOUT "not ok %d - $raw", curr_test();
64 exec $Perl, '-e0'; # Do not run END()...
67 # This has to be *outside* the fork
70 if (open(PIPE, "|-")) {
71 printf PIPE "not ok %d - $raw", curr_test();
72 close PIPE; # avoid zombies
75 $_ = join '', <STDIN>;
76 (my $raw1 = $_) =~ s/not ok \d+ - //;
77 my @r = map ord, split //, $raw;
78 my @r1 = map ord, split //, $raw1;
80 s/^not (ok \d+ -) .*/$1 '@r1' passes through '|-'\n/s;
82 s/^(not ok \d+ -) .*/$1 expect '@r', got '@r1'\n/s;
85 exec $Perl, '-e0'; # Do not run END()...
88 # This has to be *outside* the fork
92 skip "fork required", 2 unless $Config{d_fork};
94 pipe(READER,WRITER) || die "Can't open pipe";
103 close READER; # avoid zombies
106 die "Couldn't fork" unless defined $pid;
108 printf WRITER "not ok %d - pipe & fork\n", curr_test;
111 open(STDOUT,">&WRITER") || die "Can't dup WRITER to STDOUT";
114 my $tnum = curr_test;
116 exec $Perl, '-le', "print q{not ok $tnum - with fh dup }";
119 # This has to be done *outside* the fork.
120 next_test() for 1..2;
123 wait; # Collect from $pid
125 pipe(READER,WRITER) || die "Can't open pipe";
128 $SIG{'PIPE'} = 'broken_pipe';
131 $SIG{'PIPE'} = 'IGNORE'; # loop preventer
132 printf "ok %d - SIGPIPE\n", curr_test;
135 printf WRITER "not ok %d - SIGPIPE\n", curr_test;
142 skip "no fcntl", 1 unless $Config{d_fcntl};
144 pipe($r, $w) || die "pipe: $!";
145 my $fdr = fileno($r);
146 my $fdw = fileno($w);
148 print open(F, "<&=$fdr") ? 1 : 0, "\\n";
149 print open(F, ">&=$fdw") ? 1 : 0, "\\n";
150 ), "0\n0\n", {}, "pipe endpoints not inherited across exec");
153 # VMS doesn't like spawning subprocesses that are still connected to
154 # STDOUT. Someone should modify these tests to work with VMS.
157 skip "doesn't like spawning subprocesses that are still connected", 10
161 # POSIX-BC doesn't report failure when closing a broken pipe
162 # that has pending output. Go figure.
163 skip "Won't report failure on broken pipe", 1
164 if $^O eq 'posix-bc';
166 local $SIG{PIPE} = 'IGNORE';
167 open NIL, qq{|$Perl -e "exit 0"} or die "open failed: $!";
169 if (print NIL 'foo') {
170 # If print was allowed we had better get an error on close
171 ok( !close NIL, 'close error on broken pipe' );
174 ok(close NIL, 'print failed on broken pipe');
179 # check that errno gets forced to 0 if the piped program exited
181 open NIL, qq{|$Perl -e "exit 23";} or die "fork failed: $!";
183 ok(!close NIL, 'close failure on non-zero piped exit');
184 is($!, '', ' errno');
185 isnt($?, 0, ' status');
189 # check that status for the correct process is collected
191 unless( $zombie = fork ) {
195 my $pipe = open *FH, "sleep 2;exit 13|" or die "Open: $!\n";
196 $SIG{ALRM} = sub { return };
198 is( close FH, '', 'close failure for... umm, something' );
199 is( $?, 13*256, ' status' );
200 is( $!, '', ' errno');
203 is( $?, 37*256, 'status correct after wait' );
204 is( $wait, $zombie, ' wait pid' );
205 is( $!, '', ' errno');
210 # Test new semantics for missing command in piped open
211 # 19990114 M-J. Dominus mjd@plover.com
214 ok( !open(P, "| "), 'missing command in piped open input' );
215 ok( !open(P, " |"), ' output');
218 # check that status is unaffected by implicit close
221 open NIL, qq{|$Perl -e "exit 23"} or die "fork failed: $!";
223 # NIL implicitly closed here
225 is($?, 42, 'status unaffected by implicit close');
228 # check that child is reaped if the piped program can't be executed
230 skip "/no_such_process exists", 1 if -e "/no_such_process";
231 open NIL, '/no_such_process |';
236 local $SIG{ALRM} = sub { die; };
242 is($child, -1, 'child reaped if piped program cannot be executed');
246 # [perl #122112] refcnt: fd -1 < 0 when a signal handler dies
247 # while a pipe close is waiting on a child process
249 \$SIG{ALRM}=sub{die};
252 my \$cmd = qq(\$Perl -e "sleep 3");
253 my \$pid = open my \$fh, "|\$cmd" or die "\$!\n";
257 my $out = fresh_perl($prog, {});
258 cmp_ok($out, '!~', qr/refcnt/, "no exception from PerlIO");
259 # checks that that program did something rather than failing to
261 cmp_ok($out, '=~', qr/Died at/, "but we did get the exception from die");