summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-03-10 01:01:03 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-03-10 01:01:03 +0000
commit52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc (patch)
treed4b0bde3f89b5c004dcbc5747cdefd2fd75cf1db
parentzsh-workers/10017 (diff)
downloadzsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.tar
zsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.tar.gz
zsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.tar.bz2
zsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.tar.lz
zsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.tar.xz
zsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.tar.zst
zsh-52e15cd48d6732c8ddbcb99e20f5aec68f4a8dfc.zip
zsh-workers/10025
-rw-r--r--Functions/Misc/nslookup6
-rw-r--r--Src/Modules/zpty.c97
2 files changed, 86 insertions, 17 deletions
diff --git a/Functions/Misc/nslookup b/Functions/Misc/nslookup
index 2103a839b..24e46a391 100644
--- a/Functions/Misc/nslookup
+++ b/Functions/Misc/nslookup
@@ -17,7 +17,8 @@ zstyle -s ':nslookup' rprompt tmp && pmpt=("$pmpt[@]" -r "$tmp")
zpty nslookup nslookup
-zpty -r nslookup line '*> '
+zpty -r nslookup line '*
+> '
print -nr "$line"
while line=''; vared -he "$pmpt[@]" line; do
@@ -26,7 +27,8 @@ while line=''; vared -he "$pmpt[@]" line; do
zpty -w nslookup "$line"
- zpty -r nslookup line '*> ' || break
+ zpty -r nslookup line '*
+> '
print -nr "$line"
done
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index 978fd18b5..5ee6438be 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -30,6 +30,13 @@
#include "zpty.mdh"
#include "zpty.pro"
+/* The number of bytes we normally read when given no pattern and the
+ * upper bound on the number of bytes we read (even if we are give a
+ * pattern). */
+
+#define READ_LEN 1024
+#define READ_MAX (1024 * 1024)
+
typedef struct ptycmd *Ptycmd;
struct ptycmd {
@@ -310,6 +317,8 @@ newptycmd(char *nam, char *pname, char **args, int echo, int block)
close(slave);
+ setpgrp(0L, getpid());
+
execve(cmd, args, environ);
exit(0);
}
@@ -353,7 +362,9 @@ deleteptycmd(Ptycmd cmd)
zsfree(p->name);
freearray(p->args);
- kill(p->pid, SIGHUP);
+ /* We kill the process group the command put itself in. */
+
+ kill(-(p->pid), SIGHUP);
zclose(cmd->fd);
@@ -385,7 +396,7 @@ checkptycmd(Ptycmd cmd)
static int
ptyread(char *nam, Ptycmd cmd, char **args)
{
- int blen = 256, used = 0, ret;
+ int blen = 256, used = 0, ret = 1;
char *buf = (char *) zhalloc(blen + 1);
Patprog prog = NULL;
@@ -405,45 +416,101 @@ ptyread(char *nam, Ptycmd cmd, char **args)
}
}
do {
- while ((ret = read(cmd->fd, buf + used, 1)) == 1) {
+ if (!ret) {
+ checkptycmd(cmd);
+ if (cmd->fin)
+ break;
+ }
+ if ((ret = read(cmd->fd, buf + used, 1)) == 1) {
if (++used == blen) {
buf = hrealloc(buf, blen, blen << 1);
blen <<= 1;
}
}
buf[used] = '\0';
- } while (prog && !pattry(prog, buf));
- if (*args)
- setsparam(*args, ztrdup(buf));
- else
- printf("%s", buf);
+ /**** 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 (ret < 0 && (cmd->block
+#ifdef EWOULDBLOCK
+ || errno != EWOULDBLOCK
+#else
+#ifdef EAGAIN
+ || errno != EAGAIN
+#endif
+#endif
+ ))
+ break;
+
+ if (!prog && !ret)
+ break;
+ } while (!errflag &&
+ (prog ? (used < READ_MAX && (!ret || !pattry(prog, buf))) :
+ (used < READ_LEN)));
+
+ if (*args)
+ setsparam(*args, ztrdup(metafy(buf, used, META_HREALLOC)));
+ else {
+ fflush(stdout);
+ write(1, buf, used);
+ }
return !used;
}
static int
+ptywritestr(Ptycmd cmd, char *s, int len)
+{
+ int written;
+
+ for (; len; len -= written, s += written) {
+ if ((written = write(cmd->fd, s, len)) < 0 &&
+ (cmd->block
+#ifdef EWOULDBLOCK
+ || errno != EWOULDBLOCK
+#else
+#ifdef EAGAIN
+ || errno != EAGAIN
+#endif
+#endif
+ ))
+ return 1;
+ if (written < 0) {
+ checkptycmd(cmd);
+ if (cmd->fin)
+ break;
+ written = 0;
+ }
+ }
+ return 0;
+}
+
+static int
ptywrite(Ptycmd cmd, char **args, int nonl)
{
if (*args) {
char sp = ' ';
- while (*args) {
- write(cmd->fd, *args, strlen(*args));
+ while (*args)
+ if (ptywritestr(cmd, *args, strlen(*args)) ||
+ (*++args && ptywritestr(cmd, &sp, 1)))
+ return 1;
- if (*++args)
- write(cmd->fd, &sp, 1);
- }
if (!nonl) {
sp = '\n';
- write(cmd->fd, &sp, 1);
+ if (ptywritestr(cmd, &sp, 1))
+ return 1;
}
} else {
int n;
char buf[BUFSIZ];
while ((n = read(0, buf, BUFSIZ)) > 0)
- write(cmd->fd, buf, n);
+ if (ptywritestr(cmd, buf, n))
+ return 1;
}
return 0;
}