Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions src/uu/last/src/platform/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,23 +222,22 @@ impl Last {
ut_stack.push(*utmpx);
});

// "begins" is the time of the first record, whatever -n, --since and
// --until skip
let first_ut_time = ut_stack.first().map(|ut| {
let first_login_time = ut.login_time();
self.utmp_file_time(
first_login_time.unix_timestamp(),
first_login_time.nanosecond().into(),
)
});

let mut counter = 0;
let mut first_ut_time = None;
while let Some(ut) = ut_stack.pop() {
if ut.login_time() < self.since || ut.login_time() > self.until {
continue;
}

if ut_stack.is_empty() {
// By the end of loop we will have the earliest time
// (This avoids getting into issues with the compiler)
let first_login_time = ut.login_time();
first_ut_time = Some(self.utmp_file_time(
first_login_time.unix_timestamp(),
first_login_time.nanosecond().into(),
));
}

if counter >= self.limit && self.limit > 0 {
break;
}
Expand Down
25 changes: 21 additions & 4 deletions tests/by-util/test_last.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,17 @@ fn test_since_only_shows_entries_after_time() {
let expected_entry_time = "16:29";
let unexpected_entry_time = "16:24";

new_ucmd!()
let result = new_ucmd!()
.arg("--file")
.arg("last.input.1")
.arg("--since")
.arg("2025-03-08 16:28")
.succeeds()
.stdout_contains(expected_entry_time)
.stdout_does_not_contain(unexpected_entry_time);
.succeeds();

// The "begins" line after the entries shows the first record, 16:24:36
let entries = result.stdout_str().split("\n\n").next().unwrap();
assert!(entries.contains(expected_entry_time));
assert!(!entries.contains(unexpected_entry_time));
}

#[test]
Expand All @@ -169,3 +172,17 @@ fn test_until_only_shows_entries_before_time() {
.stdout_contains(expected_entry_time)
.stdout_does_not_contain(unexpected_entry_time);
}

#[test]
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "openbsd")))]
fn test_begins_is_the_first_record_when_records_are_skipped() {
for args in [&["-n", "1"][..], &["--since", "2025-03-08 16:28"][..]] {
new_ucmd!()
.env("TZ", "UTC")
.arg("--file")
.arg("last.input.1")
.args(args)
.succeeds()
.stdout_contains("last.input.1 begins Sat Mar 8 16:24:36 2025");
}
}
Loading