Really fix flushing of data in client_close().
Now that we call fmt_exit_message() from client_close() we do not need to try to determine whether the read or write events were pending in the old base. We can't tell anyway because the active flag in the event was cleared when the old sudo event base was destroyed. It is correct to enable both the read and write events after formatting the ExitMessage.
This commit is contained in:
@@ -845,6 +845,9 @@ sudo_ev_pending_v1(struct sudo_event *ev, short events, struct timespec *ts)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
debug_decl(sudo_ev_pending, SUDO_DEBUG_EVENT);
|
debug_decl(sudo_ev_pending, SUDO_DEBUG_EVENT);
|
||||||
|
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: event %p, flags 0x%x, events 0x%x",
|
||||||
|
__func__, ev, ev->flags, ev->events);
|
||||||
|
|
||||||
if (!ISSET(ev->flags, SUDO_EVQ_INSERTED))
|
if (!ISSET(ev->flags, SUDO_EVQ_INSERTED))
|
||||||
debug_return_int(0);
|
debug_return_int(0);
|
||||||
|
|
||||||
|
@@ -1396,13 +1396,16 @@ bool
|
|||||||
client_close(struct client_closure *closure, int exit_status, int error)
|
client_close(struct client_closure *closure, int exit_status, int error)
|
||||||
{
|
{
|
||||||
struct sudo_event_base *evbase = NULL;
|
struct sudo_event_base *evbase = NULL;
|
||||||
short events;
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
debug_decl(client_close, SUDOERS_DEBUG_UTIL);
|
debug_decl(client_close, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
if (closure->disabled)
|
if (closure->disabled)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
/* Format and append an ExitMessage to the write queue. */
|
||||||
|
if (!fmt_exit_message(closure, exit_status, error))
|
||||||
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create private event base and reparent the read/write events.
|
* Create private event base and reparent the read/write events.
|
||||||
* We cannot use the main sudo event loop as it has already exited.
|
* We cannot use the main sudo event loop as it has already exited.
|
||||||
@@ -1412,36 +1415,31 @@ client_close(struct client_closure *closure, int exit_status, int error)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
events = closure->read_ev->pending(closure->read_ev, SUDO_PLUGIN_EV_READ,
|
/* Enable read event to receive server messages. */
|
||||||
NULL);
|
|
||||||
closure->read_ev->setbase(closure->read_ev, evbase);
|
closure->read_ev->setbase(closure->read_ev, evbase);
|
||||||
if (events == SUDO_PLUGIN_EV_READ) {
|
|
||||||
if (closure->read_ev->add(closure->read_ev,
|
if (closure->read_ev->add(closure->read_ev,
|
||||||
&closure->log_details->server_timeout) == -1) {
|
&closure->log_details->server_timeout) == -1) {
|
||||||
sudo_warn(U_("unable to add event to queue"));
|
sudo_warn(U_("unable to add event to queue"));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
events = closure->write_ev->pending(closure->write_ev, SUDO_PLUGIN_EV_WRITE,
|
/* Enable the write event to write the ExitMessage. */
|
||||||
NULL);
|
|
||||||
closure->write_ev->setbase(closure->write_ev, evbase);
|
closure->write_ev->setbase(closure->write_ev, evbase);
|
||||||
if (events == SUDO_PLUGIN_EV_WRITE) {
|
|
||||||
if (closure->write_ev->add(closure->write_ev,
|
if (closure->write_ev->add(closure->write_ev,
|
||||||
&closure->log_details->server_timeout) == -1) {
|
&closure->log_details->server_timeout) == -1) {
|
||||||
sudo_warn(U_("unable to add event to queue"));
|
sudo_warn(U_("unable to add event to queue"));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Format and append an ExitMessage to the write queue. */
|
|
||||||
if (!fmt_exit_message(closure, exit_status, error))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Loop until queues are flushed and final commit point received. */
|
/* Loop until queues are flushed and final commit point received. */
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
"flushing buffers and waiting for final commit point");
|
"flushing buffers and waiting for final commit point");
|
||||||
ret = sudo_ev_dispatch(evbase) == 0;
|
if (sudo_ev_dispatch(evbase) == -1 || sudo_ev_got_break(evbase)) {
|
||||||
|
sudo_warnx(U_("error in event loop"));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
sudo_ev_base_free(evbase);
|
sudo_ev_base_free(evbase);
|
||||||
|
Reference in New Issue
Block a user