diff options
author | Bart Schaefer <barts@users.sourceforge.net> | 2000-11-06 06:24:27 +0000 |
---|---|---|
committer | Bart Schaefer <barts@users.sourceforge.net> | 2000-11-06 06:24:27 +0000 |
commit | 49fc6b036cbc1f42966ddcd246de61712962b576 (patch) | |
tree | 1c5145a13ce14a3d4dd5a7bbbc107eecb201e81c | |
parent | dbc0aebcd44a028ed5c5c392fa2b354a1b562955 (diff) | |
download | zsh-49fc6b036cbc1f42966ddcd246de61712962b576.tar.gz zsh-49fc6b036cbc1f42966ddcd246de61712962b576.tar.xz zsh-49fc6b036cbc1f42966ddcd246de61712962b576.zip |
Make zpty more like eval.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | Doc/Zsh/mod_zpty.yo | 13 | ||||
-rw-r--r-- | Src/Modules/zpty.c | 103 | ||||
-rw-r--r-- | Src/utils.c | 4 |
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 |