diff options
author | Peter Elliott <pelliott@ualberta.ca> | 2021-10-10 16:04:14 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-17 22:18:48 +0200 |
commit | 92b6e4fd767145d3bfc408fe036cdf63e09a9d89 (patch) | |
tree | 9092030b4bd19c143fdf0a29fd19fbb47c69dcde /Userland | |
parent | 7283b0b2141222af43419acb0c1c0c22804a70f4 (diff) | |
download | serenity-92b6e4fd767145d3bfc408fe036cdf63e09a9d89.zip |
TaskBar+Utilities: Add logout(1) command, and call it in ShutdownDialog
logout kills the session that SystemServer --user was started with.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Services/Taskbar/ShutdownDialog.cpp | 2 | ||||
-rw-r--r-- | Userland/Utilities/logout.cpp | 62 |
2 files changed, 63 insertions, 1 deletions
diff --git a/Userland/Services/Taskbar/ShutdownDialog.cpp b/Userland/Services/Taskbar/ShutdownDialog.cpp index 35aab6c854..7d6cb8b1b7 100644 --- a/Userland/Services/Taskbar/ShutdownDialog.cpp +++ b/Userland/Services/Taskbar/ShutdownDialog.cpp @@ -26,7 +26,7 @@ struct Option { static const Vector<Option> options = { { "Power off computer", { "/bin/shutdown", "--now", nullptr }, true, true }, { "Reboot", { "/bin/reboot", nullptr }, true, false }, - { "Log out", {}, false, false }, + { "Log out", { "/bin/logout", nullptr }, true, false }, }; Vector<char const*> ShutdownDialog::show() diff --git a/Userland/Utilities/logout.cpp b/Userland/Utilities/logout.cpp new file mode 100644 index 0000000000..0aedb63953 --- /dev/null +++ b/Userland/Utilities/logout.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021, Peter Elliott <pelliott@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <LibCore/ProcessStatisticsReader.h> +#include <signal.h> + +static Core::ProcessStatistics const& get_proc(Core::AllProcessesStatistics const& stats, pid_t pid) +{ + for (auto& proc : stats.processes) { + if (proc.pid == pid) + return proc; + } + VERIFY_NOT_REACHED(); +} + +int main(int, char**) +{ + if (pledge("stdio proc rpath", nullptr) < 0) { + perror("pledge"); + return 1; + } + + if (unveil("/proc/all", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/etc/passwd", "r") < 0) { + perror("unveil"); + return 1; + } + + unveil(nullptr, nullptr); + + // logout finds the highest session up all nested sessions, and kills it. + auto stats = Core::ProcessStatisticsReader::get_all(); + if (!stats.has_value()) { + warnln("couldn't get process statistics"); + return 1; + } + + pid_t sid = getsid(0); + while (true) { + pid_t parent = get_proc(stats.value(), sid).ppid; + pid_t parent_sid = get_proc(stats.value(), parent).sid; + + if (parent_sid == 0) + break; + + sid = parent_sid; + } + + if (kill(-sid, SIGTERM) == -1) { + perror("kill(2)"); + return 1; + } + + return 0; +} |