summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Zakharevich <ilya@math.berkeley.edu>2006-12-12 15:28:25 -0800
committerSteve Peters <steve@fisharerojo.org>2006-12-13 19:53:02 +0000
commit713cef20be507239588df9cdc5f99ce04b7e0b40 (patch)
tree00549fe2cfdf237bcf2e21de1c56a041f532ad4c
parent4d28fe79573bb61e3777837866812631f24ed631 (diff)
downloadperl-713cef20be507239588df9cdc5f99ce04b7e0b40.tar.gz
Text mode wrongly set on pipe file descriptors
Message-ID: <20061213072825.GA26300@powdermilk.math.berkeley.edu> p4raw-id: //depot/perl@29550
-rwxr-xr-xt/io/pipe.t47
-rw-r--r--util.c8
2 files changed, 53 insertions, 2 deletions
diff --git a/t/io/pipe.t b/t/io/pipe.t
index d411719fff..68e910028c 100755
--- a/t/io/pipe.t
+++ b/t/io/pipe.t
@@ -10,7 +10,7 @@ BEGIN {
skip_all("fork required to pipe");
}
else {
- plan(tests => 22);
+ plan(tests => 24);
}
}
@@ -30,7 +30,7 @@ close PIPE;
SKIP: {
# Technically this should be TODO. Someone try it if you happen to
# have a vmesa machine.
- skip "Doesn't work here yet", 4 if $^O eq 'vmesa';
+ skip "Doesn't work here yet", 6 if $^O eq 'vmesa';
if (open(PIPE, "-|")) {
while(<PIPE>) {
@@ -50,6 +50,49 @@ SKIP: {
# This has to be *outside* the fork
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; # avoid zombies
+ }
+ else {
+ printf STDOUT "not ok %d - $raw", curr_test();
+ exec $Perl, '-e0'; # Do not run END()...
+ }
+
+ # This has to be *outside* the fork
+ next_test();
+
+ if (open(PIPE, "|-")) {
+ printf PIPE "not ok %d - $raw", curr_test();
+ close PIPE; # avoid zombies
+ }
+ 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'; # Do not run END()...
+ }
+
+ # This has to be *outside* the fork
+ next_test();
+
SKIP: {
skip "fork required", 2 unless $Config{d_fork};
diff --git a/util.c b/util.c
index 8dfe417f5e..c5f69ae291 100644
--- a/util.c
+++ b/util.c
@@ -2356,6 +2356,14 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode)
PerlProc__exit(1);
}
#endif /* defined OS2 */
+
+#ifdef PERLIO_USING_CRLF
+ /* Since we circumvent IO layers when we manipulate low-level
+ filedescriptors directly, need to manually switch to the
+ default, binary, low-level mode; see PerlIOBuf_open(). */
+ PerlLIO_setmode((*mode == 'r'), O_BINARY);
+#endif
+
if ((tmpgv = gv_fetchpvs("$", GV_ADD|GV_NOTQUAL, SVt_PV))) {
SvREADONLY_off(GvSV(tmpgv));
sv_setiv(GvSV(tmpgv), PerlProc_getpid());