/* Handle a read or write on *FD, which is the pty if FD_IS_PTY
is true, that returned end-of-file or error indication RETVAL.
The system call is named CALL, for use in error messages.
- Returns true if processing may continue, false if we're all
- done. */
-static bool
+ Sets *FD to -1 if the fd is no longer readable or writable. */
+static void
handle_error (ssize_t retval, int *fd, bool fd_is_pty, const char *call)
{
if (fd_is_pty)
if (errno == EIO)
{
/* Slave side of pty has been closed. */
- return false;
+ *fd = -1;
}
else
fail_io (call);
}
- else
- return true;
}
else
{
{
close (*fd);
*fd = -1;
- return true;
}
else
fail_io (call);
pipes[1].in = pty;
pipes[1].out = STDOUT_FILENO;
- while (pipes[0].in != -1 || pipes[1].in != -1)
+ while (pipes[1].in != -1)
{
fd_set read_fds, write_fds;
int retval;
fail_io ("select");
if (FD_ISSET (dead_child_fd, &read_fds))
- {
- /* Child died. Do final relaying. */
- struct pipe *p = &pipes[1];
- if (p->out == -1)
- return;
- make_nonblocking (STDOUT_FILENO, false);
- for (;;)
- {
- ssize_t n;
-
- /* Write buffer. */
- while (p->size > 0)
- {
- n = write (p->out, p->buf + p->ofs, p->size);
- if (n < 0)
- fail_io ("write");
- else if (n == 0)
- fail_io ("zero-length write");
- p->ofs += n;
- p->size -= n;
- }
- p->ofs = 0;
-
- p->size = n = read (p->in, p->buf, sizeof p->buf);
- if (n <= 0)
- return;
- }
- }
+ break;
for (i = 0; i < 2; i++)
{
p->ofs = 0;
}
}
- else if (!handle_error (n, &p->in, p->in == pty, "read"))
- return;
+ else
+ handle_error (n, &p->in, p->in == pty, "read");
}
if (p->out != -1 && FD_ISSET (p->out, &write_fds))
{
if (p->size == 0)
p->ofs = 0;
}
- else if (!handle_error (n, &p->out, p->out == pty, "write"))
- return;
+ else
+ handle_error (n, &p->out, p->out == pty, "write");
}
}
}
+
+ if (pipes[1].out == -1)
+ return;
+
+ make_nonblocking (STDOUT_FILENO, false);
+ for (;;)
+ {
+ struct pipe *p = &pipes[1];
+ ssize_t n;
+
+ /* Write buffer. */
+ while (p->size > 0)
+ {
+ n = write (p->out, p->buf + p->ofs, p->size);
+ if (n < 0)
+ fail_io ("write");
+ else if (n == 0)
+ fail_io ("zero-length write");
+ p->ofs += n;
+ p->size -= n;
+ }
+ p->ofs = 0;
+
+ p->size = n = read (p->in, p->buf, sizeof p->buf);
+ if (n <= 0)
+ return;
+ }
}
static int dead_child_fd;