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:
@@ -7,6 +7,7 @@ use syscall::flag::{MODE_DIR, MODE_FILE, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
|
||||
use crate::keymap::Keymap;
|
||||
|
||||
#[derive(Clone)]
|
||||
enum HandleKind {
|
||||
Root,
|
||||
Active,
|
||||
@@ -69,7 +70,12 @@ impl KeymapScheme {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_xkb(&mut self, xkb_dir: &str, layout: &str, variant: Option<&str>) -> io::Result<()> {
|
||||
pub fn load_xkb(
|
||||
&mut self,
|
||||
xkb_dir: &str,
|
||||
layout: &str,
|
||||
variant: Option<&str>,
|
||||
) -> io::Result<()> {
|
||||
let km = crate::xkb::load_xkb_keymap(xkb_dir, layout, variant)
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
|
||||
let name = match variant {
|
||||
@@ -136,9 +142,12 @@ impl redox_scheme::SchemeBlockMut for KeymapScheme {
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
let (kind, offset) = {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
(handle.kind.clone(), handle.offset)
|
||||
};
|
||||
|
||||
let content: Vec<u8> = match &handle.kind {
|
||||
let content: Vec<u8> = match &kind {
|
||||
HandleKind::Root => {
|
||||
let mut listing = String::new();
|
||||
listing.push_str("active\nlist\n");
|
||||
@@ -147,7 +156,12 @@ impl redox_scheme::SchemeBlockMut for KeymapScheme {
|
||||
}
|
||||
listing.into_bytes()
|
||||
}
|
||||
HandleKind::Active => self.active_keymap.clone().into_bytes(),
|
||||
HandleKind::Active => format!(
|
||||
"name={}\nsample_scancode_30={}\n",
|
||||
self.active_keymap,
|
||||
self.translate(0x1E, false, false),
|
||||
)
|
||||
.into_bytes(),
|
||||
HandleKind::List => {
|
||||
let mut listing = String::new();
|
||||
for (i, name) in self.keymaps.keys().enumerate() {
|
||||
@@ -162,20 +176,25 @@ impl redox_scheme::SchemeBlockMut for KeymapScheme {
|
||||
HandleKind::Keymap { name } => {
|
||||
let km = self.keymaps.get(name).ok_or(Error::new(ENOENT))?;
|
||||
format!(
|
||||
"name={}\nentries={}\ncompose={}\ndead_keys={}\n",
|
||||
"name={}\nentries={}\ncompose={}\ndead_keys={}\nsample_scancode_30={}\nsample_altgr_scancode_30={}\nsample_compose_a_acute={}\nsample_compose_sequence={}\n",
|
||||
km.name,
|
||||
km.entries.len(),
|
||||
km.compose.len(),
|
||||
km.dead_keys.len()
|
||||
km.dead_keys.len(),
|
||||
km.get_char(0x1E, false, false),
|
||||
km.get_char(0x1E, false, true),
|
||||
km.compose('a', '\''),
|
||||
km.lookup_compose("compose").unwrap_or('\0'),
|
||||
)
|
||||
.into_bytes()
|
||||
}
|
||||
};
|
||||
|
||||
if handle.offset >= content.len() {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
if offset >= content.len() {
|
||||
return Ok(Some(0));
|
||||
}
|
||||
let remaining = &content[handle.offset..];
|
||||
let remaining = &content[offset..];
|
||||
let to_copy = remaining.len().min(buf.len());
|
||||
buf[..to_copy].copy_from_slice(&remaining[..to_copy]);
|
||||
handle.offset += to_copy;
|
||||
|
||||
Reference in New Issue
Block a user