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:
Yaping Li
2026-05-22 02:56:22 +00:00
parent 4d2bc332f3
commit ecf309cab8
13 changed files with 42 additions and 57 deletions
+5 -8
View File
@@ -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;
}
+3 -6
View File
@@ -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,
+2 -5
View File
@@ -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;
+4 -8
View File
@@ -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;
}
+1 -1
View File
@@ -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);
+3 -6
View File
@@ -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;
+12 -8
View File
@@ -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);
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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);
+4 -8
View File
@@ -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;
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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);