feat: add inherited sessions and desktop session teardown
This commit is contained in:
@@ -895,6 +895,11 @@ static bool existing_desktop_running() {
|
||||
}
|
||||
|
||||
extern "C" void _start() {
|
||||
// External applications and all of their descendants inherit this stable
|
||||
// desktop-session ID. login.elf uses it to tear down the complete session
|
||||
// after Log Out, Shutdown, or Reboot returns control to the supervisor.
|
||||
montauk::setsession();
|
||||
|
||||
if (existing_desktop_running()) {
|
||||
gui::dialogs::message_box(
|
||||
"Desktop Already Running",
|
||||
|
||||
@@ -40,6 +40,8 @@ enum SessionMode {
|
||||
SESSION_CONSOLE,
|
||||
};
|
||||
|
||||
void terminate_desktop_session(int session_id);
|
||||
|
||||
struct LoginState {
|
||||
gui::Framebuffer fb;
|
||||
int screen_w, screen_h;
|
||||
|
||||
@@ -63,6 +63,9 @@ void launch_session(LoginState* ls) {
|
||||
if (pid >= 0) {
|
||||
montauk::setuser(pid, ls->username);
|
||||
montauk::waitpid(pid);
|
||||
if (ls->session_mode == SESSION_DESKTOP) {
|
||||
terminate_desktop_session(pid);
|
||||
}
|
||||
}
|
||||
|
||||
// The desktop hands off a graceful power-off by posting a request and
|
||||
@@ -99,6 +102,21 @@ gui::Rect login_field_rect(const LoginLayout& lo, LoginState* ls, int idx) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void terminate_desktop_session(int session_id) {
|
||||
if (session_id < 0) return;
|
||||
|
||||
// Killing is asynchronous because a member may currently be executing on
|
||||
// another CPU or inside a syscall. Repeat until the kernel observes the
|
||||
// session empty; no member can spawn another process after that point.
|
||||
//
|
||||
|
||||
const int timeout_ms = 2000;
|
||||
for (int waited = 0; waited < timeout_ms; waited++) {
|
||||
if (montauk::killsession(session_id) <= 0) return;
|
||||
montauk::sleep_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
LoginField get_field(LoginState* ls, int field) {
|
||||
if (ls->mode == MODE_FIRST_BOOT) {
|
||||
switch (field) {
|
||||
|
||||
@@ -29,6 +29,7 @@ static void maybe_run_setup_session() {
|
||||
if (pid >= 0) {
|
||||
montauk::setuser(pid, user);
|
||||
montauk::waitpid(pid);
|
||||
terminate_desktop_session(pid);
|
||||
}
|
||||
|
||||
montauk::user::clear_session();
|
||||
|
||||
Reference in New Issue
Block a user