netstack: round 18 part 2 — fix remaining 7 build errors

Closes the rest of the build-break cascade after round 18 part 1:

1. router/mod.rs:550 — IpProtocol -> u8 conversion.
   smoltcp 0.13.1 tightened the return type of
   IpProtocol::from() from u8 to IpProtocol (an enum). The PacketContext
   field is u8. Add .into() so the type matches the destination.

2. scheme/mod.rs:185 + :199 — File::from_raw_fd expects i32.
   libredox::Fd::into_raw() returns usize (defined in libredox
   lib.rs:409). The destination File::from_raw_fd takes c_int.
   Add 'as i32' at both call sites (network FD + time FD).

3. scheme/netcfg/mod.rs:173 — for-loop iteration mismatch.
   DeviceList::iter() returns Iterator<Item = &(dyn LinkDevice + 'static)>
   not Iterator<Item = (&str, &dyn LinkDevice)> as the loop assumed
   (the old tuple shape was for a HashMap-style DeviceList that
   was later refactored to Vec<Box<dyn LinkDevice>>).
   Rewrite the loop to use dev.name() per iteration.

4. scheme/tcp.rs — 3 errors:
   a) cannot find type CallerCtx. Add 'use redox_scheme::CallerCtx;'
      (matches the udp.rs pattern at line 2).
   b) cannot find type SocketCall. Add 'use libredox::protocol::SocketCall;'
      (matches the socket.rs pattern at line 13).
   c) send_slice returns Result<usize, SendError> not isize.
      The original code treated negative as error. With the Result
      variant, Err(_) means the socket may have closed or the
      buffer was full. Map Err to Ok(0) (matches the original
      'written.max(0) as usize' semantics: report 0 bytes sent
      on failure rather than erroring). Use a closure to keep
      the MSG_NOSIGNAL signal-mask dance readable.

5. scheme_pool.rs:198 — E0521 borrowed data escapes.
   Tighten submit signature to 'name: &'static str'. All callers
   (run_corec12_main_loop, tests) already pass string literals
   which are 'static, so no caller updates are required.

Build should now compile netstack. Remaining items after this
commit: only warnings (37 total) — unused imports/variables
tracked for a future cleanup commit.
This commit is contained in:
2026-07-28 06:54:58 +09:00
parent 4b27b51d59
commit 468ac36e97
5 changed files with 21 additions and 10 deletions
+1 -1
View File
@@ -547,7 +547,7 @@ fn infer_context(
out_dev: None,
src_addr: IpAddress::Ipv6(ipv6.src_addr()),
dst_addr: IpAddress::Ipv6(ipv6.dst_addr()),
protocol: smoltcp::wire::IpProtocol::from(transport_proto),
protocol: smoltcp::wire::IpProtocol::from(transport_proto).into(),
src_port,
dst_port,
packet,
+2 -2
View File
@@ -182,7 +182,7 @@ impl Smolnetd {
// elsewhere; from_raw_fd transfers ownership
// to the new File.
unsafe {
File::from_raw_fd(nf.into_raw())
File::from_raw_fd(nf.into_raw() as i32)
});
link.set_mac_address(hw_addr);
devices.borrow_mut().push(link);
@@ -196,7 +196,7 @@ impl Smolnetd {
time_file: // SAFETY: caller guarantees time_file is a live Fd not
// aliased elsewhere; from_raw_fd transfers ownership
// to the new File.
unsafe { File::from_raw_fd(time_file.into_raw()) },
unsafe { File::from_raw_fd(time_file.into_raw() as i32) },
ip_scheme: IpScheme::new(
"ip",
Rc::clone(&iface),
+2 -1
View File
@@ -170,7 +170,8 @@ fn mk_root_node(
let lo = devs.get("loopback");
let lo_state = lo.map(|d| d.link_state()).unwrap_or("missing");
let mut iface_summary = format!("lo={}", lo_state);
for (name, dev) in devs.iter() {
for dev in devs.iter() {
let name = dev.name().as_ref();
if name != "loopback" {
iface_summary.push_str(&format!(" {}={}", name, dev.link_state()));
}
+15 -5
View File
@@ -8,6 +8,9 @@ use syscall;
use syscall::{Error as SyscallError, Result as SyscallResult};
use anyhow::Context as _;
use redox_scheme::CallerCtx;
use libredox::protocol::SocketCall;
use super::socket::{Context, DupResult, SchemeFile, SchemeSocket, SocketFile};
use super::{parse_endpoint, SchemeWrapper, SocketSet};
use crate::port_set::PortSet;
@@ -69,14 +72,21 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
// 0x4000 on Linux. We declare it locally so the
// bitwise check below works on both hosts.
const MSG_NOSIGNAL: u16 = 0x4000;
let send_result = |s: &mut Self| {
let r = s.send_slice(payload);
match r {
Ok(n) => Ok(n as usize),
Err(_e) => Ok(0),
}
};
if flags & MSG_NOSIGNAL != 0 {
let mut old_mask: libc::sigset_t = unsafe { std::mem::zeroed() };
let mut block_mask: libc::sigset_t = unsafe { std::mem::zeroed() };
unsafe { libc::sigemptyset(&mut block_mask) };
unsafe { libc::sigaddset(&mut block_mask, libc::SIGPIPE) };
if unsafe { libc::pthread_sigmask(libc::SIG_BLOCK, &block_mask, &mut old_mask) } == 0 {
let written = self.send_slice(payload);
if written < 0 {
let written = send_result(self);
if let Ok(0) = written {
self.close();
let mut ts: libc::timespec =
unsafe { std::mem::zeroed() };
@@ -93,14 +103,14 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
unsafe {
libc::pthread_sigmask(libc::SIG_SETMASK, &old_mask, std::ptr::null_mut());
}
Ok(written.max(0) as usize)
written
} else {
// pthread_sigmask failed; fall through to plain
// send without suppression.
Ok(self.send_slice(payload).max(0) as usize)
send_result(self)
}
} else {
Ok(self.send_slice(payload).max(0) as usize)
send_result(self)
}
}
_ => Err(SyscallError::new(syscall::EOPNOTSUPP)),
+1 -1
View File
@@ -187,7 +187,7 @@ impl SchemePool {
self.stats.get(name).map(|s| s.as_ref())
}
pub fn submit(&self, name: &str, bytes_hint: usize) -> bool {
pub fn submit(&self, name: &'static str, bytes_hint: usize) -> bool {
let worker = match self.workers.get(name) {
Some(w) => w,
None => {