feat: add inherited sessions and desktop session teardown

This commit is contained in:
2026-08-14 10:33:20 +02:00
parent f8ded3c30e
commit 0f81276efc
17 changed files with 165 additions and 0 deletions
+2
View File
@@ -125,6 +125,8 @@ namespace montauk::abi {
// User management
static constexpr uint64_t SYS_SETUSER = 92;
static constexpr uint64_t SYS_GETUSER = 93;
static constexpr uint64_t SYS_SETSESSION = 174;
static constexpr uint64_t SYS_KILLSESSION = 175;
static constexpr uint64_t SYS_FRENAME = 94;
static constexpr uint64_t SYS_GETCWD = 95;
static constexpr uint64_t SYS_CHDIR = 96;
+10
View File
@@ -76,6 +76,8 @@ extern "C" {
#define MTK_SYS_GETENVIRON 171
#define MTK_SYS_SETENVIRON 172
#define MTK_SYS_SPAWN_ENV 173
#define MTK_SYS_SETSESSION 174
#define MTK_SYS_KILLSESSION 175
#define MTK_SYS_CHILDIO_READ 50
#define MTK_SYS_CHILDIO_WRITE 51
#define MTK_SYS_CHILDIO_WRITEKEY 52
@@ -428,6 +430,14 @@ static inline int mtk_kill(int pid) {
return (int)_mtk_syscall1(MTK_SYS_KILL, (long)pid);
}
static inline int mtk_setsession(void) {
return (int)_mtk_syscall0(MTK_SYS_SETSESSION);
}
static inline int mtk_killsession(int session_id) {
return (int)_mtk_syscall1(MTK_SYS_KILLSESSION, (long)session_id);
}
static inline int mtk_proclist(mtk_procinfo *buf, int max) {
return (int)_mtk_syscall2(MTK_SYS_PROCLIST, (long)buf, (long)max);
}
+6
View File
@@ -458,6 +458,12 @@ namespace montauk {
inline int kill(int pid) {
return (int)syscall1(montauk::abi::SYS_KILL, (uint64_t)pid);
}
inline int setsession() {
return (int)syscall0(montauk::abi::SYS_SETSESSION);
}
inline int killsession(int sessionId) {
return (int)syscall1(montauk::abi::SYS_KILLSESSION, (uint64_t)sessionId);
}
inline int devlist(montauk::abi::DevInfo* buf, int max) {
return (int)syscall2(montauk::abi::SYS_DEVLIST, (uint64_t)buf, (uint64_t)max);
}
+10
View File
@@ -65,6 +65,16 @@
Terminate another process by PID.
int montauk::kill(int pid);
.B SYS_SETSESSION (174)
Make the calling process the leader of a new process session. Processes
spawned afterward inherit the session identifier.
int montauk::setsession();
.B SYS_KILLSESSION (175)
Terminate all live processes in a process session. Returns the number of
members signalled; repeat until zero to wait for complete teardown.
int montauk::killsession(int sessionId);
.B SYS_CHDIR (96)
Change the calling process's current working directory.
int montauk::chdir(const char* path);
+5
View File
@@ -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",
+2
View File
@@ -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;
+18
View File
@@ -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) {
+1
View File
@@ -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();