Skip to content

Commit 54b9aa6

Browse files
ebannerAtkinsSJ
authored andcommitted
uptime: Add number of users (active terminal sessions)
The number of users is fetched from /var/run/utmp.
1 parent dd7666e commit 54b9aa6

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

Userland/Utilities/uptime.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* SPDX-License-Identifier: BSD-2-Clause
77
*/
88

9+
#include <AK/JsonObject.h>
910
#include <AK/NumberFormat.h>
1011
#include <LibCore/ArgsParser.h>
1112
#include <LibCore/DateTime.h>
@@ -25,9 +26,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
2526
args_parser.add_option(output_since, "Show when the system is up since, in yyyy-mm-dd HH:MM:SS format", "since", 's');
2627
args_parser.parse(arguments);
2728

28-
auto file = TRY(Core::File::open("/sys/kernel/uptime"sv, Core::File::OpenMode::Read));
29+
TRY(Core::System::unveil("/sys/kernel/uptime"sv, "r"sv));
30+
TRY(Core::System::unveil("/var/run/utmp"sv, "r"sv));
31+
TRY(Core::System::unveil(nullptr, nullptr));
2932

30-
TRY(Core::System::pledge("stdio"));
33+
auto file = TRY(Core::File::open("/sys/kernel/uptime"sv, Core::File::OpenMode::Read));
3134

3235
Array<u8, BUFSIZ> buffer;
3336
auto read_buffer = TRY(file->read_some(buffer));
@@ -44,9 +47,20 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
4447
outln("Up {}", human_readable_time(seconds));
4548
} else {
4649
auto current_time = TRY(Core::DateTime::now().to_string());
47-
// FIXME: To match Linux and the BSDs, we should also include the number of current users,
48-
// and some load averages, but these don't seem to be available yet.
49-
outln("{} up {}", current_time, human_readable_digital_time(seconds));
50+
// FIXME: To match Linux and the BSDs, we should also include
51+
// some load averages, but these don't seem to be available yet.
52+
53+
auto utmp_file = TRY(Core::File::open("/var/run/utmp"sv, Core::File::OpenMode::Read));
54+
auto utmp_contents = TRY(utmp_file->read_until_eof());
55+
auto json = TRY(AK::JsonValue::from_string(utmp_contents));
56+
auto object = json.as_object();
57+
auto user_count = object.size();
58+
59+
if (user_count == 1) {
60+
outln("{} up {}, {} user", current_time, human_readable_digital_time(seconds), user_count);
61+
} else {
62+
outln("{} up {}, {} users", current_time, human_readable_digital_time(seconds), user_count);
63+
}
5064
}
5165

5266
return 0;

0 commit comments

Comments
 (0)