diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2009-06-10 14:03:19 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2009-06-10 14:03:19 +0000 |
commit | 987f22245254e4b288752cb99001225755832a5b (patch) | |
tree | 079ed750fefe68b2acab99baac906523a8dfad25 | |
parent | c802493e52978e3fe6b0ab0edcfce75a53660e19 (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.c | 56 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_script.c | 129 | ||||
-rw-r--r-- | usr.bin/vi/include/ex_extern.h | 3 |
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 *); |