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
@@ -1,10 +1,7 @@
mod scheme;
use std::io::Write;
use std::thread;
use std::time::Duration;
use scheme::AccessibilityScheme;
use std::io::Write;
fn log_msg(level: &str, msg: &str) {
let _ = writeln!(std::io::stderr(), "[accessibility] {} {}", level, msg);
@@ -13,7 +10,7 @@ fn log_msg(level: &str, msg: &str) {
fn main() {
let mut scheme = AccessibilityScheme::new();
let socket = redox_scheme::Socket::nonblock("accessibility")
let socket = redox_scheme::Socket::create("accessibility")
.expect("accessibility: failed to register scheme:accessibility");
log_msg("INFO", "registered scheme:accessibility");
@@ -25,15 +22,16 @@ fn main() {
break;
}
Err(e) => {
log_msg("WARN", &format!("scheme read error (ignoring): {}", e));
thread::sleep(Duration::from_millis(100));
continue;
log_msg("ERROR", &format!("scheme read error: {}", e));
break;
}
};
match request.handle_scheme_block_mut(&mut scheme) {
Ok(response) => {
if let Err(e) = socket.write_response(response, redox_scheme::SignalBehavior::Restart) {
if let Err(e) =
socket.write_response(response, redox_scheme::SignalBehavior::Restart)
{
log_msg("ERROR", &format!("failed to write response: {}", e));
}
}
@@ -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)),
}
}