#!./perl
BEGIN {
chdir
't'
if
-d
't'
;
require
'./test.pl'
;
set_up_inc(
'../lib'
);
require
Config; Config->
import
;
}
if
(!
$Config
{
'd_fork'
}) {
skip_all(
"fork required to pipe"
);
}
else
{
plan(
tests
=> 27);
}
my
$Perl
= which_perl();
$| = 1;
open
(PIPE,
"|-"
) ||
exec
$Perl
,
'-pe'
,
'tr/YX/ko/'
;
printf
PIPE
"Xk %d - open |- || exec\n"
, curr_test();
next_test();
printf
PIPE
"oY %d - again\n"
, curr_test();
next_test();
close
PIPE;
{
if
(
open
(PIPE,
"-|"
)) {
while
(<PIPE>) {
s/^not //;
print
;
}
close
PIPE;
}
else
{
printf
STDOUT
"not ok %d - open -|\n"
, curr_test();
next_test();
my
$tnum
= curr_test;
next_test();
exec
$Perl
,
'-le'
,
"print q{not ok $tnum - again}"
;
}
next_test()
for
1..2;
my
$raw
=
"abc\nrst\rxyz\r\nfoo\n"
;
if
(
open
(PIPE,
"-|"
)) {
$_
=
join
''
, <PIPE>;
(
my
$raw1
=
$_
) =~ s/not ok \d+ - //;
my
@r
=
map
ord
,
split
//,
$raw
;
my
@r1
=
map
ord
,
split
//,
$raw1
;
if
(
$raw1
eq
$raw
) {
s/^not (ok \d+ -) .*/$1
'@r1'
passes through
'-|'
\n/s;
}
else
{
s/^(not ok \d+ -) .*/$1 expect
'@r'
, got
'@r1'
\n/s;
}
print
;
close
PIPE;
}
else
{
printf
STDOUT
"not ok %d - $raw"
, curr_test();
exec
$Perl
,
'-e0'
;
}
next_test();
if
(
open
(PIPE,
"|-"
)) {
printf
PIPE
"not ok %d - $raw"
, curr_test();
close
PIPE;
}
else
{
$_
=
join
''
, <STDIN>;
(
my
$raw1
=
$_
) =~ s/not ok \d+ - //;
my
@r
=
map
ord
,
split
//,
$raw
;
my
@r1
=
map
ord
,
split
//,
$raw1
;
if
(
$raw1
eq
$raw
) {
s/^not (ok \d+ -) .*/$1
'@r1'
passes through
'|-'
\n/s;
}
else
{
s/^(not ok \d+ -) .*/$1 expect
'@r'
, got
'@r1'
\n/s;
}
print
;
exec
$Perl
,
'-e0'
;
}
next_test();
SKIP: {
skip
"fork required"
, 2
unless
$Config
{d_fork};
pipe
(READER,WRITER) ||
die
"Can't open pipe"
;
if
(
$pid
=
fork
) {
close
WRITER;
while
(<READER>) {
s/^not //;
y/A-Z/a-z/;
print
;
}
close
READER;
}
else
{
die
"Couldn't fork"
unless
defined
$pid
;
close
READER;
printf
WRITER
"not ok %d - pipe & fork\n"
, curr_test;
next_test;
open
(STDOUT,
">&WRITER"
) ||
die
"Can't dup WRITER to STDOUT"
;
close
WRITER;
my
$tnum
= curr_test;
next_test;
exec
$Perl
,
'-le'
,
"print q{not ok $tnum - with fh dup }"
;
}
next_test()
for
1..2;
}
}
wait
;
pipe
(READER,WRITER) ||
die
"Can't open pipe"
;
close
READER;
eval
{
my
$mask
= POSIX::SigSet->new(POSIX::SIGPIPE());
my
$old
= POSIX::SigSet->new();
POSIX::sigprocmask(POSIX::SIG_UNBLOCK(),
$mask
,
$old
);
note
"Yes, SIGPIPE was blocked"
if
$old
->ismember(POSIX::SIGPIPE());
};
$SIG
{
'PIPE'
} =
'broken_pipe'
;
sub
broken_pipe {
$SIG
{
'PIPE'
} =
'IGNORE'
;
printf
"ok %d - SIGPIPE\n"
, curr_test;
}
printf
WRITER
"not ok %d - SIGPIPE\n"
, curr_test;
close
WRITER;
sleep
1;
next_test;
pass();
SKIP: {
skip
"no fcntl"
, 1
unless
$Config
{d_fcntl};
my
(
$r
,
$w
);
pipe
(
$r
,
$w
) ||
die
"pipe: $!"
;
my
$fdr
=
fileno
(
$r
);
my
$fdw
=
fileno
(
$w
);
fresh_perl_is(
qq(
print open(F, "<&=$fdr")
? 1 : 0,
"\\n"
;
print
open
(F,
">&=$fdw"
) ? 1 : 0,
"\\n"
;
),
"0\n0\n"
, {},
"pipe endpoints not inherited across exec"
);
}
SKIP: {
skip
"doesn't like spawning subprocesses that are still connected"
, 10
if
$^O eq
'VMS'
;
SKIP: {
skip
"Won't report failure on broken pipe"
, 1
if
$^O eq
'posix-bc'
;
local
$SIG
{PIPE} =
'IGNORE'
;
open
NIL,
qq{|$Perl -e "exit 0"}
or
die
"open failed: $!"
;
sleep
5;
if
(
print
NIL
'foo'
) {
ok( !
close
NIL,
'close error on broken pipe'
);
}
else
{
ok(
close
NIL,
'print failed on broken pipe'
);
}
}
{
open
NIL,
qq{|$Perl -e "exit 23";}
or
die
"fork failed: $!"
;
$! = 1;
ok(!
close
NIL,
'close failure on non-zero piped exit'
);
is($!,
''
,
' errno'
);
isnt($?, 0,
' status'
);
{
my
$zombie
;
unless
(
$zombie
=
fork
) {
$NO_ENDING
=1;
exit
37;
}
my
$pipe
=
open
*FH
,
"sleep 2;exit 13|"
or
die
"Open: $!\n"
;
$SIG
{ALRM} =
sub
{
return
};
alarm
(1);
is(
close
FH,
''
,
'close failure for... umm, something'
);
is( $?, 13*256,
' status'
);
is( $!,
''
,
' errno'
);
my
$wait
=
wait
;
is( $?, 37*256,
'status correct after wait'
);
is(
$wait
,
$zombie
,
' wait pid'
);
is( $!,
''
,
' errno'
);
}
}
}
{
local
*P
;
no
warnings
'pipe'
;
ok( !
open
(P,
"| "
),
'missing command in piped open input'
);
ok( !
open
(P,
" |"
),
' output'
);
}
{
local
(
*NIL
);
open
NIL,
qq{|$Perl -e "exit 23"}
or
die
"fork failed: $!"
;
$? = 42;
}
is($?, 42,
'status unaffected by implicit close'
);
$? = 0;
SKIP: {
skip
"/no_such_process exists"
, 1
if
-e
"/no_such_process"
;
open
NIL,
'/no_such_process |'
;
close
NIL;
my
$child
= 0;
eval
{
local
$SIG
{ALRM} =
sub
{
die
; };
alarm
2;
$child
=
wait
;
alarm
0;
};
is(
$child
, -1,
'child reaped if piped program cannot be executed'
);
}
{
my
$prog
=
<<PROG;
\$SIG{ALRM}=sub{die};
alarm 1;
\$Perl = "$Perl";
my \$cmd = qq(\$Perl -e "sleep 3");
my \$pid = open my \$fh, "|\$cmd" or die "\$!\n";
close \$fh;
PROG
my
$out
= fresh_perl(
$prog
, {});
cmp_ok(
$out
,
'!~'
,
qr/refcnt/
,
"no exception from PerlIO"
);
cmp_ok(
$out
,
'=~'
,
qr/Died at/
,
"but we did get the exception from die"
);
}