base: apply Red Bear patches on latest upstream/main

251 files: init, acpid, ipcd, netcfg, ihdgd, virtio-gpud, scheme-utils,
inputd, block driver, ptyd, ramfs, randd, initfs bootstrap, path deps,
version +rb0.3.1, author attribution
This commit is contained in:
Red Bear OS
2026-07-11 11:39:24 +03:00
parent 1b17b3fc24
commit bd595851e2
251 changed files with 24641 additions and 5993 deletions
+86 -37
View File
@@ -251,17 +251,34 @@ where
flags: usize,
) -> SyscallResult<usize>;
fn get_sock_opt(
&self,
file: &SchemeFile<Self>,
name: usize,
buf: &mut [u8],
fn call(
&mut self,
_file: &mut SchemeFile<Self>,
_payload: &mut [u8],
_metadata: &[u64],
_ctx: &CallerCtx,
) -> SyscallResult<usize> {
Err(SyscallError::new(syscall::EOPNOTSUPP))
}
fn get_sock_opt(
&self,
_file: &SchemeFile<Self>,
_name: usize,
_buf: &mut [u8],
) -> SyscallResult<usize> {
Err(SyscallError::new(syscall::ENOPROTOOPT))
}
fn set_sock_opt(
&mut self,
_file: &SchemeFile<Self>,
_name: usize,
_buf: &[u8],
) -> SyscallResult<usize> {
// Return Err for default implementation
Err(SyscallError::new(syscall::ENOPROTOOPT))
}
}
pub enum Handle<SocketT>
where
SocketT: SchemeSocket,
@@ -322,8 +339,8 @@ where
}?;
let mut timeout = match op {
Op::Read(_) => write_timeout,
Op::Write(_) => read_timeout,
Op::Read(_) => read_timeout,
Op::Write(_) => write_timeout,
_ => None,
};
@@ -453,10 +470,20 @@ where
// SocketCall::Bind => self.handle_bind(id, &payload),
// SocketCall::Connect => self.handle_connect(id, &payload),
SocketCall::SetSockOpt => {
// currently not used
// self.handle_setsockopt(id, metadata[1] as i32, &payload)
// TODO: SO_REUSEADDR from null socket
Ok(0)
let handle = self.handles.get(fd)?;
match handle {
Handle::File(file) => {
let mut socket_set = self.socket_set.borrow_mut();
let socket = socket_set.get_mut::<SocketT>(file.socket_handle());
SocketT::set_sock_opt(
socket,
file,
metadata[1] as usize,
payload,
)
}
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}
}
SocketCall::GetSockOpt => {
let handle = self.handles.get_mut(fd)?;
@@ -489,7 +516,21 @@ where
Handle::SchemeRoot => Err(SyscallError::new(syscall::EBADF)),
}
}
// SocketCall::SendMsg => self.handle_sendmsg(id, payload, ctx),
SocketCall::SendMsg => {
let flags = metadata[1] as usize;
let handle = self.handles.get_mut(fd)?;
match *handle {
Handle::File(ref mut file) => {
let mut socket_set = self.socket_set.borrow_mut();
let socket = socket_set.get_mut::<SocketT>(file.socket_handle());
SocketT::call(socket, file, payload, &[flags as u64], ctx)
}
Handle::Null(_) => Err(SyscallError::new(syscall::EINVAL)),
Handle::SchemeRoot => Err(SyscallError::new(syscall::EBADF)),
}
}
// SocketCall::Unbind => self.handle_unbind(id),
// SocketCall::GetToken => self.handle_get_token(id, payload),
SocketCall::GetPeerName => {
@@ -658,32 +699,33 @@ where
let socket_handle = scheme_file.socket_handle();
let mut socket_set = self.socket_set.borrow_mut();
let socket = socket_set.get::<SocketT>(socket_handle);
let _ = socket.close_file(&scheme_file, &mut self.scheme_data);
let remove = match self.ref_counts.entry(socket_handle) {
// Compute refcount change WITHOUT calling close_file yet.
// The port release (inside close_file) must happen exactly
// once when the LAST file referencing this socket is
// closed — otherwise a dup'd socket's port would be
// double-freed.
let new_count = match self.ref_counts.entry(socket_handle) {
Entry::Vacant(_) => {
warn!("Closing a socket_handle with no ref");
true
0
}
Entry::Occupied(mut e) => {
if *e.get() == 0 {
warn!("Closing a socket_handle with no ref");
let count = *e.get();
if count <= 1 {
e.remove();
true
0
} else {
*e.get_mut() -= 1;
if *e.get() == 0 {
e.remove();
true
} else {
false
}
count - 1
}
}
};
if remove {
// Only close the socket (which releases the port) when
// the last reference is gone.
if new_count == 0 {
let socket = socket_set.get::<SocketT>(socket_handle);
let _ = socket.close_file(&scheme_file, &mut self.scheme_data);
socket_set.remove(socket_handle);
}
}
@@ -817,22 +859,27 @@ where
if let Some((socket_handle, data)) = update_with {
if let SchemeFile::Socket(ref mut file) = *file {
// We replace the socket_handle pointed by file so update the ref_counts
// accordingly
// We replace the socket_handle pointed by file so update
// the ref_counts accordingly.
self.ref_counts
.entry(file.socket_handle)
.and_modify(|e| *e = e.saturating_sub(1))
.or_insert(0);
// Increment refcount of the NEW socket (socket_handle)
// that the file is being updated to point at.
*self
.ref_counts
.entry(new_handle.socket_handle())
.entry(socket_handle)
.or_insert(0) += 1;
file.socket_handle = socket_handle;
file.data = data;
}
}
// Increment refcount for the new_handle fd being inserted.
// This is always done (regardless of update_with) because
// new_handle represents a new fd in the handle table.
*self
.ref_counts
.entry(new_handle.socket_handle())
@@ -875,12 +922,14 @@ where
}
fn fsync(&mut self, fd: usize, _ctx: &CallerCtx) -> SyscallResult<()> {
{
let _file = self.handles.get_mut(fd)?;
}
// Verify the socket exists. The netstack is event-driven (polled by
// userspace via fevent), so there is no kernel-side buffer to flush.
// POSIX fsync(2) on a socket is required to return success when the
// socket is valid; the underlying protocol (TCP) handles acknowledgements
// asynchronously through the normal poll loop.
// Cross-referenced with Linux net/socket.c: sockfs_fsync -> sock_no_fsync.
let _file = self.handles.get(fd)?;
Ok(())
// TODO Implement fsyncing
// self.0.network_fsync()
}
fn fpath(&mut self, fd: usize, buf: &mut [u8], _ctx: &CallerCtx) -> SyscallResult<usize> {