diff options
author | Sven Wischnowsky <wischnow@users.sourceforge.net> | 2000-10-19 08:46:54 +0000 |
---|---|---|
committer | Sven Wischnowsky <wischnow@users.sourceforge.net> | 2000-10-19 08:46:54 +0000 |
commit | 16d7e31ae81bdd87dd90ce91d9072006e43f6596 (patch) | |
tree | 163fa15d6076a55c9cb0991656bf3b4d512f6de8 | |
parent | f718ed6b52199e6a650fb8b01fec392e86dcf412 (diff) | |
download | zsh-16d7e31ae81bdd87dd90ce91d9072006e43f6596.tar.gz zsh-16d7e31ae81bdd87dd90ce91d9072006e43f6596.tar.xz zsh-16d7e31ae81bdd87dd90ce91d9072006e43f6596.zip |
make non-blocking IO on ptys work again; add -t option to test if command is still alive (13035)
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/mod_zpty.yo | 5 | ||||
-rw-r--r-- | Functions/Misc/nslookup | 2 | ||||
-rw-r--r-- | Src/Modules/zpty.c | 55 | ||||
-rw-r--r-- | Src/utils.c | 2 | ||||
-rw-r--r-- | Test/comptest | 2 |
6 files changed, 55 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog index 4c3c49966..a8bf8c92a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2000-10-19 Sven Wischnowsky <wischnow@zsh.org> + + * 13035: Doc/Zsh/mod_zpty.yo, Functions/Misc/nslookup, Src/utils.c, + Src/Modules/zpty.c, Test/comptest: make non-blocking IO on ptys + work again; add -t option to test if command is still alive + 2000-10-19 Wayne Davison <wayned@users.sourceforge.net> * 13034: Src/hist.c: Don't call histreduceblanks() if the line diff --git a/Doc/Zsh/mod_zpty.yo b/Doc/Zsh/mod_zpty.yo index 0c1558056..664e2fabd 100644 --- a/Doc/Zsh/mod_zpty.yo +++ b/Doc/Zsh/mod_zpty.yo @@ -9,6 +9,7 @@ xitem(tt(zpty) [ tt(-e) ] [ tt(-b) ] var(name) var(command) [ var(args ...) ]) xitem(tt(zpty) tt(-d) [ var(names) ... ]) xitem(tt(zpty) tt(-w) [ tt(-n) ] var(name) var(strings ...)) xitem(tt(zpty) tt(-r) var(name) [ var(param) [ var(pattern) ] ]) +xitem(tt(zpty) tt(-t) var(name)) item(tt(zpty) [ tt(-L) ])( 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 @@ -35,6 +36,10 @@ read will be put in the parameter named var(param). If the var(pattern) is also given, output will be read until the whole string read matches the var(pattern). +The tt(-t) option can be used to test whether the command var(name) is +still running. It returns a zero value if the command is running and +a non-zero value otherwise. + The last form without any arguments is used to list the commands currently defined. If the tt(-L) option is given, this is done in the form of calls to the tt(zpty) builtin. diff --git a/Functions/Misc/nslookup b/Functions/Misc/nslookup index d4f7e96b9..1751ef68a 100644 --- a/Functions/Misc/nslookup +++ b/Functions/Misc/nslookup @@ -24,7 +24,7 @@ zstyle -s ':nslookup' pager tmp && [[ -z "$pager" ]] && pager="${opager:-more}" (( $#pmpt )) || pmpt=(-p '> ') -zpty nslookup nslookup "$@" +zpty -b nslookup nslookup "$@" zpty -r nslookup line '* > ' diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c index b469feb72..18f838ed4 100644 --- a/Src/Modules/zpty.c +++ b/Src/Modules/zpty.c @@ -48,6 +48,7 @@ struct ptycmd { int echo; int block; int fin; + int read; }; static Ptycmd ptycmds; @@ -381,6 +382,7 @@ newptycmd(char *nam, char *pname, char **args, int echo, int block) p->echo = echo; p->block = block; p->fin = 0; + p->read = -1; p->next = ptycmds; ptycmds = p; @@ -434,7 +436,9 @@ deleteallptycmds(void) static void checkptycmd(Ptycmd cmd) { - if (kill(cmd->pid, 0) < 0) { + if (cmd->read != -1) + return; + if (!read_poll(cmd->fd, &cmd->read, 1) && kill(cmd->pid, 0) < 0) { cmd->fin = 1; zclose(cmd->fd); } @@ -444,7 +448,7 @@ static int ptyread(char *nam, Ptycmd cmd, char **args) { int blen = 256, used = 0, ret = 1; - char *buf = (char *) zhalloc(blen + 1); + char *buf = (char *) zhalloc((blen = 256) + 1); Patprog prog = NULL; if (*args && args[1]) { @@ -462,6 +466,12 @@ ptyread(char *nam, Ptycmd cmd, char **args) return 1; } } + if (cmd->read != -1) { + buf[0] = (char) cmd->read; + buf[1] = '\0'; + used = 1; + cmd->read = -1; + } do { if (!ret) { checkptycmd(cmd); @@ -476,11 +486,10 @@ ptyread(char *nam, Ptycmd cmd, char **args) } buf[used] = '\0'; - /**** Hm. If we leave the loop when ret < 0 the user would have - * to make sure that `zpty -r' is tried more than once if - * there will be some output and we only got the ret == -1 - * because the output is not yet available. - * The same for the `write' below. */ +#if 0 + /* This once used the following test, to make sure to return + * non-zero if there are no characters to read. That looks + * like a thinko now, because it disables non-blocking ptys. */ if (ret < 0 && (cmd->block #ifdef EWOULDBLOCK @@ -492,8 +501,9 @@ ptyread(char *nam, Ptycmd cmd, char **args) #endif )) break; +#endif - if (!prog && !ret) + if (!prog && ret <= 0) break; } while (!errflag && !breaks && !retflag && !contflag && (prog ? (used < READ_MAX && (!ret || !pattry(prog, buf))) : @@ -514,7 +524,10 @@ ptywritestr(Ptycmd cmd, char *s, int len) int written; for (; len; len -= written, s += written) { - if ((written = write(cmd->fd, s, len)) < 0 && + if ((written = write(cmd->fd, s, len)) < 0 +#if 0 + /* Same as above. */ + && (cmd->block #ifdef EWOULDBLOCK || errno != EWOULDBLOCK @@ -523,7 +536,9 @@ ptywritestr(Ptycmd cmd, char *s, int len) || errno != EAGAIN #endif #endif - )) + ) +#endif + ) return 1; if (written < 0) { checkptycmd(cmd); @@ -567,11 +582,11 @@ static int bin_zpty(char *nam, char **args, char *ops, int func) { if ((ops['r'] && ops['w']) || - ((ops['r'] || ops['w']) && (ops['d'] || ops['e'] || + ((ops['r'] || ops['w']) && (ops['d'] || ops['e'] || ops['t'] || ops['b'] || ops['L'])) || - (ops['n'] && (ops['b'] || ops['e'] || ops['r'] || + (ops['n'] && (ops['b'] || ops['e'] || ops['r'] || ops['t'] || ops['d'] || ops['L'])) || - (ops['d'] && (ops['b'] || ops['e'] || ops['L'])) || + (ops['d'] && (ops['b'] || ops['e'] || ops['L'] || ops['t'])) || (ops['L'] && (ops['b'] || ops['e']))) { zwarnnam(nam, "illegal option combination", NULL, 0); return 1; @@ -607,6 +622,18 @@ bin_zpty(char *nam, char **args, char *ops, int func) deleteallptycmds(); return ret; + } else if (ops['t']) { + Ptycmd p; + + if (!*args) { + zwarnnam(nam, "missing pty command name", NULL, 0); + return 1; + } else if (!(p = getptycmd(*args))) { + zwarnnam(nam, "no such pty command: %s", *args, 0); + return 1; + } + checkptycmd(p); + return p->fin; } else if (*args) { if (!args[1]) { zwarnnam(nam, "missing command", NULL, 0); @@ -649,7 +676,7 @@ ptyhook(Hookdef d, void *dummy) } static struct builtin bintab[] = { - BUILTIN("zpty", 0, bin_zpty, 0, -1, 0, "ebdrwLn", NULL), + BUILTIN("zpty", 0, bin_zpty, 0, -1, 0, "ebdrwLnt", NULL), }; /**/ diff --git a/Src/utils.c b/Src/utils.c index 4e5da893b..05865cf67 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1312,7 +1312,7 @@ setblock_stdin(void) */ /**/ -int +mod_export int read_poll(int fd, int *readchar, int polltty) { int ret = 0; diff --git a/Test/comptest b/Test/comptest index cb0e06f57..0f57e7d70 100644 --- a/Test/comptest +++ b/Test/comptest @@ -16,7 +16,7 @@ comptestinit () { (( OPTIND > 1 )) && shift $(( OPTIND - 1 )) export PS1="<PROMPT>" - zpty zsh "$comptest_zsh" -f + zpty -b zsh "$comptest_zsh" -f zpty -r zsh log1 "*<PROMPT>*" || { print "first prompt hasn't appeared." |