From: Greg Klanderman <gak@klanderman.net>
To: zsh-workers@zsh.org
Subject: Re: ztcp should not pick fd 0
Date: Wed, 11 Aug 2010 15:50:55 -0400 [thread overview]
Message-ID: <m3hbj153og.fsf@klanderman.net> (raw)
In-Reply-To: <m3k4nx5b4s.fsf@klanderman.net> (Greg Klanderman's message of "Wed, 11 Aug 2010 13:09:55 -0400")
Peter, how's this look?
greg
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.236
diff -u -r1.236 utils.c
--- Src/utils.c 16 Dec 2009 18:38:44 -0000 1.236
+++ Src/utils.c 11 Aug 2010 19:46:00 -0000
@@ -1621,6 +1621,34 @@
}
}
+/* Add an entry for fd to the fdtable with the given value. */
+
+/**/
+mod_export void
+fdtable_add(int fd, int fdtval)
+{
+ if (fd != -1 && fdtval != FDT_UNUSED) {
+ if (fd > max_zsh_fd) {
+ while (fd >= fdtable_size)
+ fdtable = zrealloc(fdtable,
+ (fdtable_size *= 2)*sizeof(*fdtable));
+ max_zsh_fd = fd;
+ }
+ fdtable[fd] = fdtval;
+ }
+}
+
+/* Clear the entry for fd in the fdtable. */
+
+/**/
+mod_export void
+fdtable_clear(int fd)
+{
+ fdtable[fd] = FDT_UNUSED;
+ while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED)
+ max_zsh_fd--;
+}
+
/* Move a fd to a place >= 10 and mark the new fd in fdtable. If the fd *
* is already >= 10, it is not moved. If it is invalid, -1 is returned. */
@@ -1643,15 +1671,12 @@
zclose(fd);
fd = fe;
}
- if(fd != -1) {
- if (fd > max_zsh_fd) {
- while (fd >= fdtable_size)
- fdtable = zrealloc(fdtable,
- (fdtable_size *= 2)*sizeof(*fdtable));
- max_zsh_fd = fd;
- }
- fdtable[fd] = FDT_INTERNAL;
- }
+
+ /* FIXME: setting the entry to FDT_INTERNAL is pretty bogus; it would be
+ * better to copy the value from the old fd (as redup below does), but
+ * changing that would require auditing all uses of this function. */
+ fdtable_add(fd, FDT_INTERNAL);
+
return fd;
}
@@ -1669,12 +1694,9 @@
if(x < 0)
zclose(y);
else if (x != y) {
- while (y >= fdtable_size)
- fdtable = zrealloc(fdtable, (fdtable_size *= 2)*sizeof(*fdtable));
if (dup2(x, y) == -1)
ret = -1;
- if ((fdtable[y] = fdtable[x]) && y > max_zsh_fd)
- max_zsh_fd = y;
+ fdtable_add(y, fdtable[x]);
zclose(x);
}
@@ -1688,9 +1710,7 @@
zclose(int fd)
{
if (fd >= 0) {
- fdtable[fd] = FDT_UNUSED;
- while (max_zsh_fd > 0 && fdtable[max_zsh_fd] == FDT_UNUSED)
- max_zsh_fd--;
+ fdtable_clear(fd);
if (fd == coprocin)
coprocin = -1;
if (fd == coprocout)
Index: Src/Modules/tcp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.c,v
retrieving revision 1.51
diff -u -r1.51 tcp.c
--- Src/Modules/tcp.c 22 Sep 2009 16:04:16 -0000 1.51
+++ Src/Modules/tcp.c 11 Aug 2010 19:46:00 -0000
@@ -236,6 +236,7 @@
if (!sess) return NULL;
sess->fd = socket(domain, type, protocol);
+ fdtable_add(sess->fd, FDT_EXTERNAL);
return sess;
}
@@ -298,6 +299,7 @@
{
if (sess->fd != -1)
{
+ fdtable_clear(sess->fd);
err = close(sess->fd);
if (err)
zwarn("connection close failed: %e", errno);
@@ -337,6 +339,29 @@
}
static int
+maybe_move_fd(char *nam, Tcp_session sess, int targetfd)
+{
+ if (targetfd) {
+ sess->fd = redup(sess->fd, targetfd);
+ if (sess->fd < 0) {
+ zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
+ return 1;
+ }
+ }
+ else {
+ /* if necessary, move the fd to one >= 10 */
+ int oldfd = sess->fd;
+ sess->fd = movefd(sess->fd);
+ fdtable_add(sess->fd, FDT_EXTERNAL); /* FIXME: see comment in movefd() */
+ if (sess->fd < 0) {
+ zerrnam(nam, "could not move socket fd %d: %e", oldfd, errno);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int
bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
{
int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0;
@@ -445,19 +470,8 @@
return 1;
}
- if (targetfd) {
- sess->fd = redup(sess->fd, targetfd);
- }
- else {
- /* move the fd since no one will want to read from it */
- sess->fd = movefd(sess->fd);
- }
-
- if (sess->fd == -1) {
- zwarnnam(nam, "cannot duplicate fd %d: %e", sess->fd, errno);
- tcp_close(sess);
- return 1;
- }
+ if (maybe_move_fd(nam, sess, targetfd))
+ return 1;
setiparam("REPLY", sess->fd);
@@ -543,16 +557,11 @@
return 1;
}
- if (targetfd) {
- sess->fd = redup(rfd, targetfd);
- if (sess->fd < 0) {
- zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
- return 1;
- }
- }
- else {
- sess->fd = rfd;
- }
+ sess->fd = rfd;
+ fdtable_add(rfd, FDT_EXTERNAL);
+
+ if (maybe_move_fd(nam, sess, targetfd))
+ return 1;
setiparam("REPLY", sess->fd);
@@ -659,22 +668,14 @@
zsfree(desthost);
return 1;
}
- else
- {
- if (targetfd) {
- sess->fd = redup(sess->fd, targetfd);
- if (sess->fd < 0) {
- zerrnam(nam, "could not duplicate socket fd to %d: %e", targetfd, errno);
- return 1;
- }
- }
- setiparam("REPLY", sess->fd);
+ if (maybe_move_fd(nam, sess, targetfd))
+ return 1;
- if (verbose)
- printf("%s:%d is now on fd %d\n",
- desthost, destport, sess->fd);
- }
+ setiparam("REPLY", sess->fd);
+
+ if (verbose)
+ printf("%s:%d is now on fd %d\n", desthost, destport, sess->fd);
zsfree(desthost);
}
next prev parent reply other threads:[~2010-08-11 19:59 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-11 16:21 Greg Klanderman
2010-08-11 16:44 ` Peter Stephenson
2010-08-11 17:09 ` Greg Klanderman
2010-08-11 19:50 ` Greg Klanderman [this message]
2010-08-13 13:51 ` Greg Klanderman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3hbj153og.fsf@klanderman.net \
--to=gak@klanderman.net \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).