summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/zle.yo4
-rw-r--r--Src/Zle/zle_main.c119
3 files changed, 111 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 992c53b4f..618d31c41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2002-06-06 Peter Stephenson <pws@csr.com>
+
+ * 17293: Src/Zle/zle_main.c, Doc/Zsh/zle.yo: support poll()
+ as a (preferred) alternative to select() in zle.
+
2002-06-06 Clint Adams <clint@zsh.org>
* 17297: Src/Modules/zpty.c: 17265 continued.
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 67e66830d..bfdbbd736 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -413,8 +413,8 @@ within this invocation of ZLE. Any following invocation (e.g., the next
command line) will start as usual with the `tt(main)' keymap selected.
)
item(tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ])(
-Only available if your system support the `select' system call; most
-modern systems do.
+Only available if your system supports one of the `poll' or `select' system
+calls; most modern systems do.
Installs var(handler) (the name of a shell function) to handle input from
file descriptor var(fd). When zle is attempting to read data, it will
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 56797a9a9..782bd472c 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -30,6 +30,13 @@
#include "zle.mdh"
#include "zle_main.pro"
+#ifdef HAVE_POLL_H
+# include <poll.h>
+#endif
+#if defined(HAVE_POLL) && !defined(POLLIN) && !defined(POLLNORM)
+# undef HAVE_POLL
+#endif
+
/* != 0 if in a shell function called from completion, such that read -[cl] *
* will work (i.e., the line is metafied, and the above word arrays are OK). */
@@ -340,11 +347,13 @@ raw_getkey(int keytmout, char *cptr)
{
long exp100ths;
int ret;
-#ifdef HAVE_SELECT
+#ifndef HAVE_POLL
+# ifdef HAVE_SELECT
fd_set foofd;
-#else
-# ifdef HAS_TIO
+# else
+# ifdef HAS_TIO
struct ttyinfo ti;
+# endif
# endif
#endif
@@ -364,18 +373,45 @@ raw_getkey(int keytmout, char *cptr)
exp100ths = 500;
else
exp100ths = keytimeout;
-#ifdef HAVE_SELECT
+#if defined(HAVE_SELECT) || defined(HAVE_POLL)
if (!keytmout || exp100ths) {
+ int i, errtry = 0, selret;
+# ifdef HAVE_POLL
+ int poll_timeout;
+ int nfds = keytmout ? 1 : 1 + nwatch;
+ /* First pollfd is SHTTY, following are the nwatch fds */
+ struct pollfd *fds = zalloc(sizeof(struct pollfd) * nfds);
+ if (exp100ths)
+ poll_timeout = exp100ths * 10;
+ else
+ poll_timeout = -1;
+
+ fds[0].fd = SHTTY;
+ /*
+ * POLLIN, POLLIN, POLLIN,
+ * Keep those fd's POLLIN...
+ */
+ fds[0].events = POLLIN;
+ if (!keytmout) {
+ for (i = 0; i < nwatch; i++) {
+ fds[i+1].fd = watch_fds[i];
+ fds[i+1].events = POLLIN;
+ }
+ }
+# else
+ int fdmax = SHTTY;
struct timeval *tvptr = NULL;
struct timeval expire_tv;
- int i, fdmax = SHTTY, errtry = 0;
if (exp100ths) {
expire_tv.tv_sec = exp100ths / 100;
expire_tv.tv_usec = (exp100ths % 100) * 10000L;
tvptr = &expire_tv;
}
+# endif
do {
- int selret;
+# ifdef HAVE_POLL
+ selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
+# else
FD_ZERO(&foofd);
FD_SET(SHTTY, &foofd);
if (!keytmout && !errtry) {
@@ -388,11 +424,12 @@ raw_getkey(int keytmout, char *cptr)
}
selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
NULL, NULL, tvptr);
+# endif
/*
* Make sure a user interrupt gets passed on straight away.
*/
if (selret < 0 && errflag)
- return selret;
+ break;
/*
* Try to avoid errors on our special fd's from
* messing up reads from the terminal. Try first
@@ -404,9 +441,10 @@ raw_getkey(int keytmout, char *cptr)
}
if (selret == 0) {
/* Special value -2 signals nothing ready */
- return -2;
- } else if (selret < 0)
- return selret;
+ selret = -2;
+ }
+ if (selret < 0)
+ break;
if (!keytmout && nwatch) {
/*
* Copy the details of the watch fds in case the
@@ -418,7 +456,13 @@ raw_getkey(int keytmout, char *cptr)
char **lwatch_funcs = zarrdup(watch_funcs);
memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(int));
for (i = 0; i < lnwatch; i++) {
- if (FD_ISSET(lwatch_fds[i], &foofd)) {
+ if (
+# ifdef HAVE_POLL
+ (fds[i+1].revents & POLLIN)
+# else
+ FD_ISSET(lwatch_fds[i], &foofd)
+# endif
+ ) {
/* Handle the fd. */
LinkList funcargs = znewlinklist();
zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
@@ -427,6 +471,21 @@ raw_getkey(int keytmout, char *cptr)
convbase(buf, lwatch_fds[i], 10);
zaddlinknode(funcargs, ztrdup(buf));
}
+# ifdef HAVE_POLL
+# ifdef POLLERR
+ if (fds[i+1].revents & POLLERR)
+ zaddlinknode(funcargs, ztrdup("err"));
+# endif
+# ifdef POLLHUP
+ if (fds[i+1].revents & POLLHUP)
+ zaddlinknode(funcargs, ztrdup("hup"));
+# endif
+# ifdef POLLNVAL
+ if (fds[i+1].revents & POLLNVAL)
+ zaddlinknode(funcargs, ztrdup("nval"));
+# endif
+# endif
+
callhookfunc(lwatch_funcs[i], funcargs);
if (errflag) {
@@ -447,7 +506,18 @@ raw_getkey(int keytmout, char *cptr)
zfree(lwatch_fds, lnwatch*sizeof(int));
freearray(lwatch_funcs);
}
- } while (!FD_ISSET(SHTTY, &foofd));
+ } while (!
+# ifdef HAVE_POLL
+ (fds[0].revents & POLLIN)
+# else
+ FD_ISSET(SHTTY, &foofd)
+# endif
+ );
+# ifdef HAVE_POLL
+ zfree(fds, sizeof(struct pollfd) * nfds);
+# endif
+ if (selret < 0)
+ return selret;
}
#else
# ifdef HAS_TIO
@@ -571,10 +641,13 @@ zleread(char *lp, char *rp, int flags)
int old_errno = errno;
int tmout = getiparam("TMOUT");
-#ifdef HAVE_SELECT
+#if defined(HAVE_SELECT) || defined(HAVE_POLL)
long costmult;
+# ifdef HAVE_POLL
+# else
struct timeval tv;
fd_set foofd;
+# endif
baud = getiparam("BAUD");
costmult = (baud) ? 3840000L / baud : 0;
@@ -620,8 +693,10 @@ zleread(char *lp, char *rp, int flags)
zlereadflags = flags;
histline = curhist;
-#ifdef HAVE_SELECT
+#ifndef HAVE_POLL
+# ifdef HAVE_SELECT
FD_ZERO(&foofd);
+# endif
#endif
undoing = 1;
line = (unsigned char *)zalloc((linesz = 256) + 2);
@@ -683,7 +758,20 @@ zleread(char *lp, char *rp, int flags)
errflag = 1;
break;
}
-#ifdef HAVE_SELECT
+#ifdef HAVE_POLL
+ if (baud && !(lastcmd & ZLE_MENUCMP)) {
+ struct pollfd pfd;
+ int to = cost * costmult / 1000; /* milliseconds */
+
+ if (to > 500)
+ to = 500;
+ pfd.fd = SHTTY;
+ pfd.events = POLLIN;
+ if (!kungetct && poll(&pfd, 1, to) <= 0)
+ zrefresh();
+ } else
+#else
+# ifdef HAVE_SELECT
if (baud && !(lastcmd & ZLE_MENUCMP)) {
FD_SET(SHTTY, &foofd);
tv.tv_sec = 0;
@@ -693,6 +781,7 @@ zleread(char *lp, char *rp, int flags)
NULL, NULL, &tv) <= 0)
zrefresh();
} else
+# endif
#endif
if (!kungetct)
zrefresh();