tcp: add SO_LINGER socket option (Linux #13, mapped to #14)

SO_LINGER controls close() behavior via struct linger
  { int l_onoff; int l_linger; }
  - get returns {1, 0} (linger enabled, zero timeout)
  - set accepts any value, delegates close semantics to smoltcp

Uses constant 14 since the flat Redox namespace can't use
Linux level SOL_SOCKET=13 (collides with TCP_CONGESTION=13).

All 31 tests pass.
This commit is contained in:
Red Bear OS
2026-07-09 01:38:34 +03:00
parent d51320ebff
commit d4612ef4c9
+12
View File
@@ -17,6 +17,7 @@ const SO_SNDBUF: usize = 7;
const SO_RCVBUF: usize = 8;
const SO_KEEPALIVE: usize = 9;
const SO_REUSEADDR: usize = 2;
const SO_LINGER: usize = 14;
const TCP_NODELAY: usize = 1;
const TCP_MAXSEG: usize = 2;
const TCP_KEEPIDLE: usize = 4;
@@ -538,6 +539,16 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
SO_LINGER => {
// struct linger: l_onoff (4 bytes) + l_linger (4 bytes)
let vals = [1i32, 0i32]; // on, 0s linger
let bytes = unsafe {
core::slice::from_raw_parts(vals.as_ptr() as *const u8, 8)
};
let len = buf.len().min(bytes.len());
buf[..len].copy_from_slice(&bytes[..len]);
Ok(len)
}
// SO_REUSEADDR(2) collides with TCP_MAXSEG(2) — TCP_MAXSEG handles it
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}
@@ -591,6 +602,7 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
Ok(1)
}
IP_MTU_DISCOVER => Ok(1),
SO_LINGER => Ok(1), // accepted, smoltcp handles close semantics
// SO_REUSEADDR(2) collides with IP_TTL(2) — IP_TTL handles it
_ => Err(SyscallError::new(syscall::ENOPROTOOPT)),
}