mirror of
https://github.com/systemd/systemd.git
synced 2026-08-03 06:30:30 +00:00
Merge pull request #7549 from poettering/ptyfwd-fixes
pty forwarder fixes
This commit is contained in:
@@ -1085,6 +1085,9 @@ static int start_transient_service(
|
||||
return log_error_errno(r, "Failed to create PTY forwarder: %m");
|
||||
|
||||
pty_forward_set_handler(c.forward, pty_forward_handler, &c);
|
||||
|
||||
/* Make sure to process any TTY events before we process bus events */
|
||||
(void) pty_forward_set_priority(c.forward, SD_EVENT_PRIORITY_IMPORTANT);
|
||||
}
|
||||
|
||||
path = unit_dbus_path_from_name(service);
|
||||
@@ -1100,7 +1103,7 @@ static int start_transient_service(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add properties changed signal.");
|
||||
|
||||
r = sd_bus_attach_event(bus, c.event, 0);
|
||||
r = sd_bus_attach_event(bus, c.event, SD_EVENT_PRIORITY_NORMAL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to attach bus to event loop.");
|
||||
|
||||
|
||||
@@ -171,6 +171,30 @@ static bool ignore_vhangup(PTYForward *f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool drained(PTYForward *f) {
|
||||
int q = 0;
|
||||
|
||||
assert(f);
|
||||
|
||||
if (f->out_buffer_full > 0)
|
||||
return false;
|
||||
|
||||
if (f->master_readable)
|
||||
return false;
|
||||
|
||||
if (ioctl(f->master, TIOCINQ, &q) < 0)
|
||||
log_debug_errno(errno, "TIOCINQ failed on master: %m");
|
||||
else if (q > 0)
|
||||
return false;
|
||||
|
||||
if (ioctl(f->master, TIOCOUTQ, &q) < 0)
|
||||
log_debug_errno(errno, "TIOCOUTQ failed on master: %m");
|
||||
else if (q > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int shovel(PTYForward *f) {
|
||||
ssize_t k;
|
||||
|
||||
@@ -306,7 +330,7 @@ static int shovel(PTYForward *f) {
|
||||
|
||||
/* If we were asked to drain, and there's nothing more to handle from the master, then call the callback
|
||||
* too. */
|
||||
if (f->drain && f->out_buffer_full == 0 && !f->master_readable)
|
||||
if (f->drain && drained(f))
|
||||
return pty_forward_done(f, 0);
|
||||
|
||||
return 0;
|
||||
@@ -547,6 +571,28 @@ bool pty_forward_drain(PTYForward *f) {
|
||||
*/
|
||||
|
||||
f->drain = true;
|
||||
|
||||
return f->out_buffer_full == 0 && !f->master_readable;
|
||||
return drained(f);
|
||||
}
|
||||
|
||||
int pty_forward_set_priority(PTYForward *f, int64_t priority) {
|
||||
int r;
|
||||
assert(f);
|
||||
|
||||
r = sd_event_source_set_priority(f->stdin_event_source, priority);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_source_set_priority(f->stdout_event_source, priority);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_source_set_priority(f->master_event_source, priority);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_source_set_priority(f->sigwinch_event_source, priority);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,4 +54,6 @@ void pty_forward_set_handler(PTYForward *f, PTYForwardHandler handler, void *use
|
||||
|
||||
bool pty_forward_drain(PTYForward *f);
|
||||
|
||||
int pty_forward_set_priority(PTYForward *f, int64_t priority);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(PTYForward*, pty_forward_free);
|
||||
|
||||
Reference in New Issue
Block a user