#!./perl
BEGIN {
chdir
't'
if
-d
't'
;
@INC
=
'../lib'
;
require
'./test.pl'
;
skip_all_without_config(
'd_fcntl'
);
}
$|=1;
skip_all($^O)
if
$^O eq
'VMS'
or $^O eq
'MSWin32'
or $^O eq
'amigaos'
;
sub
make_tmp_file {
my
(
$fname
,
$fcontents
) =
@_
;
local
*FHTMP
;
open
FHTMP,
">$fname"
or
die
"open '$fname': $!"
;
print
FHTMP
$fcontents
or
die
"print '$fname': $!"
;
close
FHTMP or
die
"close '$fname': $!"
;
}
my
$Perl
= which_perl();
my
$quote
=
"'"
;
my
$tmperr
= tempfile();
my
$tmpfile1
= tempfile();
my
$tmpfile2
= tempfile();
my
$tmpfile1_contents
=
"tmpfile1 line 1\ntmpfile1 line 2\n"
;
my
$tmpfile2_contents
=
"tmpfile2 line 1\ntmpfile2 line 2\n"
;
make_tmp_file(
$tmpfile1
,
$tmpfile1_contents
);
make_tmp_file(
$tmpfile2
,
$tmpfile2_contents
);
my
$Child_prog
=
<<'CHILD_PROG';
my $fd = shift;
print qq{childfd=$fd\n};
open INHERIT, qq{<&=$fd} or die qq{open $fd: $!};
my $line = <INHERIT>;
close INHERIT or die qq{close $fd: $!};
print $line
CHILD_PROG
$Child_prog
=~
tr
/\n//d;
plan(
tests
=> 22);
sub
test_not_inherited {
my
$expected_fd
=
shift
;
ok( -f
$tmpfile2
,
"tmpfile '$tmpfile2' exists"
);
my
$cmd
=
qq{$Perl -e $quote$Child_prog$quote $expected_fd}
;
local
*SAVERR
;
open
SAVERR,
">&STDERR"
;
open
STDERR,
">$tmperr"
or
die
"open '$tmperr': $!"
;
my
$out
= `
$cmd
`;
my
$rc
= $? >> 8;
open
STDERR,
">&SAVERR"
or
die
"error: restore STDERR: $!"
;
close
SAVERR or
die
"error: close SAVERR: $!"
;
cmp_ok(
$out
=~
tr
/\n//,
'=='
, 1,
"child stdout: has 1 newline (rc=$rc, should be non-zero)"
);
is(
$out
,
"childfd=$expected_fd\n"
,
'child stdout: fd'
);
}
sub
test_inherited {
my
$expected_fd
=
shift
;
ok( -f
$tmpfile1
,
"tmpfile '$tmpfile1' exists"
);
my
$cmd
=
qq{$Perl -e $quote$Child_prog$quote $expected_fd}
;
my
$out
= `
$cmd
`;
my
$rc
= $? >> 8;
cmp_ok(
$rc
,
'=='
, 0,
"child return code=$rc (zero means inherited fd=$expected_fd ok)"
);
my
@lines
=
split
(/^/,
$out
);
cmp_ok(
$out
=~
tr
/\n//,
'=='
, 2,
'child stdout: has 2 newlines'
);
cmp_ok(
scalar
(
@lines
),
'=='
, 2,
'child stdout: split into 2 lines'
);
is(
$lines
[0],
"childfd=$expected_fd\n"
,
'child stdout: fd'
);
is(
$lines
[1],
"tmpfile1 line 1\n"
,
'child stdout: line 1'
);
}
$^F == 2 or
print
STDERR
"# warning: \$^F is $^F (not 2)\n"
;
open
FHPARENT2,
"<$tmpfile2"
or
die
"open '$tmpfile2': $!"
;
my
$parentfd2
=
fileno
FHPARENT2;
defined
$parentfd2
or
die
"fileno: $!"
;
cmp_ok(
$parentfd2
,
'>'
, $^F,
"parent open fd=$parentfd2 (\$^F=$^F)"
);
test_not_inherited(
$parentfd2
);
close
FHPARENT2 or
die
"close '$tmpfile2': $!"
;
$^F =
$parentfd2
;
open
FHPARENT1,
"<$tmpfile1"
or
die
"open '$tmpfile1': $!"
;
my
$parentfd1
=
fileno
FHPARENT1;
defined
$parentfd1
or
die
"fileno: $!"
;
cmp_ok(
$parentfd1
,
'<='
, $^F,
"parent open fd=$parentfd1 (\$^F=$^F)"
);
test_inherited(
$parentfd1
);
close
FHPARENT1 or
die
"close '$tmpfile1': $!"
;
open
FHPARENT1,
"<$tmpfile1"
or
die
"open '$tmpfile1': $!"
;
open
FHPARENT2,
"<$tmpfile2"
or
die
"open '$tmpfile2': $!"
;
$parentfd2
=
fileno
FHPARENT2;
defined
$parentfd2
or
die
"fileno: $!"
;
cmp_ok(
$parentfd2
,
'>'
, $^F,
"parent open fd=$parentfd2 (\$^F=$^F)"
);
test_not_inherited(
$parentfd2
);
close
FHPARENT2 or
die
"close '$tmpfile2': $!"
;
close
FHPARENT1 or
die
"close '$tmpfile1': $!"
;
$^F =
$parentfd2
;
open
FHPARENT2,
"<$tmpfile2"
or
die
"open '$tmpfile2': $!"
;
open
FHPARENT1,
"<$tmpfile1"
or
die
"open '$tmpfile1': $!"
;
$parentfd1
=
fileno
FHPARENT1;
defined
$parentfd1
or
die
"fileno: $!"
;
cmp_ok(
$parentfd1
,
'<='
, $^F,
"parent open fd=$parentfd1 (\$^F=$^F)"
);
test_inherited(
$parentfd1
);
close
FHPARENT1 or
die
"close '$tmpfile1': $!"
;
close
FHPARENT2 or
die
"close '$tmpfile2': $!"
;