Files
RedBear-OS/local/patches/base/P0-daemon-silence-init-notify.patch
T
vasilito 702ec7efac 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
2026-05-05 21:12:08 +01:00

116 lines
4.0 KiB
Diff

diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs
--- a/daemon/src/lib.rs
+++ b/daemon/src/lib.rs
@@ -10,26 +10,35 @@ use libredox::Fd;
use redox_scheme::scheme::{SchemeAsync, SchemeSync};
use redox_scheme::Socket;
-unsafe fn get_fd(var: &str) -> RawFd {
- let fd: RawFd = match std::env::var(var)
- .map_err(|e| eprintln!("daemon: env var {var} not set: {e}"))
- .ok()
- .and_then(|val| {
- val.parse()
- .map_err(|e| eprintln!("daemon: failed to parse {var} as fd: {e}"))
- .ok()
- }) {
- Some(fd) => fd,
- None => return -1,
+unsafe fn get_fd(var: &str) -> Option<RawFd> {
+ let value = match std::env::var(var) {
+ Ok(value) => value,
+ Err(_) => {
+ let exe = std::env::args()
+ .next()
+ .unwrap_or_else(|| "daemon".to_string());
+ eprintln!("daemon: {var} not set for {exe}; readiness notification disabled");
+ return None;
+ }
+ };
+ let fd: RawFd = match value.parse() {
+ Ok(fd) => fd,
+ Err(err) => {
+ let exe = std::env::args()
+ .next()
+ .unwrap_or_else(|| "daemon".to_string());
+ eprintln!("daemon: invalid {var} value {value:?} for {exe}: {err}; readiness notification disabled");
+ return None;
+ }
};
if unsafe { libc::fcntl(fd, libc::F_SETFD, libc::FD_CLOEXEC) } == -1 {
eprintln!(
"daemon: failed to set CLOEXEC flag for {var} fd: {}",
io::Error::last_os_error()
);
- return -1;
+ return None;
}
- fd
+ Some(fd)
}
unsafe fn pass_fd(cmd: &mut Command, env: &str, fd: OwnedFd) {
@@ -47,22 +56,20 @@ unsafe fn pass_fd(cmd: &mut Command, env: &str, fd: OwnedFd) {
/// A long running background process that handles requests.
#[must_use = "Daemon::ready must be called"]
pub struct Daemon {
- write_pipe: PipeWriter,
+ write_pipe: Option<PipeWriter>,
}
impl Daemon {
/// Create a new daemon.
pub fn new(f: impl FnOnce(Daemon) -> !) -> ! {
- let write_pipe = unsafe { io::PipeWriter::from_raw_fd(get_fd("INIT_NOTIFY")) };
+ let write_pipe = unsafe { get_fd("INIT_NOTIFY").map(io::PipeWriter::from_raw_fd) };
f(Daemon { write_pipe })
}
/// Notify the process that the daemon is ready to accept requests.
pub fn ready(mut self) {
- if let Err(err) = self.write_pipe.write_all(&[0]) {
- if err.kind() != io::ErrorKind::BrokenPipe {
- eprintln!("daemon::ready write failed: {err}");
- }
+ if let Some(write_pipe) = self.write_pipe.as_mut() {
+ write_pipe.write_all(&[0]).unwrap();
}
}
@@ -87,24 +94,26 @@ impl Daemon {
/// A long running background process that handles requests using schemes.
#[must_use = "SchemeDaemon::ready must be called"]
pub struct SchemeDaemon {
- write_pipe: PipeWriter,
+ write_pipe: Option<PipeWriter>,
}
impl SchemeDaemon {
/// Create a new daemon for use with schemes.
pub fn new(f: impl FnOnce(SchemeDaemon) -> !) -> ! {
- let write_pipe = unsafe { io::PipeWriter::from_raw_fd(get_fd("INIT_NOTIFY")) };
+ let write_pipe = unsafe { get_fd("INIT_NOTIFY").map(io::PipeWriter::from_raw_fd) };
f(SchemeDaemon { write_pipe })
}
/// Notify the process that the scheme daemon is ready to accept requests.
pub fn ready_with_fd(self, cap_fd: Fd) -> syscall::Result<()> {
- syscall::call_wo(
- self.write_pipe.as_raw_fd() as usize,
- &cap_fd.into_raw().to_ne_bytes(),
- syscall::CallFlags::FD,
- &[],
- )?;
+ if let Some(write_pipe) = self.write_pipe {
+ syscall::call_wo(
+ write_pipe.as_raw_fd() as usize,
+ &cap_fd.into_raw().to_ne_bytes(),
+ syscall::CallFlags::FD,
+ &[],
+ )?;
+ }
Ok(())
}