about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2000-11-06 06:24:27 +0000
committerBart Schaefer <barts@users.sourceforge.net>2000-11-06 06:24:27 +0000
commit49fc6b036cbc1f42966ddcd246de61712962b576 (patch)
tree1c5145a13ce14a3d4dd5a7bbbc107eecb201e81c
parentdbc0aebcd44a028ed5c5c392fa2b354a1b562955 (diff)
downloadzsh-49fc6b036cbc1f42966ddcd246de61712962b576.tar.gz
zsh-49fc6b036cbc1f42966ddcd246de61712962b576.tar.xz
zsh-49fc6b036cbc1f42966ddcd246de61712962b576.zip
Make zpty more like eval.
-rw-r--r--ChangeLog9
-rw-r--r--Doc/Zsh/mod_zpty.yo13
-rw-r--r--Src/Modules/zpty.c103
-rw-r--r--Src/utils.c4
4 files changed, 65 insertions, 64 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d8482b3c..bc2a167e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2000-11-05  Bart Schaefer  <schaefer@zsh.org>
 
+	* unposted: Src/Modules/zpty.c: Cloned shell is non-interactive
+	for purposes of calling zexit(), so it doesn't print job status,
+	save history, etc.
+
+	* 13123: Doc/Zsh/mod_zpty.yo, Src/utils.c, Src/Modules/zpty.c:
+	Change `zpty' to act as a combination of `clone' and `eval', to
+	remove the limitation that only external commands can be run on
+	the pty.  Also fix typos in utils.c.
+
 	* 13120: Doc/Zsh/mod_zpty.yo, Functions/Misc/nslookup,
 	Src/utils.c, Src/Modules/zpty.c: Merge Sven's uncommitted patch
 	from 13061 with 13116.  WARNING: This reverses the meaning of
diff --git a/Doc/Zsh/mod_zpty.yo b/Doc/Zsh/mod_zpty.yo
index e90b36d09..24139a83f 100644
--- a/Doc/Zsh/mod_zpty.yo
+++ b/Doc/Zsh/mod_zpty.yo
@@ -5,12 +5,13 @@ The tt(zsh/zpty) module offers one builtin:
 
 startitem()
 findex(zpty)
