Set stdin to non-blocking mode early instead of in check_input.

Use term_raw instead of term_cbreak since the data we get has
already been expanded via OPOST.
This commit is contained in:
Todd C. Miller
2009-12-26 01:49:25 +00:00
parent 7a759cd2ac
commit 8fbdbde2f5

View File

@@ -154,7 +154,7 @@ static int stack_top;
extern time_t get_date __P((char *)); extern time_t get_date __P((char *));
extern char *get_timestr __P((time_t, int)); extern char *get_timestr __P((time_t, int));
extern int term_cbreak __P((int)); extern int term_raw __P((int, int, int));
extern int term_restore __P((int, int)); extern int term_restore __P((int, int));
extern void zero_bytes __P((volatile void *, size_t)); extern void zero_bytes __P((volatile void *, size_t));
void cleanup __P((int)); void cleanup __P((int));
@@ -179,7 +179,7 @@ main(argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
int ch, plen, ttyfd, interactive = 0, listonly = 0; int ch, plen, nready, interactive = 0, listonly = 0;
const char *id, *user = NULL, *pattern = NULL, *tty = NULL; const char *id, *user = NULL, *pattern = NULL, *tty = NULL;
char path[PATH_MAX], buf[LINE_MAX], *cp, *ep; char path[PATH_MAX], buf[LINE_MAX], *cp, *ep;
FILE *lfile; FILE *lfile;
@@ -188,6 +188,7 @@ main(argc, argv)
#else #else
FILE *tfile, *sfile; FILE *tfile, *sfile;
#endif #endif
fd_set *fdsr;
sigaction_t sa; sigaction_t sa;
unsigned long nbytes; unsigned long nbytes;
size_t len, nread; size_t len, nread;
@@ -282,7 +283,6 @@ main(argc, argv)
free(cp); free(cp);
fclose(lfile); fclose(lfile);
/* Set stdout to cbreak mode if it is a tty */
fflush(stdout); fflush(stdout);
zero_bytes(&sa, sizeof(sa)); zero_bytes(&sa, sizeof(sa));
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
@@ -297,11 +297,17 @@ main(argc, argv)
(void) sigaction(SIGTSTP, &sa, NULL); (void) sigaction(SIGTSTP, &sa, NULL);
(void) sigaction(SIGQUIT, &sa, NULL); (void) sigaction(SIGQUIT, &sa, NULL);
ttyfd = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0); /* Set stdin to raw mode if it is a tty */
if (ttyfd != -1) { interactive = isatty(STDIN_FILENO);
term_cbreak(ttyfd); if (interactive) {
interactive = isatty(STDOUT_FILENO); ch = fcntl(STDIN_FILENO, F_GETFL, 0);
if (ch != -1)
(void) fcntl(STDIN_FILENO, F_SETFL, ch | O_NONBLOCK);
if (!term_raw(STDIN_FILENO, 0, 1))
error(1, "cannot set tty to raw mode");
} }
fdsr = (fd_set *)emalloc2(howmany(STDOUT_FILENO + 1, NFDBITS),
sizeof(fd_mask));
/* /*
* Timing file consists of line of the format: "%f %d\n" * Timing file consists of line of the format: "%f %d\n"
@@ -323,7 +329,7 @@ main(argc, argv)
error(1, "invalid timing file byte count: %s", cp); error(1, "invalid timing file byte count: %s", cp);
if (interactive) if (interactive)
check_input(ttyfd, &speed); check_input(STDIN_FILENO, &speed);
/* Adjust delay using speed factor and clamp to max_wait */ /* Adjust delay using speed factor and clamp to max_wait */
to_wait = seconds / speed; to_wait = seconds / speed;
@@ -345,8 +351,19 @@ main(argc, argv)
do { do {
/* no stdio, must be unbuffered */ /* no stdio, must be unbuffered */
nwritten = write(STDOUT_FILENO, buf, nread); nwritten = write(STDOUT_FILENO, buf, nread);
if (nwritten == -1) if (nwritten == -1) {
if (errno == EINTR)
continue;
if (errno == EAGAIN) {
FD_SET(STDOUT_FILENO, fdsr);
do {
nready = select(STDOUT_FILENO + 1, fdsr, NULL, NULL, NULL);
} while (nready == -1 && errno == EINTR);
if (nready == 1)
continue;
}
error(1, "writing to standard output"); error(1, "writing to standard output");
}
nread -= nwritten; nread -= nwritten;
} while (nread); } while (nread);
} }
@@ -752,44 +769,39 @@ check_input(ttyfd, speed)
double *speed; double *speed;
{ {
fd_set *fdsr; fd_set *fdsr;
int flags, nready; int nready, paused = 0;
struct timeval tv; struct timeval tv;
char ch; char ch;
ssize_t n; ssize_t n;
fdsr = (fd_set *)emalloc2(howmany(ttyfd + 1, NFDBITS), sizeof(fd_mask)); fdsr = (fd_set *)emalloc2(howmany(ttyfd + 1, NFDBITS), sizeof(fd_mask));
FD_SET(ttyfd, fdsr);
tv.tv_sec = 0;
tv.tv_usec = 0;
nready = select(ttyfd + 1, fdsr, NULL, NULL, &tv); for (;;) {
if (nready == 1) { FD_SET(ttyfd, fdsr);
flags = fcntl(ttyfd, F_GETFL, 0); tv.tv_sec = 0;
if (flags != -1) tv.tv_usec = 0;
(void) fcntl(ttyfd, F_SETFL, flags | O_NONBLOCK);
do { nready = select(ttyfd + 1, fdsr, NULL, NULL, paused ? NULL : &tv);
n = read(ttyfd, &ch, 1); if (nready != 1)
if (n == 1) { break;
switch (ch) { n = read(ttyfd, &ch, 1);
case ' ': if (n == 1) {
/* wait for another character */ if (paused) {
if (flags != -1) paused = 0;
(void) fcntl(ttyfd, F_SETFL, flags); continue;
n = read(ttyfd, &ch, 1);
if (flags != -1)
(void) fcntl(ttyfd, F_SETFL, flags | O_NONBLOCK);
break;
case '<':
*speed /= 2;
break;
case '>':
*speed *= 2;
break;
}
} }
} while (n == 1); switch (ch) {
if (flags != -1) case ' ':
(void) fcntl(ttyfd, F_SETFL, flags); paused = 1;
break;
case '<':
*speed /= 2;
break;
case '>':
*speed *= 2;
break;
}
}
} }
free(fdsr); free(fdsr);
} }