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:
22
src/script.c
22
src/script.c
@@ -433,7 +433,8 @@ perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
|
|||||||
break;
|
break;
|
||||||
} else if (n == 0) {
|
} else if (n == 0) {
|
||||||
/* got EOF */
|
/* got EOF */
|
||||||
close(iob->rfd);
|
if (iob->rfd != script_fds[SFD_USERTTY])
|
||||||
|
close(iob->rfd);
|
||||||
iob->rfd = -1;
|
iob->rfd = -1;
|
||||||
} else {
|
} else {
|
||||||
if (!iob->action(iob->buf + iob->len, n))
|
if (!iob->action(iob->buf + iob->len, n))
|
||||||
@@ -450,10 +451,12 @@ perform_io(struct io_buffer *iobufs, fd_set *fdsr, fd_set *fdsw)
|
|||||||
if (errno == EPIPE) {
|
if (errno == EPIPE) {
|
||||||
/* other end of pipe closed */
|
/* other end of pipe closed */
|
||||||
if (iob->rfd != -1) {
|
if (iob->rfd != -1) {
|
||||||
close(iob->rfd);
|
if (iob->rfd != script_fds[SFD_USERTTY])
|
||||||
|
close(iob->rfd);
|
||||||
iob->rfd = -1;
|
iob->rfd = -1;
|
||||||
}
|
}
|
||||||
close(iob->wfd);
|
if (iob->wfd != script_fds[SFD_USERTTY])
|
||||||
|
close(iob->wfd);
|
||||||
iob->wfd = -1;
|
iob->wfd = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1173,7 +1176,7 @@ flush_output(struct io_buffer *iobufs)
|
|||||||
struct io_buffer *iob;
|
struct io_buffer *iob;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set *fdsr, *fdsw;
|
fd_set *fdsr, *fdsw;
|
||||||
int nready, maxfd = -1;
|
int nready, nwriters, maxfd = -1;
|
||||||
|
|
||||||
/* Determine maxfd */
|
/* Determine maxfd */
|
||||||
for (iob = iobufs; iob; iob = iob->next) {
|
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(fdsw, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));
|
||||||
zero_bytes(fdsr, 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) {
|
for (iob = iobufs; iob; iob = iob->next) {
|
||||||
/* Don't read from /dev/tty while flushing. */
|
/* 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;
|
continue;
|
||||||
if (iob->rfd == -1 && iob->wfd == -1)
|
if (iob->rfd == -1 && iob->wfd == -1)
|
||||||
continue;
|
continue;
|
||||||
@@ -1209,15 +1213,17 @@ flush_output(struct io_buffer *iobufs)
|
|||||||
FD_SET(iob->rfd, fdsr);
|
FD_SET(iob->rfd, fdsr);
|
||||||
}
|
}
|
||||||
if (iob->wfd != -1) {
|
if (iob->wfd != -1) {
|
||||||
if (iob->len > iob->off)
|
if (iob->len > iob->off) {
|
||||||
|
nwriters++;
|
||||||
FD_SET(iob->wfd, fdsw);
|
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_sec = 0;
|
||||||
tv.tv_usec = 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) {
|
||||||
if (nready == 0)
|
if (nready == 0)
|
||||||
break; /* all I/O flushed */
|
break; /* all I/O flushed */
|
||||||
|
Reference in New Issue
Block a user