-item(tt(zpty) [ tt(-e) ] [ tt(-b) ] var(name) var(command) [ var(args ...) ])(
-In the first form, the var(command) is started with the var(args) as
-arguments.  The command runs under a newly assigned pseudo-terminal; this
-is useful for running commands non-interactively which expect an
-interactive environment.  The var(name) is used to refer to this command
-in later calls to tt(zpty).
+item(tt(zpty) [ tt(-e) ] [ tt(-b) ] var(name) [ var(arg ...) ])(
+The arguments following var(name) are concatenated with spaces between,
+then executed as a command, as if passed to the tt(eval) builtin.  The
+command runs under a newly assigned pseudo-terminal; this is useful for
+running commands non-interactively which expect an interactive
+environment.  The var(name) is not part of the command, but is used to
+refer to this command in later calls to tt(zpty).
 
 With the tt(-e) option, the pseudo-terminal is set up so that input
 characters are echoed.
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 463fbdf75..30a36b194 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -171,7 +171,7 @@ get_pty(int master, int *retfd)
     int ret;
 
     if (master) {
-	if ((mfd = open("/dev/ptmx", O_RDWR)) < 0)
+	if ((mfd = open("/dev/ptmx", O_RDWR|O_NOCTTY)) < 0)
 	    return 1;
 
 	if (grantpt(mfd) || unlockpt(mfd) || !(name = ptsname(mfd))) {
@@ -182,7 +182,7 @@ get_pty(int master, int *retfd)
 
 	return 0;
     }
-    if ((sfd = open(name, O_RDWR)) < 0) {
+    if ((sfd = open(name, O_RDWR|O_NOCTTY)) < 0) {
 	close(mfd);
 	return 1;
     }
@@ -242,7 +242,7 @@ get_pty(int master, int *retfd)
 	    name[8] = *p1;
 	    for (p2 = char2; *p2; p2++) {
 		name[9] = *p2;
-		if ((mfd = open(name, O_RDWR)) >= 0) {
+		if ((mfd = open(name, O_RDWR|O_NOCTTY)) >= 0) {
 		    *retfd = mfd;
 
 		    return 0;
@@ -251,7 +251,7 @@ get_pty(int master, int *retfd)
 	}
     }
     name[5] = 't';
-    if ((sfd = open(name, O_RDWR)) >= 0) {
+    if ((sfd = open(name, O_RDWR|O_NOCTTY)) >= 0) {
 	*retfd = sfd;
 
 	return 0;
@@ -268,12 +268,14 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 {
     Ptycmd p;
     int master, slave, pid;
-    char *cmd;
+    Eprog prog;
 
-    if (!(cmd = findcmd(*args, 1))) {
-	zwarnnam(nam, "unknown command: %s", *args, 0);
+    prog = parse_string(zjoin(args, ' ', 1), 0);
+    if (!prog) {
+	errflag = 0;
 	return 1;
     }
+
     if (get_pty(1, &master)) {
 	zwarnnam(nam, "can't open pseudo terminal: %e", NULL, errno);
 	return 1;
@@ -283,41 +285,40 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 	close(master);
 	return 1;
     } else if (!pid) {
+	/* This code copied from the clone module, except for getting *
+	 * the descriptor from get_pty() and duplicating it to 0/1/2. */
 
-	pid = getpid();
-
+	clearjobtab();
+	ppid = getppid();
+	mypid = getpid();
 #ifdef HAVE_SETSID
-	setsid();
-#else
+	if (setsid() != mypid) {
+	    zwarnnam(nam, "failed to create new session: %e", NULL, errno);
+#endif
 #ifdef TIOCNOTTY
-	{
-	    int t = open("/dev/tty", O_RDWR);
-
-	    ioctl(t, TIOCNOTTY, 0);
-	    close(t);
-	}
+	    if (ioctl(SHTTY, TIOCNOTTY, 0))
+		zwarnnam(nam, "%e", NULL, errno);
+	    setpgrp(0L, mypid);
 #endif
+#ifdef HAVE_SETSID
+	}
 #endif
 
 	if (get_pty(0, &slave))
 	    exit(1);
+#ifdef TIOCGWINSZ
+	/* Set the window size before associating with the terminal *
+	 * so that we don't get hit with a SIGWINCH.  I'm paranoid. */
+	if (interact) {
+	    struct ttyinfo info;
 
-#ifdef TIOCSCTTY
-	ioctl(slave, TIOCSCTTY, 0);
-#endif
-
-	/* This is taken from attachtty(). Should we exit in case of
-	 * failure? */
-
-#ifdef HAVE_TCSETPGRP
-	tcsetpgrp(slave, pid);
-#else
-# if ardent
-	setpgrp();
-# else
-	ioctl(slave, TIOCSPGRP, &pid);
-# endif
-#endif
+	    if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) {
+		info.winsize.ws_row = lines;
+		info.winsize.ws_col = columns;
+		ioctl(slave, TIOCSWINSZ, (char *) &info.winsize);
+	    }
+	}
+#endif /* TIOCGWINSZ */
 
 	if (!echo) {
 	    struct ttyinfo info;
@@ -336,21 +337,9 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 	    }
 	}
 
-#ifdef TIOCGWINSZ
-	if (interact) {
-	    struct ttyinfo info;
-
-	    if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) {
-		info.winsize.ws_row = lines;
-		info.winsize.ws_col = columns;
-		ioctl(slave, TIOCSWINSZ, (char *) &info.winsize);
-	    }
-	}
-#endif /* TIOCGWINSZ */
-
-	signal_default(SIGTERM);
-	signal_default(SIGINT);
-	signal_default(SIGQUIT);
+#ifdef TIOCSCTTY
+	ioctl(slave, TIOCSCTTY, 0);
+#endif
 
 	close(0);
 	close(1);
@@ -360,16 +349,18 @@ newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
 	dup2(slave, 1);
 	dup2(slave, 2);
 
+	closem(0);
 	close(slave);
 	close(master);
-
-	if (SHTTY != -1)
-	    close(SHTTY);
-
-	closedumps();
-
-	execve(cmd, args, environ);
-	exit(0);
+	close(coprocin);
+	close(coprocout);
+	init_io();
+	setsparam("TTY", ztrdup(ttystrname));
+
+	execode(prog, 1, 0);
+	opts[INTERACTIVE] = 0;
+	stopmsg = 2;
+	zexit(lastval, 0);
     }
     master = movefd(master);
 
diff --git a/Src/utils.c b/Src/utils.c
index 1190347f7..686a46fbf 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -2547,7 +2547,7 @@ getbaudrate(struct ttyinfo *shttyinfo)
  *   META_NOALLOC:  buf points to a memory area which is long enough to hold *
  *                  the quoted form, just quote it and return buf.           *
  *   META_STATIC:   store the quoted string in a static area.  The original  *
- *                  sting should be at most PATH_MAX long.                   *
+ *                  string should be at most PATH_MAX long.                   *
  *   META_ALLOC:    allocate memory for the new string with zalloc().        *
  *   META_DUP:      leave buf unchanged and allocate space for the return    *
  *                  value even if buf does not contains special characters   *
@@ -2599,7 +2599,7 @@ metafy(char *buf, int len, int heap)
 	case META_NOALLOC:
 	    break;
 	default:
-	    fprintf(stderr, "BUG: metafy called with invaild heap value\n");
+	    fprintf(stderr, "BUG: metafy called with invalid heap value\n");
 	    fflush(stderr);
 	    break;
 #endif