Additional checks to make sure we don't close /dev/tty by mistake.

When flushing, sleep in select as long as we have buffers that need
to be written out.
This commit is contained in:
Todd C. Miller
2010-05-18 18:50:20 -04:00
parent 6a2a182e0f
commit 0eec7335af

View File

@@ -433,6 +433,7 @@ perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
break;
} else if (n == 0) {
/* got EOF */
if (iob->rfd != script_fds[SFD_USERTTY])
close(iob->rfd);
iob->rfd = -1;
} else {
@@ -450,9 +451,11 @@ perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
if (errno == EPIPE) {
/* other end of pipe closed */
if (iob->rfd != -1) {
if (iob->rfd != script_fds[SFD_USERTTY])
close(iob->rfd);
iob->rfd = -1;
}
if (iob->wfd != script_fds[SFD_USERTTY])
close(iob->wfd);
iob->wfd = -1;
continue;
@@ -1173,7 +1176,7 @@ flush_output(struct io_buffer *iobufs)
struct io_buffer *iob;
struct timeval tv;
fd_set *fdsr, *fdsw;
int nready, maxfd = -1;
int nready, nwriters, maxfd = -1;
/* Determine maxfd */
for (iob = iobufs; iob; iob = iob->next) {
@@ -1189,9 +1192,10 @@ flush_output(struct io_buffer *iobufs)
zero_bytes(fdsw, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));
zero_bytes(fdsr, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));
nwriters = 0;
for (iob = iobufs; iob; iob = iob->next) {
/* Don't read from /dev/tty while flushing. */
if (iob->rfd == script_fds[SFD_USERTTY])
if (script_fds[SFD_USERTTY] != -1 && iob->rfd == script_fds[SFD_USERTTY])
continue;
if (iob->rfd == -1 && iob->wfd == -1)
continue;
@@ -1209,15 +1213,17 @@ flush_output(struct io_buffer *iobufs)
FD_SET(iob->rfd, fdsr);
}
if (iob->wfd != -1) {
if (iob->len > iob->off)
if (iob->len > iob->off) {
nwriters++;
FD_SET(iob->wfd, fdsw);
}
}
}
/* Effect a poll (no sleeping in select) */
/* Don't sleep in select if there are no buffers that need writing. */
tv.tv_sec = 0;
tv.tv_usec = 0;
nready = select(maxfd + 1, fdsr, fdsw, NULL, &tv);
nready = select(maxfd + 1, fdsr, fdsw, NULL, nwriters ? NULL : &tv);
if (nready <= 0) {
if (nready == 0)
break; /* all I/O flushed */