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:
92
sudoreplay.c
92
sudoreplay.c
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user