Merge branch 'bulk-send-recvfd' into 'main'

feat: Implement bulk fd passing

See merge request redox-os/base!25
This commit is contained in:
Jeremy Soller
2025-07-30 18:49:38 -06:00
4 changed files with 110 additions and 23 deletions
Generated
+7 -7
View File
@@ -454,7 +454,7 @@ dependencies = [
"rand",
"redox-daemon",
"redox-rt",
"redox-scheme 0.7.0",
"redox-scheme 0.8.0",
"redox_event",
"redox_syscall",
]
@@ -483,9 +483,9 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libredox"
version = "0.1.6"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0"
checksum = "360e552c93fa0e8152ab463bc4c4837fce76a225df11dfaeea66c313de5e61f7"
dependencies = [
"bitflags 2.9.0",
"ioslice",
@@ -802,9 +802,9 @@ dependencies = [
[[package]]
name = "redox-scheme"
version = "0.7.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4da6a0251965958189cdfd5ebb66f99754db4aa165394300aa2b958525d94b64"
checksum = "2ad682dfdadbfcf79ee861ba3cebcb78f4615276c1a3434fb510403916cbaba4"
dependencies = [
"libredox",
"redox_syscall",
@@ -837,9 +837,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.14"
version = "0.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3a5d9f0aba1dbcec1cc47f0ff94a4b778fe55bca98a6dfa92e4e094e57b1c4"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [
"bitflags 2.9.0",
]
+3 -3
View File
@@ -4,10 +4,10 @@ name = "ipcd"
version = "0.1.0"
[dependencies]
libredox = { version = "0.1.6", features = ["call"]}
libredox = { version = "0.1.8", features = ["call"]}
redox-daemon = "0.1.2"
redox_syscall = "0.5"
redox-scheme = "0.7.0"
redox_syscall = "0.5.17"
redox-scheme = "0.8.0"
redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false }
redox_event = "0.4.0"
anyhow = "1.0.97"
+47 -6
View File
@@ -10,8 +10,8 @@ use rand::rngs::SmallRng;
use rand::{RngCore, SeedableRng};
use redox_rt::protocol::SocketCall;
use redox_scheme::{
scheme::SchemeSync, CallerCtx, OpenResult, Response, SendFdRequest, SignalBehavior,
Socket as SchemeSocket,
scheme::SchemeSync, CallerCtx, OpenResult, RecvFdRequest, Response, SendFdRequest,
SignalBehavior, Socket as SchemeSocket,
};
use std::{
cell::RefCell,
@@ -558,19 +558,56 @@ impl<'sock> UdsDgramScheme<'sock> {
}
fn sendfd_inner(&mut self, sendfd_request: &SendFdRequest) -> Result<usize> {
let mut new_fd = usize::MAX;
if sendfd_request.num_fds() == 0 {
return Ok(0);
}
let mut new_fds = Vec::new();
new_fds.resize(sendfd_request.num_fds(), usize::MAX);
if let Err(e) =
sendfd_request.obtain_fd(&self.socket, FobtainFdFlags::empty(), Err(&mut new_fd))
sendfd_request.obtain_fd(&self.socket, FobtainFdFlags::UPPER_TBL, &mut new_fds)
{
eprintln!("sendfd_inner: obtain_fd failed with error: {:?}", e);
return Err(e);
}
let socket_id = sendfd_request.id();
let (remote_id, remote_rc) = self.get_connected_peer(socket_id)?;
remote_rc.borrow_mut().fds.push_back(new_fd);
{
let mut remote = remote_rc.borrow_mut();
for new_fd in &new_fds {
remote.fds.push_back(*new_fd);
}
}
self.post_fevent(remote_id, EVENT_READ.bits())?;
Ok(new_fd)
Ok(new_fds.len())
}
fn recvfd_inner(&mut self, recvfd_request: &RecvFdRequest) -> Result<OpenResult> {
if recvfd_request.num_fds() == 0 {
return Ok(OpenResult::OtherSchemeMultiple { num_fds: 0 });
}
let socket_id = recvfd_request.id();
let socket_rc = self.get_socket(socket_id)?;
let mut socket = socket_rc.borrow_mut();
if socket.fds.len() < recvfd_request.num_fds() {
return if (socket.flags as usize) & O_NONBLOCK == O_NONBLOCK {
Ok(OpenResult::WouldBlock)
} else {
Err(Error::new(EWOULDBLOCK))
};
}
let fds: Vec<usize> = socket.fds.drain(..recvfd_request.num_fds()).collect();
if let Err(e) = recvfd_request.move_fd(&self.socket, FmoveFdFlags::empty(), &fds) {
eprintln!("recvfd_inner: move_fd failed with error: {:?}", e);
return Err(Error::new(EPROTO));
}
Ok(OpenResult::OtherSchemeMultiple {
num_fds: recvfd_request.num_fds(),
})
}
}
@@ -673,6 +710,10 @@ impl<'sock> SchemeSync for UdsDgramScheme<'sock> {
self.sendfd_inner(sendfd_request)
}
fn on_recvfd(&mut self, recvfd_request: &RecvFdRequest) -> Result<OpenResult> {
self.recvfd_inner(recvfd_request)
}
fn fcntl(&mut self, id: usize, cmd: usize, arg: usize, _ctx: &CallerCtx) -> Result<usize> {
let socket = self.get_socket(id)?;
match cmd {
+53 -7
View File
@@ -9,8 +9,8 @@ use libc::{AF_UNIX, SO_DOMAIN, SO_PASSCRED};
use rand::prelude::*;
use redox_rt::protocol::SocketCall;
use redox_scheme::{
scheme::SchemeSync, CallerCtx, OpenResult, Response, SendFdRequest, SignalBehavior,
Socket as SchemeSocket,
scheme::SchemeSync, CallerCtx, OpenResult, RecvFdRequest, Response, SendFdRequest,
SignalBehavior, Socket as SchemeSocket,
};
use std::{
cell::RefCell,
@@ -417,7 +417,7 @@ impl<'sock> UdsStreamScheme<'sock> {
socket.path = Some(path_owned.clone());
socket.state = State::Bound;
token = self.rng.next_u64();
socket.issued_token.insert(token);
socket.issued_token = Some(token);
}
self.socket_paths.insert(path_owned, socket_rc.clone());
@@ -852,9 +852,10 @@ impl<'sock> UdsStreamScheme<'sock> {
receiver_id: usize,
sendfd_request: &SendFdRequest,
) -> Result<usize> {
let mut new_fd = usize::MAX;
let mut new_fds = Vec::new();
new_fds.resize(sendfd_request.num_fds(), usize::MAX);
if let Err(e) =
sendfd_request.obtain_fd(&self.socket, FobtainFdFlags::empty(), Err(&mut new_fd))
sendfd_request.obtain_fd(&self.socket, FobtainFdFlags::UPPER_TBL, &mut new_fds)
{
eprintln!("sendfd_inner: obtain_fd failed with error: {:?}", e);
return Err(e);
@@ -863,11 +864,52 @@ impl<'sock> UdsStreamScheme<'sock> {
let mut receiver = receiver_rc.borrow_mut();
let connection = receiver.require_connected_connection()?;
connection.fds.push_back(new_fd);
for new_fd in &new_fds {
connection.fds.push_back(*new_fd);
}
self.post_fevent(receiver_id, EVENT_READ.bits())?;
Ok(new_fd)
Ok(new_fds.len())
}
fn recvfd_inner(&mut self, recvfd_request: &RecvFdRequest) -> Result<OpenResult> {
let socket_id = recvfd_request.id();
let socket_rc = self.get_socket(socket_id)?;
let mut socket = socket_rc.borrow_mut();
if recvfd_request.num_fds() == 0 {
return Ok(OpenResult::OtherSchemeMultiple { num_fds: 0 });
}
match socket.state {
State::Established | State::Accepted => {
let connection = socket.require_connected_connection()?;
if connection.fds.len() < recvfd_request.num_fds() {
return if connection.is_peer_shutdown {
Ok(OpenResult::OtherSchemeMultiple { num_fds: 0 }) // EOF, no data to read
} else if (socket.flags as usize) & O_NONBLOCK == O_NONBLOCK {
Ok(OpenResult::WouldBlock)
} else {
Err(Error::new(EWOULDBLOCK))
};
}
let fds: Vec<usize> = connection.fds.drain(..recvfd_request.num_fds()).collect();
if let Err(e) = recvfd_request.move_fd(&self.socket, FmoveFdFlags::empty(), &fds) {
eprintln!("recvfd_inner: move_fd failed with error: {:?}", e);
return Err(Error::new(EPROTO));
}
Ok(OpenResult::OtherSchemeMultiple {
num_fds: recvfd_request.num_fds(),
})
}
State::Closed => Err(Error::new(EPIPE)),
State::Listening => Err(Error::new(EOPNOTSUPP)),
_ => Err(Error::new(ENOTCONN)),
}
}
fn read_inner(connection: &mut Connection, buf: &mut [u8], flags: u32) -> Result<usize> {
@@ -1072,6 +1114,10 @@ impl<'sock> SchemeSync for UdsStreamScheme<'sock> {
self.sendfd_inner(receiver_id, sendfd_request)
}
fn on_recvfd(&mut self, recvfd_request: &RecvFdRequest) -> Result<OpenResult> {
self.recvfd_inner(recvfd_request)
}
fn on_close(&mut self, id: usize) {
let Some(socket_rc) = self.sockets.remove(&id) else {
return;