summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/Modules/zpty.c30
-rw-r--r--Test/V08zpty.ztst10
3 files changed, 42 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 08b8abdc4..8f594b45b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-26  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 31672: Src/Modules/zpty.c, Test/V08zpty.ztst: add test that
+	was failing and fix race when setting up pty.
+
 2013-08-25  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
 	* 31665: Src/Modules/zpty.c, Test/V08zpty.ztst, Test/.distfiles:
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 382119483..fca0cc172 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -293,8 +293,8 @@ static int
 newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 {
     Ptycmd p;
-    int master, slave, pid, oineval = ineval;
-    char *oscriptname = scriptname;
+    int master, slave, pid, oineval = ineval, ret;
+    char *oscriptname = scriptname, syncch;
     Eprog prog;
 
     /* code borrowed from bin_eval() */
@@ -398,6 +398,20 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 	setsparam("TTY", ztrdup(ttystrname));
 
 	opts[INTERACTIVE] = 0;
+
+	syncch = 0;
+	do {
+	    ret = write(1, &syncch, 1);
+	} while (ret != 1 && (
+#ifdef EWOULDBLOCK
+	    errno == EWOULDBLOCK ||
+#else
+#ifdef EAGAIN
+	    errno == EAGAIN ||
+#endif
+#endif
+	    errno == EINTR));
+
 	execode(prog, 1, 0, "zpty");
 	stopmsg = 2;
 	mypid = 0; /* trick to ensure we _exit() */
@@ -433,6 +447,18 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
     scriptname = oscriptname;
     ineval = oineval;
 
+    do {
+	ret = read(master, &syncch, 1);
+    } while (ret != 1 && (
+#ifdef EWOULDBLOCK
+	    errno == EWOULDBLOCK ||
+#else
+#ifdef EAGAIN
+	    errno == EAGAIN ||
+#endif
+#endif
+	    errno == EINTR));
+
     return 0;
 }
 
diff --git a/Test/V08zpty.ztst b/Test/V08zpty.ztst
index d9d24c5e8..5b08fc281 100644
--- a/Test/V08zpty.ztst
+++ b/Test/V08zpty.ztst
@@ -12,9 +12,17 @@
 %test
 
   zpty cat cat
+  zpty -w cat a line of text
+  var=
+  zpty -r cat var && print -r -- ${var%%$'\r\n'}
+  zpty -d cat
+0:zpty with a process that does not set up the terminal: internal write
+>a line of text
+
+  zpty cat cat
   print a line of text | zpty -w cat
   var=
   zpty -r cat var && print -r -- ${var%%$'\r\n'}
   zpty -d cat
-0:zpty with a process that does not set up the terminal
+0:zpty with a process that does not set up the terminal: write via stdin
 >a line of text