summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doio.c6
-rwxr-xr-xt/op/misc.t10
2 files changed, 15 insertions, 1 deletions
diff --git a/doio.c b/doio.c
index de0cdee95b..cc038e26cc 100644
--- a/doio.c
+++ b/doio.c
@@ -92,6 +92,7 @@ do_open(GV *gv, register char *name, I32 len, int as_raw, int rawmode, int rawpe
PerlIO *fp;
int fd;
int result;
+ bool was_fdopen = FALSE;
forkprocess = 1; /* assume true if no fork */
@@ -221,6 +222,8 @@ do_open(GV *gv, register char *name, I32 len, int as_raw, int rawmode, int rawpe
}
if (dodup)
fd = PerlLIO_dup(fd);
+ else
+ was_fdopen = TRUE;
if (!(fp = PerlIO_fdopen(fd,mode))) {
if (dodup)
PerlLIO_close(fd);
@@ -330,7 +333,8 @@ do_open(GV *gv, register char *name, I32 len, int as_raw, int rawmode, int rawpe
sv = *av_fetch(fdpid,fd,TRUE);
(void)SvUPGRADE(sv, SVt_IV);
SvIVX(sv) = pid;
- PerlIO_close(fp);
+ if (!was_fdopen)
+ PerlIO_close(fp);
}
fp = saveifp;
diff --git a/t/op/misc.t b/t/op/misc.t
index 1ca45db039..40c9c38825 100755
--- a/t/op/misc.t
+++ b/t/op/misc.t
@@ -358,3 +358,13 @@ init <b>
end <c>
argv <>
########
+-l
+# fdopen from a system descriptor to a system descriptor used to close
+# the former.
+open STDERR, '>&=STDOUT' or die $!;
+select STDOUT; $| = 1; print fileno STDOUT;
+select STDERR; $| = 1; print fileno STDERR;
+EXPECT
+1
+2
+########