feat: relibc S1 — sem_open refcounting + glibc cross-reference assessment

Phase S1 (Critical Correctness):
- sem_open/sem_close: global refcounting via BTreeMap + AtomicUsize
- sem_close: decrements refcount, munmaps only at zero
- sem_open: reuses existing mapping, O_EXCL returns EEXIST
- sem_unlink: marks entry for removal before shm_unlink
- va_list parsing: reads mode_t and value from stack after oflag
- All 11 sem_* functions verified in libc.so T

Phase S2-S4 (Designed, documented):
- eventfd() function, signalfd read path, EINTR handling
- name canonicalization, cancellation safety
- Full plan in local/docs/RELIBC-AGAINST-GLIBC-ASSESSMENT.md

Reference: glibc 2.41 cloned to local/reference/glibc/

Boot verified: greeter ready on VT 3 with refcounted semaphores
This commit is contained in:
2026-05-05 21:12:08 +01:00
parent f31522130f
commit 702ec7efac
14 changed files with 1201 additions and 279 deletions
@@ -5,7 +5,7 @@ use syscall::error::{Error, Result, EBADF, EINVAL, ENOENT};
use syscall::flag::{MODE_DIR, MODE_FILE};
#[derive(Clone, Copy, Debug, PartialEq)]
enum StickyKeyState {
pub(crate) enum StickyKeyState {
Off,
Latched,
Locked,
@@ -251,6 +251,29 @@ impl redox_scheme::SchemeBlockMut for AccessibilityScheme {
}
Ok(Some(buf.len()))
}
HandleKind::StickyKeys => {
let input = String::from_utf8_lossy(buf);
for line in input.lines() {
let mut fields = line.split_whitespace();
let Some("key") = fields.next() else {
continue;
};
let Some(code) = fields.next().and_then(|field| field.parse::<u16>().ok())
else {
continue;
};
let Some(pressed) = fields.next().and_then(|field| field.parse::<bool>().ok())
else {
continue;
};
let now_ms = fields
.next()
.and_then(|field| field.parse::<u64>().ok())
.unwrap_or(0);
let _ = self.filter_key(code, pressed, now_ms);
}
Ok(Some(buf.len()))
}
_ => Err(Error::new(EINVAL)),
}
}