feat(users): per-user sealed folders users/<id>/{home,apps,data,permissions}; storage SET_USER/LOCK/PURGE; init sign-in/sign-out loop (purge fresh/removed/guest, seed from factory, session start/stop); shell logout; pm user+system app shelves; terminal SIGNED_OUT; per-program stack (gatekeeper 12p); 128K load scratch
This commit is contained in:
@@ -103,6 +103,10 @@ impl server::Console for Screen {
|
||||
fn interrupt(&mut self, notification: CapSlot) {
|
||||
let _ = syscall::signal(notification);
|
||||
}
|
||||
|
||||
fn forget(&mut self, notification: CapSlot) {
|
||||
syscall::drop_cap(notification);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() -> ! {
|
||||
|
||||
@@ -24,6 +24,8 @@ pub trait Console {
|
||||
/// Takes input focus back from whoever took it, and clears the screen.
|
||||
fn take_focus(&mut self);
|
||||
fn interrupt(&mut self, notification: CapSlot);
|
||||
/// Lets go of a notification it was given.
|
||||
fn forget(&mut self, notification: CapSlot);
|
||||
}
|
||||
|
||||
pub const BACKSPACE: u8 = 8;
|
||||
@@ -232,7 +234,7 @@ impl<C: Console> Server for TerminalServer<C> {
|
||||
Done
|
||||
}
|
||||
|
||||
fn handle_call(&mut self, _badge: usize, words: [usize; 4], cap: Option<CapSlot>) -> ([usize; 4], Option<libkos::syscall::Give>) {
|
||||
fn handle_call(&mut self, badge: usize, words: [usize; 4], cap: Option<CapSlot>) -> ([usize; 4], Option<libkos::syscall::Give>) {
|
||||
let reply = match words[0] {
|
||||
types::terminal::READ => self.read(false),
|
||||
types::terminal::READ_SECRET => self.read(true),
|
||||
@@ -252,6 +254,13 @@ impl<C: Console> Server for TerminalServer<C> {
|
||||
}
|
||||
_ => [MALFORMED, 0, 0, 0],
|
||||
},
|
||||
types::terminal::SIGNED_OUT if badge == 0 => {
|
||||
if let Some(n) = self.on_interrupt.take() {
|
||||
self.console.forget(n);
|
||||
}
|
||||
[0; 4]
|
||||
}
|
||||
types::terminal::SIGNED_OUT => [MALFORMED, 0, 0, 0],
|
||||
types::terminal::CLEAR => {
|
||||
self.handle(Request::Clear);
|
||||
[0; 4]
|
||||
|
||||
@@ -20,6 +20,7 @@ struct Fake {
|
||||
/// Every row drawn, with how many cells.
|
||||
rows_drawn: Vec<(usize, usize)>,
|
||||
interrupted: Vec<CapSlot>,
|
||||
forgotten: Vec<CapSlot>,
|
||||
}
|
||||
|
||||
impl Console for Fake {
|
||||
@@ -48,6 +49,9 @@ impl Console for Fake {
|
||||
fn interrupt(&mut self, notification: CapSlot) {
|
||||
self.interrupted.push(notification);
|
||||
}
|
||||
fn forget(&mut self, notification: CapSlot) {
|
||||
self.forgotten.push(notification);
|
||||
}
|
||||
}
|
||||
|
||||
fn term(keys: &[u8]) -> TerminalServer<Fake> {
|
||||
@@ -186,3 +190,17 @@ fn a_secret_line_shows_stars_and_is_forgotten() {
|
||||
assert_eq!(&t.grid().row(0)[..8], b"*******\x20");
|
||||
assert!(!t.grid().row(0).windows(7).any(|w| w == b"hunter2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_init_lets_the_next_session_register_for_ctrl_c() {
|
||||
use server_framework::MALFORMED;
|
||||
let mut t = term(&[]);
|
||||
assert_eq!(on_interrupt(&mut t, 7), 0);
|
||||
assert_eq!(on_interrupt(&mut t, 8), MALFORMED, "an app cannot take Ctrl+C over");
|
||||
let signed_out = |t: &mut TerminalServer<Fake>, badge| t.handle_call(badge, [types::terminal::SIGNED_OUT, 0, 0, 0], None).0[0];
|
||||
assert_eq!(signed_out(&mut t, 1), MALFORMED, "nor say the user signed out");
|
||||
assert_eq!(on_interrupt(&mut t, 8), MALFORMED);
|
||||
assert_eq!(signed_out(&mut t, 0), 0);
|
||||
assert_eq!(t.console().forgotten, [CapSlot::new(7).unwrap()]);
|
||||
assert_eq!(on_interrupt(&mut t, 9), 0, "the next shell may");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user