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:
@@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user