Go back to dropping out of the select() loop when the process dies; Linux

ptys apparently don't behave the same as BSD in regards to select().
No need to flush remaining output to the transcript, only to stdout.
Add back code to check the master pty for additional data when we exit
the main select loop.
This commit is contained in:
Todd C. Miller
2009-09-20 13:51:51 +00:00
parent b008f3fda8
commit 7bb38284b0

View File

@@ -386,7 +386,7 @@ script_execv(path, argv)
sizeof(fd_mask));
zero_bytes(&input, sizeof(input));
zero_bytes(&output, sizeof(output));
for (;;) {
while (alive) {
if (input.off == input.len)
input.off = input.len = 0;
if (output.off == output.len)
@@ -394,16 +394,14 @@ script_execv(path, argv)
zero_bytes(fdsw, howmany(script_fds[SFD_MASTER] + 1, NFDBITS) * sizeof(fd_mask));
zero_bytes(fdsr, howmany(script_fds[SFD_MASTER] + 1, NFDBITS) * sizeof(fd_mask));
if (input.len != sizeof(input.buf))
FD_SET(STDIN_FILENO, fdsr);
if (output.len != sizeof(output.buf))
FD_SET(script_fds[SFD_MASTER], fdsr);
if (output.len > output.off)
FD_SET(STDOUT_FILENO, fdsw);
if (alive) {
if (input.len != sizeof(input.buf))
FD_SET(STDIN_FILENO, fdsr);
if (input.len > input.off)
FD_SET(script_fds[SFD_MASTER], fdsw);
}
if (input.len > input.off)
FD_SET(script_fds[SFD_MASTER], fdsw);
nready = select(script_fds[SFD_MASTER] + 1, fdsr, fdsw, NULL, NULL);
if (nready == -1) {
@@ -469,14 +467,28 @@ script_execv(path, argv)
}
}
/* Flush any remaining output. */
/* Flush any remaining output to stdout (already updated output file). */
n = fcntl(STDOUT_FILENO, F_GETFL, 0);
if (n != -1) {
n &= ~O_NONBLOCK;
(void) fcntl(STDOUT_FILENO, F_SETFL, n);
}
if (output.len > output.off) {
log_output(&output, output.len - output.off, &then, &now, ofile, tfile);
do {
n = write(STDOUT_FILENO, output.buf + output.off,
output.len - output.off);
if (n <= 0)
break;
output.off += n;
} while (output.len > output.off);
/* Make sure there is no output remaining on the master pty. */
for (;;) {
n = read(script_fds[SFD_MASTER], output.buf, sizeof(output.buf));
if (n <= 0)
break;
output.off = 0;
output.len = n;
log_output(&output, output.len, &then, &now, ofile, tfile);
do {
n = write(STDOUT_FILENO, output.buf + output.off,
output.len - output.off);
@@ -485,6 +497,7 @@ script_execv(path, argv)
output.off += n;
} while (output.len > output.off);
}
term_restore(STDIN_FILENO);
if (WIFEXITED(child_status))