Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] Remove zpty exit hook from forked processes



Fixes a bug where `zpty -d foo` kills `foo` and all pty commands started
before `foo`.

Steps to reproduce before the patch:

  % zmodload zsh/zpty
  % zpty -b foo cat
  % zpty -b bar cat
  % zpty -b baz cat
  % zpty -d bar
  % zpty -t foo; echo $?
  1
  % zpty -t bar; echo $?
  zpty: no such pty command: bar
  1
  % zpty -t baz; echo $?
  0

Results after the patch (note the exit code of `zpty -t foo`):

  % zmodload zsh/zpty
  % zpty -b foo cat
  % zpty -b bar cat
  % zpty -b baz cat
  % zpty -d bar
  % zpty -t foo; echo $?
  0
  % zpty -t bar; echo $?
  zpty: no such pty command: bar
  1
  % zpty -t baz; echo $?
  0
---
 Src/Modules/zpty.c | 91 +++++++++++++++++++++++++++---------------------------
 1 file changed, 46 insertions(+), 45 deletions(-)

diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 2c87be1..fbc1a88 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -294,6 +294,51 @@ get_pty(int master, int *retfd)
 
 #endif /* /dev/ptmx or alternatives */
 
+static void
+deleteptycmd(Ptycmd cmd)
+{
+    Ptycmd p, q;
+
+    for (q = NULL, p = ptycmds; p != cmd; q = p, p = p->next);
+
+    if (p != cmd)
+	return;
+
+    if (q)
+	q->next = p->next;
+    else
+	ptycmds = p->next;
+
+    zsfree(p->name);
+    freearray(p->args);
+
+    zclose(cmd->fd);
+
+    /* We kill the process group the command put itself in. */
+
+    kill(-(p->pid), SIGHUP);
+
+    zfree(p, sizeof(*p));
+}
+
+static void
+deleteallptycmds(void)
+{
+    Ptycmd p, n;
+
+    for (p = ptycmds; p; p = n) {
+	n = p->next;
+	deleteptycmd(p);
+    }
+}
+
+static int
+ptyhook(UNUSED(Hookdef d), UNUSED(void *dummy))
+{
+    deleteallptycmds();
+    return 0;
+}
+
 static int
 newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 {
@@ -331,6 +376,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 	/* This code copied from the clone module, except for getting *
 	 * the descriptor from get_pty() and duplicating it to 0/1/2. */
 
+	deletehookfunc("exit", ptyhook);
 	clearjobtab(0);
 	ppid = getppid();
 	mypid = getpid();
@@ -469,44 +515,6 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
     return 0;
 }
 
-static void
-deleteptycmd(Ptycmd cmd)
-{
-    Ptycmd p, q;
-
-    for (q = NULL, p = ptycmds; p != cmd; q = p, p = p->next);
-
-    if (p != cmd)
-	return;
-
-    if (q)
-	q->next = p->next;
-    else
-	ptycmds = p->next;
-
-    zsfree(p->name);
-    freearray(p->args);
-
-    zclose(cmd->fd);
-
-    /* We kill the process group the command put itself in. */
-
-    kill(-(p->pid), SIGHUP);
-
-    zfree(p, sizeof(*p));
-}
-
-static void
-deleteallptycmds(void)
-{
-    Ptycmd p, n;
-
-    for (p = ptycmds; p; p = n) {
-	n = p->next;
-	deleteptycmd(p);
-    }
-}
-
 /**** a better process handling would be nice */
 
 static void
@@ -852,13 +860,6 @@ bin_zpty(char *nam, char **args, Options ops, UNUSED(int func))
     }
 }
 
-static int
-ptyhook(UNUSED(Hookdef d), UNUSED(void *dummy))
-{
-    deleteallptycmds();
-    return 0;
-}
-
 
 static struct builtin bintab[] = {
     BUILTIN("zpty", 0, bin_zpty, 0, -1, 0, "ebdmrwLnt", NULL),
-- 
2.9.0



Messages sorted by: Reverse Date, Date, Thread, Author