summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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