about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.stephenson@samsung.com>2019-07-02 13:42:53 +0100
committerPeter Stephenson <p.stephenson@samsung.com>2019-07-02 13:42:53 +0100
commit3bdf4d6641fb34d1c2f130abddb847169a793afe (patch)
treeb1c3686749a26212f08bfd8ffea464804f308d86
parent700ec49581650ea1f0bffacb207a30145e278417 (diff)
downloadzsh-3bdf4d6641fb34d1c2f130abddb847169a793afe.tar.gz
zsh-3bdf4d6641fb34d1c2f130abddb847169a793afe.tar.xz
zsh-3bdf4d6641fb34d1c2f130abddb847169a793afe.zip
44480: Don't automatically close externally visible file descroptors.
These are descriptors marked FDT_EXTERNAL.

Make all sysopen'ed file descriptors FDT_EXTERNAL.

Make =(...) call closem() consistent with other substitutions.

Document file descriptors are left open.
-rw-r--r--ChangeLog8
-rw-r--r--Doc/Zsh/mod_socket.yo6
-rw-r--r--Doc/Zsh/mod_system.yo4
-rw-r--r--Doc/Zsh/redirect.yo3
-rw-r--r--Src/Modules/system.c4
-rw-r--r--Src/exec.c5
6 files changed, 23 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 1eb2ef24a..a73915f3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2019-07-02  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 44480: Doc/Zsh/mod_socket.yo, Doc/Zsh/mod_system.yo,
+	Doc/Zsh/redirect.yo, Src/Modules/system.c, Src/exec.c:
+	Don't automatically close FDT_EXTERNAL file descriptors.
+	All sysopen-created fd's become FDT_EXTERNAL.  =(...)
+	calls closem() consistent with other substitutions.
+
 2019-07-01  Peter Stephenson  <p.stephenson@samsung.com>
 
 	* Martijn: 44469: Src/builtin.c, Test/B10getopts.ztst: correct
diff --git a/Doc/Zsh/mod_socket.yo b/Doc/Zsh/mod_socket.yo
index 867f6081f..78d9254e8 100644
--- a/Doc/Zsh/mod_socket.yo
+++ b/Doc/Zsh/mod_socket.yo
@@ -43,7 +43,8 @@ startitem()
 item(tt(zsocket) tt(-l) [ tt(-v) ] [ tt(-d) var(fd) ] var(filename))(
 tt(zsocket -l) will open a socket listening on var(filename).
 The shell parameter tt(REPLY) will be set to the file descriptor
-associated with that listener.
+associated with that listener.  The file descriptor remains open in subshells
+and forked external executables.
 
 If tt(-d) is specified, its argument
 will be taken as the target file descriptor for
@@ -56,7 +57,8 @@ tt(zsocket -a) will accept an incoming connection
 to the socket associated with var(listenfd).
 The shell parameter tt(REPLY) will
 be set to the file descriptor associated with
-the inbound connection.
+the inbound connection.  The file descriptor remains open in subshells
+and forked external executables.
 
 If tt(-d) is specified, its argument
 will be taken as the target file descriptor for the
diff --git a/Doc/Zsh/mod_system.yo b/Doc/Zsh/mod_system.yo
index 3a85e760f..6292af071 100644
--- a/Doc/Zsh/mod_system.yo
+++ b/Doc/Zsh/mod_system.yo
@@ -45,7 +45,9 @@ specified as a comma-separated list. The following is a list of possible
 options. Note that, depending on the system, some may not be available.
 startitem()
 item(tt(cloexec))(
-mark file to be closed when other programs are executed
+mark file to be closed when other programs are executed (else
+the file descriptor remains open in subshells and forked external
+executables)
 )
 xitem(tt(create))
 item(tt(creat))(
diff --git a/Doc/Zsh/redirect.yo b/Doc/Zsh/redirect.yo
index 7e38cd0c3..13496d8d3 100644
--- a/Doc/Zsh/redirect.yo
+++ b/Doc/Zsh/redirect.yo
@@ -182,7 +182,8 @@ indent(... tt({myfd}>&1))
 This opens a new file descriptor that is a duplicate of file descriptor
 1 and sets the parameter tt(myfd) to the number of the file descriptor,
 which will be at least 10.  The new file descriptor can be written to using
-the syntax tt(>&$myfd).
+the syntax tt(>&$myfd).  The file descriptor remains open in subshells
+and forked external executables.
 
 The syntax tt({)var(varid)tt(}>&-), for example tt({myfd}>&-), may be used
 to close a file descriptor opened in this fashion.  Note that the
diff --git a/Src/Modules/system.c b/Src/Modules/system.c
index 7a4f4ee13..50de59cf9 100644
--- a/Src/Modules/system.c
+++ b/Src/Modules/system.c
@@ -316,7 +316,7 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
     int o, fd, moved_fd, explicit = -1;
     mode_t perms = 0666;
 #if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
-    int fdflags;
+    int fdflags = 0;
 #endif
 
     if (!OPT_ISSET(ops, 'u')) {
@@ -396,8 +396,8 @@ bin_sysopen(char *nam, char **args, Options ops, UNUSED(int func))
 #endif /* O_CLOEXEC */
 	fcntl(moved_fd, F_SETFD, FD_CLOEXEC);
 #endif /* FD_CLOEXEC */
+    fdtable[moved_fd] = FDT_EXTERNAL;
     if (explicit == -1) {
-	fdtable[moved_fd] = FDT_EXTERNAL;
 	setiparam(fdvar, moved_fd);
 	/* if setting the variable failed, close moved_fd to avoid leak */
 	if (errflag)
diff --git a/Src/exec.c b/Src/exec.c
index 60ab0acf8..2acb2c0bc 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -4407,8 +4407,10 @@ closem(int how, int all)
 	    /*
 	     * Process substitution needs to be visible to user;
 	     * fd's are explicitly cleaned up by filelist handling.
+	     * External FDs are managed directly by the user.
 	     */
-	    (all || fdtable[i] != FDT_PROC_SUBST) &&
+	    (all || (fdtable[i] != FDT_PROC_SUBST &&
+		     fdtable[i] != FDT_EXTERNAL)) &&
 	    (how == FDT_UNUSED || (fdtable[i] & FDT_TYPE_MASK) == how)) {
 	    if (i == SHTTY)
 		SHTTY = -1;
@@ -4823,6 +4825,7 @@ getoutputfile(char *cmd, char **eptr)
     }
 
     /* pid == 0 */
+    closem(FDT_UNUSED, 0);
     redup(fd, 1);
     entersubsh(ESUB_PGRP|ESUB_NOMONITOR, NULL);
     cmdpush(CS_CMDSUBST);