Only set user's tty to blocking mode when doing the final flush.
Flush pipes as well as pty master when the process is done.
This commit is contained in:
58
src/script.c
58
src/script.c
@@ -704,12 +704,10 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
|
|||||||
|
|
||||||
if (log_io) {
|
if (log_io) {
|
||||||
/* Flush any remaining output (the plugin already got it) */
|
/* Flush any remaining output (the plugin already got it) */
|
||||||
for (iob = iobufs; iob; iob = iob->next) {
|
n = fcntl(script_fds[SFD_USERTTY], F_GETFL, 0);
|
||||||
n = fcntl(iob->wfd, F_GETFL, 0);
|
if (n != -1 && ISSET(n, O_NONBLOCK)) {
|
||||||
if (n != -1 && ISSET(n, O_NONBLOCK)) {
|
CLR(n, O_NONBLOCK);
|
||||||
CLR(n, O_NONBLOCK);
|
(void) fcntl(script_fds[SFD_USERTTY], F_SETFL, n);
|
||||||
(void) fcntl(iob->wfd, F_SETFL, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
flush_output(iobufs);
|
flush_output(iobufs);
|
||||||
|
|
||||||
@@ -1008,11 +1006,13 @@ bad:
|
|||||||
static void
|
static void
|
||||||
flush_output(struct io_buffer *iobufs)
|
flush_output(struct io_buffer *iobufs)
|
||||||
{
|
{
|
||||||
struct io_buffer *iob, output;
|
struct io_buffer *iob;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
/* XXX - really only want to flush output buffers, does it matter? */
|
/* Drain output buffers. */
|
||||||
for (iob = iobufs; iob; iob = iob->next) {
|
for (iob = iobufs; iob; iob = iob->next) {
|
||||||
|
if (iob->rfd == script_fds[SFD_USERTTY])
|
||||||
|
continue;
|
||||||
while (iob->len > iob->off) {
|
while (iob->len > iob->off) {
|
||||||
n = write(iob->wfd, iob->buf + iob->off, iob->len - iob->off);
|
n = write(iob->wfd, iob->buf + iob->off, iob->len - iob->off);
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
@@ -1021,23 +1021,33 @@ flush_output(struct io_buffer *iobufs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure there is no output remaining on the master pty. */
|
/* Make sure there is no output remaining on the master pty or in pipes. */
|
||||||
/* XXX - pipes too? */
|
for (iob = iobufs; iob; iob = iob->next) {
|
||||||
for (;;) {
|
if (iob->rfd == script_fds[SFD_USERTTY])
|
||||||
n = read(script_fds[SFD_MASTER], output.buf, sizeof(output.buf));
|
continue;
|
||||||
if (n <= 0)
|
|
||||||
break;
|
for (;;) {
|
||||||
/* XXX */
|
n = read(iob->rfd, iob->buf + iob->len,
|
||||||
log_output(output.buf, n);
|
sizeof(iob->buf) - iob->len);
|
||||||
output.off = 0;
|
if (n <= 0) {
|
||||||
output.len = n;
|
if (n == -1 && errno == EINTR)
|
||||||
do {
|
continue;
|
||||||
n = write(script_fds[SFD_USERTTY], output.buf + output.off,
|
|
||||||
output.len - output.off);
|
|
||||||
if (n <= 0)
|
|
||||||
break;
|
break;
|
||||||
output.off += n;
|
}
|
||||||
} while (output.len > output.off);
|
if (!iob->action(iob->buf + iob->len, n))
|
||||||
|
break;
|
||||||
|
iob->len += n;
|
||||||
|
|
||||||
|
do {
|
||||||
|
n = write(iob->wfd, iob->buf + iob->off, iob->len - iob->off);
|
||||||
|
if (n <= 0) {
|
||||||
|
if (n == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iob->off += n;
|
||||||
|
} while (iob->len > iob->off);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user