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

PATCH: (more) Re: PATCH: 3.1.5* & 3.0.5: Re: strange xterm & zsh behaviour



On Jan 29, 10:16am, Peter Stephenson wrote:
} Subject: PATCH: 3.1.5* & 3.0.5: Re: strange xterm & zsh behaviour
}
} The worst that can happen is that you get a read-only terminal,
} but the alternative is no terminal at all.
} 
} I added a free for ttystrname to match the other bits.  Any more
} comments?

I think the following is better; apply it on top of Peter's patch.  Besides
testing fds 0 and 1 for read-write-ness before using them (when possible),
it also prefers ttyname(SHTTY) to "/dev/tty" for the setting of the $TTY
parameter.

This patch DOES NOT resolve a related bug that I reported long ago:

	echo echo foo | zsh -i

gets you an interactive prompt reading from the tty, and does not echo foo.
On the other hand:

	echo echo foo | zsh +Z -i

(that is, explicitly turn off zle) prints a prompt, executes "echo foo"
and then exits (end of file).  I think the second behavior is the correct
one for both cases, and that it should not be necessary to use +Z.

Index: Src/init.c
===================================================================
--- init.c	1999/01/29 18:16:38	1.9
+++ init.c	1999/01/29 18:55:29
@@ -303,31 +303,45 @@
 	zsfree(ttystrname);
 	if ((ttystrname = ztrdup(ttyname(0))))
 	    SHTTY = movefd(open(ttystrname, O_RDWR | O_NOCTTY));
+	/*
+	 * xterm, rxvt and probably all terminal emulators except
+	 * dtterm on Solaris 2.6 & 7 have a bug. Applications are
+	 * unable to open /dev/tty or /dev/pts/<terminal number here>
+	 * because something in Sun's STREAMS modules doesn't like
+	 * it. The open() call fails with EBUSY which is not even
+	 * listed as a possibility in the open(2) man page.  So we'll
+	 * try to outsmart The Company.  -- <dave@xxxxxxx>
+	 *
+	 * Presumably there's no harm trying this on any OS, given that
+	 * isatty(0) worked but opening the tty didn't.  Possibly we won't
+	 * get the tty read/write, but it's the best we can do -- pws
+	 *
+	 * Try both stdin and stdout before trying /dev/tty. -- Bart
+	 */
+#if defined(HAVE_FCNTL_H) && defined(F_GETFL)
+#define rdwrtty(fd)	((fcntl(fd, F_GETFL) & O_RDWR) == O_RDWR)
+#else
+#define rdwrtty(fd)	1
+#endif
+	if (SHTTY == -1 && rdwrtty(0)) {
+	    SHTTY = movefd(dup(0));
+	}
     }
-    if (SHTTY == -1 &&
-	(SHTTY = movefd(open("/dev/tty", O_RDWR | O_NOCTTY))) != -1) {
+    if (SHTTY == -1 && isatty(1) && rdwrtty(1) &&
+	(SHTTY = movefd(dup(1))) != -1) {
 	zsfree(ttystrname);
-	ttystrname = ztrdup("/dev/tty");
+	ttystrname = ztrdup(ttyname(1));
     }
-    /*
-     * xterm, rxvt and probably all terminal emulators except dtterm on
-     * Solaris 2.6 & 7 have a bug. Applications are unable to open /dev/tty
-     * or /dev/pts/<terminal number here> because something in Sun's STREAMS
-     * modules doesn't like it. The open() call fails with EBUSY which
-     * is not even listed as a possibility in the open(2) man page.
-     * So we'll try to outsmart The Company.  -- <dave@xxxxxxx>
-     *
-     * Presumably there's no harm trying this on any OS, given that
-     * isatty(0) worked but opening the tty didn't.  Possibly we won't
-     * get the tty read/write, but it's the best we can do -- pws
-     */
-    if (SHTTY == -1 && isatty(0) && (SHTTY = movefd(dup(0))) != -1) {
+    if (SHTTY == -1 &&
+	(SHTTY = movefd(open("/dev/tty", O_RDWR | O_NOCTTY))) != -1) {
 	zsfree(ttystrname);
-	ttystrname = ztrdup(ttyname(0));
+	ttystrname = ztrdup(ttyname(SHTTY));
     }
     if (SHTTY == -1) {
 	zsfree(ttystrname);
 	ttystrname = ztrdup("");
+    } else if (!ttystrname) {
+	ttystrname = ztrdup("/dev/tty");
     }
 
     /* We will only use zle if shell is interactive, *

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com




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