logind: let {session,user,seat}_get_idle_hint() return bool and always set output timestamp
These helpers returned int but in practice only ever produced 0/1. session_get_idle_hint() silently swallowed negative returns from get_tty_atime()/get_process_ctty_atime() and fell through to return false; user_get_idle_hint() and seat_get_idle_hint() propagated errors from session_get_idle_hint() that could no longer occur. Change all three to return bool and always set *t on non-NULL output. session_get_idle_hint() previously did not set *t on the !SESSION_CLASS_CAN_IDLE() early return; fix by defaulting *t at the top of the function. Callers that read *t after a false return now see DUAL_TIMESTAMP_NULL rather than uninitialized memory. Update all callers: drop dead < 0 error checks, drop > 0 coercion, drop DUAL_TIMESTAMP_NULL pre-init at sites that only pass &t to the helpers.
This commit is contained in:
@@ -447,7 +447,7 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret) {
|
||||
return !!u;
|
||||
}
|
||||
|
||||
int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
||||
bool manager_get_idle_hint(Manager *m, dual_timestamp *ret_timestamp) {
|
||||
Session *s;
|
||||
bool idle_hint;
|
||||
dual_timestamp ts;
|
||||
@@ -458,19 +458,16 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
||||
* unreasonable large idle periods starting with the Unix epoch. */
|
||||
ts = m->init_ts;
|
||||
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, t, /* flags= */ 0, UID_INVALID, NULL);
|
||||
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, /* since= */ NULL, /* flags= */ 0, UID_INVALID, NULL);
|
||||
|
||||
HASHMAP_FOREACH(s, m->sessions) {
|
||||
dual_timestamp k;
|
||||
int ih;
|
||||
bool ih;
|
||||
|
||||
if (!SESSION_CLASS_CAN_IDLE(s->class))
|
||||
continue;
|
||||
|
||||
ih = session_get_idle_hint(s, &k);
|
||||
if (ih < 0)
|
||||
return ih;
|
||||
|
||||
if (!ih) {
|
||||
if (!idle_hint) {
|
||||
if (k.monotonic < ts.monotonic)
|
||||
@@ -486,8 +483,8 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
|
||||
}
|
||||
}
|
||||
|
||||
if (t)
|
||||
*t = ts;
|
||||
if (ret_timestamp)
|
||||
*ret_timestamp = ts;
|
||||
|
||||
return idle_hint;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ static int property_get_idle_hint(
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, NULL) > 0);
|
||||
return sd_bus_message_append(reply, "b", manager_get_idle_hint(m, /* ret_timestamp= */ NULL));
|
||||
}
|
||||
|
||||
static int property_get_idle_since_hint(
|
||||
@@ -295,7 +295,7 @@ static int property_get_idle_since_hint(
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
dual_timestamp t = DUAL_TIMESTAMP_NULL;
|
||||
dual_timestamp t;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
@@ -701,10 +701,7 @@ static int method_list_sessions_ex(sd_bus_message *message, void *userdata, sd_b
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
r = session_get_idle_hint(s, &idle_ts);
|
||||
if (r < 0)
|
||||
return r;
|
||||
idle = r > 0;
|
||||
idle = session_get_idle_hint(s, &idle_ts);
|
||||
|
||||
r = sd_bus_message_append(reply, "(sussussbto)",
|
||||
s->id,
|
||||
|
||||
@@ -100,7 +100,7 @@ static int property_get_idle_hint(
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "b", seat_get_idle_hint(s, NULL) > 0);
|
||||
return sd_bus_message_append(reply, "b", seat_get_idle_hint(s, /* ret_timestamp= */ NULL));
|
||||
}
|
||||
|
||||
static int property_get_idle_since_hint(
|
||||
@@ -115,14 +115,11 @@ static int property_get_idle_since_hint(
|
||||
Seat *s = ASSERT_PTR(userdata);
|
||||
dual_timestamp t;
|
||||
uint64_t u;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = seat_get_idle_hint(s, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
seat_get_idle_hint(s, &t);
|
||||
|
||||
u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
|
||||
|
||||
|
||||
@@ -773,7 +773,7 @@ bool seat_can_graphical(Seat *s) {
|
||||
return seat_has_master_device(s);
|
||||
}
|
||||
|
||||
int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
|
||||
bool seat_get_idle_hint(Seat *s, dual_timestamp *ret_timestamp) {
|
||||
bool idle_hint = true;
|
||||
dual_timestamp ts = DUAL_TIMESTAMP_NULL;
|
||||
|
||||
@@ -781,12 +781,9 @@ int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
|
||||
|
||||
LIST_FOREACH(sessions_by_seat, session, s->sessions) {
|
||||
dual_timestamp k;
|
||||
int ih;
|
||||
bool ih;
|
||||
|
||||
ih = session_get_idle_hint(session, &k);
|
||||
if (ih < 0)
|
||||
return ih;
|
||||
|
||||
if (!ih) {
|
||||
if (!idle_hint) {
|
||||
if (k.monotonic > ts.monotonic)
|
||||
@@ -796,14 +793,13 @@ int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
|
||||
ts = k;
|
||||
}
|
||||
} else if (idle_hint) {
|
||||
|
||||
if (k.monotonic > ts.monotonic)
|
||||
ts = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (t)
|
||||
*t = ts;
|
||||
if (ret_timestamp)
|
||||
*ret_timestamp = ts;
|
||||
|
||||
return idle_hint;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ bool seat_can_tty(Seat *s);
|
||||
bool seat_has_master_device(Seat *s);
|
||||
bool seat_can_graphical(Seat *s);
|
||||
|
||||
int seat_get_idle_hint(Seat *s, dual_timestamp *t);
|
||||
bool seat_get_idle_hint(Seat *s, dual_timestamp *ret_timestamp);
|
||||
|
||||
int seat_start(Seat *s);
|
||||
int seat_stop(Seat *s, bool force);
|
||||
|
||||
@@ -117,7 +117,7 @@ static int property_get_idle_hint(
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "b", session_get_idle_hint(s, NULL) > 0);
|
||||
return sd_bus_message_append(reply, "b", session_get_idle_hint(s, /* ret_timestamp= */ NULL));
|
||||
}
|
||||
|
||||
static int property_get_can_idle(
|
||||
@@ -164,16 +164,13 @@ static int property_get_idle_since_hint(
|
||||
sd_bus_error *error) {
|
||||
|
||||
Session *s = ASSERT_PTR(userdata);
|
||||
dual_timestamp t = DUAL_TIMESTAMP_NULL;
|
||||
dual_timestamp t;
|
||||
uint64_t u;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = session_get_idle_hint(s, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
session_get_idle_hint(s, &t);
|
||||
|
||||
u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
|
||||
|
||||
|
||||
@@ -1153,19 +1153,23 @@ static int get_process_ctty_atime(pid_t pid, usec_t *atime) {
|
||||
return get_tty_atime(p, atime);
|
||||
}
|
||||
|
||||
int session_get_idle_hint(Session *s, dual_timestamp *t) {
|
||||
bool session_get_idle_hint(Session *s, dual_timestamp *ret_timestamp) {
|
||||
usec_t atime = 0, dtime = 0;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!SESSION_CLASS_CAN_IDLE(s->class))
|
||||
if (!SESSION_CLASS_CAN_IDLE(s->class)) {
|
||||
if (ret_timestamp)
|
||||
*ret_timestamp = DUAL_TIMESTAMP_NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Graphical sessions have an explicit idle hint */
|
||||
if (SESSION_TYPE_IS_GRAPHICAL(s->type)) {
|
||||
if (t)
|
||||
*t = s->idle_hint_timestamp;
|
||||
if (ret_timestamp)
|
||||
*ret_timestamp = s->idle_hint_timestamp;
|
||||
|
||||
return s->idle_hint;
|
||||
}
|
||||
@@ -1187,14 +1191,14 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
|
||||
}
|
||||
}
|
||||
|
||||
if (t)
|
||||
*t = DUAL_TIMESTAMP_NULL;
|
||||
if (ret_timestamp)
|
||||
*ret_timestamp = DUAL_TIMESTAMP_NULL;
|
||||
|
||||
return false;
|
||||
|
||||
found_atime:
|
||||
if (t)
|
||||
dual_timestamp_from_realtime(t, atime);
|
||||
if (ret_timestamp)
|
||||
dual_timestamp_from_realtime(ret_timestamp, atime);
|
||||
|
||||
if (s->manager->idle_action_usec > 0 && s->manager->stop_idle_session_usec != USEC_INFINITY)
|
||||
dtime = MIN(s->manager->idle_action_usec, s->manager->stop_idle_session_usec);
|
||||
|
||||
@@ -179,7 +179,7 @@ bool session_may_gc(Session *s, bool drop_not_started);
|
||||
void session_add_to_gc_queue(Session *s);
|
||||
int session_activate(Session *s);
|
||||
bool session_is_active(Session *s);
|
||||
int session_get_idle_hint(Session *s, dual_timestamp *t);
|
||||
bool session_get_idle_hint(Session *s, dual_timestamp *ret_timestamp);
|
||||
int session_set_idle_hint(Session *s, bool b);
|
||||
int session_get_locked_hint(Session *s);
|
||||
int session_set_locked_hint(Session *s, bool b);
|
||||
|
||||
@@ -144,7 +144,7 @@ static int property_get_idle_hint(
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "b", user_get_idle_hint(u, NULL) > 0);
|
||||
return sd_bus_message_append(reply, "b", user_get_idle_hint(u, /* ret_timestamp= */ NULL));
|
||||
}
|
||||
|
||||
static int property_get_idle_since_hint(
|
||||
@@ -163,7 +163,7 @@ static int property_get_idle_since_hint(
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
(void) user_get_idle_hint(u, &t);
|
||||
user_get_idle_hint(u, &t);
|
||||
k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
|
||||
|
||||
return sd_bus_message_append(reply, "t", k);
|
||||
|
||||
@@ -621,7 +621,7 @@ int user_finalize(User *u) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int user_get_idle_hint(User *u, dual_timestamp *t) {
|
||||
bool user_get_idle_hint(User *u, dual_timestamp *ret_timestamp) {
|
||||
bool idle_hint = true;
|
||||
dual_timestamp ts = DUAL_TIMESTAMP_NULL;
|
||||
|
||||
@@ -629,15 +629,12 @@ int user_get_idle_hint(User *u, dual_timestamp *t) {
|
||||
|
||||
LIST_FOREACH(sessions_by_user, s, u->sessions) {
|
||||
dual_timestamp k;
|
||||
int ih;
|
||||
bool ih;
|
||||
|
||||
if (!SESSION_CLASS_CAN_IDLE(s->class))
|
||||
continue;
|
||||
|
||||
ih = session_get_idle_hint(s, &k);
|
||||
if (ih < 0)
|
||||
return ih;
|
||||
|
||||
if (!ih) {
|
||||
if (!idle_hint) {
|
||||
if (k.monotonic < ts.monotonic)
|
||||
@@ -647,14 +644,13 @@ int user_get_idle_hint(User *u, dual_timestamp *t) {
|
||||
ts = k;
|
||||
}
|
||||
} else if (idle_hint) {
|
||||
|
||||
if (k.monotonic > ts.monotonic)
|
||||
ts = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (t)
|
||||
*t = ts;
|
||||
if (ret_timestamp)
|
||||
*ret_timestamp = ts;
|
||||
|
||||
return idle_hint;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ void user_add_to_gc_queue(User *u);
|
||||
int user_stop(User *u, bool force);
|
||||
int user_finalize(User *u);
|
||||
UserState user_get_state(User *u);
|
||||
int user_get_idle_hint(User *u, dual_timestamp *t);
|
||||
bool user_get_idle_hint(User *u, dual_timestamp *ret_timestamp);
|
||||
int user_save(User *u);
|
||||
int user_load(User *u);
|
||||
int user_kill(User *u, int signo);
|
||||
|
||||
+3
-2
@@ -1116,6 +1116,7 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
struct dual_timestamp since;
|
||||
usec_t n, elapse;
|
||||
bool idle;
|
||||
int r;
|
||||
|
||||
if (m->idle_action == HANDLE_IGNORE ||
|
||||
@@ -1124,8 +1125,8 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us
|
||||
|
||||
n = now(CLOCK_MONOTONIC);
|
||||
|
||||
r = manager_get_idle_hint(m, &since);
|
||||
if (r <= 0) {
|
||||
idle = manager_get_idle_hint(m, &since);
|
||||
if (!idle) {
|
||||
/* Not idle. Let's check if after a timeout it might be idle then. */
|
||||
elapse = n + m->idle_action_usec;
|
||||
m->was_idle = false;
|
||||
|
||||
+1
-1
@@ -159,7 +159,7 @@ int manager_spawn_autovt(Manager *m, unsigned vtnr);
|
||||
|
||||
bool manager_shall_kill(Manager *m, const char *user);
|
||||
|
||||
int manager_get_idle_hint(Manager *m, dual_timestamp *t);
|
||||
bool manager_get_idle_hint(Manager *m, dual_timestamp *ret_timestamp);
|
||||
|
||||
int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret);
|
||||
int manager_get_session_by_pidref(Manager *m, const PidRef *pid, Session **ret);
|
||||
|
||||
Reference in New Issue
Block a user