summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2009-06-10 14:03:19 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2009-06-10 14:03:19 +0000
commit987f22245254e4b288752cb99001225755832a5b (patch)
tree079ed750fefe68b2acab99baac906523a8dfad25
parentc802493e52978e3fe6b0ab0edcfce75a53660e19 (diff)
Use poll() instead of select(). The sscr_check_input() bit is
adapted from nvi 1.81. Tested by several people during the hackathon.
-rw-r--r--usr.bin/vi/cl/cl_read.c56
-rw-r--r--usr.bin/vi/ex/ex_script.c129
-rw-r--r--usr.bin/vi/include/ex_extern.h3
3 files changed, 110 insertions, 78 deletions
diff --git a/usr.bin/vi/cl/cl_read.c b/usr.bin/vi/cl/cl_read.c
index a1e61316ea4..6edc55197ea 100644
--- a/usr.bin/vi/cl/cl_read.c
+++ b/usr.bin/vi/cl/cl_read.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cl_read.c,v 1.16 2009/06/02 00:21:32 millert Exp $ */
+/* $OpenBSD: cl_read.c,v 1.17 2009/06/10 14:03:18 millert Exp $ */
/*-
* Copyright (c) 1993, 1994
@@ -17,15 +17,13 @@ static const char sccsid[] = "@(#)cl_read.c 10.15 (Berkeley) 9/24/96";
#include <sys/types.h>
#include <sys/queue.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
#include <sys/time.h>
#include <bitstring.h>
#include <curses.h>
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -142,27 +140,16 @@ cl_read(sp, flags, bp, blen, nrp, tp)
struct timeval *tp;
{
struct termios term1, term2;
- struct timeval poll;
CL_PRIVATE *clp;
GS *gp;
- SCR *tsp;
- fd_set *rdfd;
+ struct pollfd pfd[1];
input_t rval;
- int maxfd, nr, term_reset;
+ int nr, term_reset, timeout;
gp = sp->gp;
clp = CLP(sp);
term_reset = 0;
- /* Allocate space for rdfd. */
- maxfd = STDIN_FILENO;
- CIRCLEQ_FOREACH(tsp, &gp->dq, q)
- if (F_ISSET(tsp, SC_SCRIPT) && tsp->script->sh_master > maxfd)
- maxfd = tsp->script->sh_master;
- rdfd = (fd_set *)calloc(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask));
- if (rdfd == NULL)
- goto err;
-
/*
* 1: A read from a file or a pipe. In this case, the reads
* never timeout regardless. This means that we can hang
@@ -172,13 +159,11 @@ cl_read(sp, flags, bp, blen, nrp, tp)
if (!F_ISSET(clp, CL_STDIN_TTY)) {
switch (nr = read(STDIN_FILENO, bp, blen)) {
case 0:
- free(rdfd);
return (INP_EOF);
case -1:
goto err;
default:
*nrp = nr;
- free(rdfd);
return (INP_OK);
}
/* NOTREACHED */
@@ -190,15 +175,11 @@ cl_read(sp, flags, bp, blen, nrp, tp)
*/
tty_retry:
if (tp != NULL) {
- memset(rdfd, 0, howmany(STDIN_FILENO + 1, NFDBITS)
- * sizeof(fd_mask));
- poll.tv_sec = 0;
- poll.tv_usec = 0;
- FD_SET(STDIN_FILENO, rdfd);
- switch (select(STDIN_FILENO + 1,
- rdfd, NULL, NULL, tp == NULL ? &poll : tp)) {
+ pfd[0].fd = STDIN_FILENO;
+ pfd[0].events = POLLIN;
+ timeout = tp ? (tp->tv_sec * 1000) + (tp->tv_usec / 1000) : 0;
+ switch (poll(pfd, 1, timeout)) {
case 0:
- free(rdfd);
return (INP_TIMEOUT);
case -1:
goto err;
@@ -238,26 +219,8 @@ tty_retry:
* the only way to keep from locking out scripting windows.
*/
if (F_ISSET(gp, G_SCRWIN)) {
-loop: memset(rdfd, 0, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));
- FD_SET(STDIN_FILENO, rdfd);
- CIRCLEQ_FOREACH(tsp, &gp->dq, q)
- if (F_ISSET(tsp, SC_SCRIPT))
- FD_SET(tsp->script->sh_master, rdfd);
- switch (select(maxfd + 1, rdfd, NULL, NULL, NULL)) {
- case 0:
- abort();
- case -1:
+ if (sscr_check_input(sp))
goto err;
- default:
- break;
- }
- if (!FD_ISSET(STDIN_FILENO, rdfd)) {
- if (sscr_input(sp)) {
- free(rdfd);
- return (INP_ERR);
- }
- goto loop;
- }
}
/*
@@ -316,7 +279,6 @@ err: if (errno == EINTR)
/* Restore the terminal state if it was modified. */
if (term_reset)
(void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &term1);
- free(rdfd);
return (rval);
}
diff --git a/usr.bin/vi/ex/ex_script.c b/usr.bin/vi/ex/ex_script.c
index 7852b7b7344..ec0eaa943a4 100644
--- a/usr.bin/vi/ex/ex_script.c
+++ b/usr.bin/vi/ex/ex_script.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ex_script.c,v 1.14 2007/09/02 15:19:35 deraadt Exp $ */
+/* $OpenBSD: ex_script.c,v 1.15 2009/06/10 14:03:18 millert Exp $ */
/*-
* Copyright (c) 1992, 1993, 1994
@@ -21,9 +21,6 @@ static const char sccsid[] = "@(#)ex_script.c 10.30 (Berkeley) 9/24/96";
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/queue.h>
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
#include <sys/stat.h>
#ifdef HAVE_SYS5_PTY
#include <sys/stropts.h>
@@ -367,6 +364,73 @@ err1: rval = 1;
}
/*
+ * sscr_check_input -
+ * Check for input from command input or scripting windows.
+ *
+ * PUBLIC: int sscr_check_input(SCR *sp);
+ */
+int
+sscr_check_input(SCR *sp)
+{
+ GS *gp;
+ SCR *tsp;
+ struct pollfd *pfd;
+ int nfds, rval;
+
+ gp = sp->gp;
+ rval = 0;
+
+ /* Allocate space for pfd. */
+ nfds = 1;
+ CIRCLEQ_FOREACH(tsp, &gp->dq, q)
+ if (F_ISSET(sp, SC_SCRIPT))
+ nfds++;
+ pfd = calloc(nfds, sizeof(struct pollfd));
+ if (pfd == NULL) {
+ msgq(sp, M_SYSERR, "malloc");
+ return (1);
+ }
+
+ /* Setup events bitmasks. */
+ pfd[0].fd = STDIN_FILENO;
+ pfd[0].events = POLLIN;
+ nfds = 1;
+ CIRCLEQ_FOREACH(tsp, &gp->dq, q)
+ if (F_ISSET(sp, SC_SCRIPT)) {
+ pfd[nfds].fd = sp->script->sh_master;
+ pfd[nfds].events = POLLIN;
+ nfds++;
+ }
+
+loop:
+ /* Check for input. */
+ switch (poll(pfd, nfds, INFTIM)) {
+ case -1:
+ msgq(sp, M_SYSERR, "poll");
+ rval = 1;
+ /* FALLTHROUGH */
+ case 0:
+ goto done;
+ default:
+ break;
+ }
+
+ /* Only insert from the scripting windows if no command input */
+ if (!(pfd[0].revents & POLLIN)) {
+ nfds = 1;
+ CIRCLEQ_FOREACH(tsp, &gp->dq, q)
+ if (F_ISSET(sp, SC_SCRIPT)) {
+ if ((pfd[nfds++].revents & POLLIN) && sscr_insert(sp))
+ goto done;
+ }
+ goto loop;
+ }
+done:
+ free(pfd);
+ return (rval);
+}
+
+/*
* sscr_input --
* Read any waiting shell input.
*
@@ -377,53 +441,58 @@ sscr_input(sp)
SCR *sp;
{
GS *gp;
- struct timeval tv;
- fd_set *rdfd;
- int maxfd;
+ struct pollfd *pfd;
+ int nfds, rval;
gp = sp->gp;
+ rval = 0;
- /* Allocate space for rdfd. */
- maxfd = STDIN_FILENO;
+ /* Allocate space for pfd. */
+ nfds = 0;
CIRCLEQ_FOREACH(sp, &gp->dq, q)
- if (F_ISSET(sp, SC_SCRIPT) && sp->script->sh_master > maxfd)
- maxfd = sp->script->sh_master;
- rdfd = (fd_set *)calloc(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask));
- if (rdfd == NULL) {
+ if (F_ISSET(sp, SC_SCRIPT))
+ nfds++;
+ if (nfds == 0)
+ return (0);
+ pfd = calloc(nfds, sizeof(struct pollfd));
+ if (pfd == NULL) {
msgq(sp, M_SYSERR, "malloc");
return (1);
}
-loop: memset(rdfd, 0, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- /* Set up the input mask. */
+ /* Setup events bitmasks. */
+ nfds = 0;
CIRCLEQ_FOREACH(sp, &gp->dq, q)
- if (F_ISSET(sp, SC_SCRIPT))
- FD_SET(sp->script->sh_master, rdfd);
+ if (F_ISSET(sp, SC_SCRIPT)) {
+ pfd[nfds].fd = sp->script->sh_master;
+ pfd[nfds].events = POLLIN;
+ nfds++;
+ }
+loop:
/* Check for input. */
- switch (select(maxfd + 1, rdfd, NULL, NULL, &tv)) {
+ switch (poll(pfd, nfds, 0)) {
case -1:
- msgq(sp, M_SYSERR, "select");
- free(rdfd);
- return (1);
+ msgq(sp, M_SYSERR, "poll");
+ rval = 1;
+ /* FALLTHROUGH */
case 0:
- free(rdfd);
- return (0);
+ goto done;
default:
break;
}
/* Read the input. */
+ nfds = 0;
CIRCLEQ_FOREACH(sp, &gp->dq, q)
- if (F_ISSET(sp, SC_SCRIPT) &&
- FD_ISSET(sp->script->sh_master, rdfd) && sscr_insert(sp)) {
- free(rdfd);
- return (1);
+ if (F_ISSET(sp, SC_SCRIPT)) {
+ if ((pfd[nfds++].revents & POLLIN) && sscr_insert(sp))
+ goto done;
}
goto loop;
+done:
+ free(pfd);
+ return (rval);
}
/*
diff --git a/usr.bin/vi/include/ex_extern.h b/usr.bin/vi/include/ex_extern.h
index 51141e8d208..6d2835bfdcd 100644
--- a/usr.bin/vi/include/ex_extern.h
+++ b/usr.bin/vi/include/ex_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ex_extern.h,v 1.8 2002/06/12 06:07:17 mpech Exp $ */
+/* $OpenBSD: ex_extern.h,v 1.9 2009/06/10 14:03:18 millert Exp $ */
int ex(SCR **);
int ex_cmd(SCR *);
@@ -73,6 +73,7 @@ int ex_resize(SCR *, EXCMD *);
int ex_sdisplay(SCR *);
int ex_script(SCR *, EXCMD *);
int sscr_exec(SCR *, recno_t);
+int sscr_check_input(SCR *);
int sscr_input(SCR *);
int sscr_end(SCR *);
int ex_set(SCR *, EXCMD *);