write_callback: only enable /dev/tty reader if the command is running
This fixes a hang when there is /dev/tty data in a buffer to be flushed by the final call to del_io_events(). We do not want to re-enable the reader when flushing the buffers as part of pty_finish(). See PR #247 for analysis of the problem and how to reproduce it.
This commit is contained in:
@@ -447,10 +447,15 @@ write_callback(int fd, int what, void *v)
|
||||
ev_free_by_fd(evbase, fd);
|
||||
}
|
||||
}
|
||||
/* Enable reader if buffer is not full. */
|
||||
/*
|
||||
* Enable reader if buffer is not full but avoid reading
|
||||
* /dev/tty if the command is no longer running.
|
||||
*/
|
||||
if (iob->revent != NULL && iob->len != sizeof(iob->buf)) {
|
||||
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||
sudo_fatal("%s", U_("unable to add event to queue"));
|
||||
if (!USERTTY_EVENT(iob->revent) || iob->ec->cmnd_pid != -1) {
|
||||
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||
sudo_fatal("%s", U_("unable to add event to queue"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -469,10 +469,13 @@ write_callback(int fd, int what, void *v)
|
||||
ev_free_by_fd(evbase, fd);
|
||||
}
|
||||
}
|
||||
/* Enable reader if buffer is not full. */
|
||||
if (iob->revent != NULL &&
|
||||
(ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) {
|
||||
if (iob->len != sizeof(iob->buf)) {
|
||||
/*
|
||||
* Enable reader if buffer is not full but avoid reading /dev/tty
|
||||
* if not in raw mode or the command is no longer running.
|
||||
*/
|
||||
if (iob->revent != NULL && iob->len != sizeof(iob->buf)) {
|
||||
if (!USERTTY_EVENT(iob->revent) ||
|
||||
(ttymode == TERM_RAW && iob->ec->cmnd_pid != -1)) {
|
||||
if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
|
||||
sudo_fatal("%s", U_("unable to add event to queue"));
|
||||
}
|
||||
|
Reference in New Issue
Block a user