Fix Sockaddr, implement sys_rusage and fix readv

master
jiegec 6 years ago
parent 91ae86ad3f
commit 09588d7a1f

@ -260,7 +260,8 @@ pub fn sys_readv(fd: usize, iov_ptr: *const IoVec, iov_count: usize) -> SysResul
let mut iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.memory_set, true)?; let mut iovs = IoVecs::check_and_new(iov_ptr, iov_count, &proc.memory_set, true)?;
// read all data to a buf // read all data to a buf
let file = proc.get_file(fd)?; let mut file = proc.get_file(fd)?.clone();
drop(proc);
let mut buf = iovs.new_buf(true); let mut buf = iovs.new_buf(true);
let len = file.read(buf.as_mut_slice())?; let len = file.read(buf.as_mut_slice())?;
// copy data to user // copy data to user

@ -97,7 +97,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
087 => sys_unlink(args[0] as *const u8), 087 => sys_unlink(args[0] as *const u8),
096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8), 096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8),
// 097 => sys_getrlimit(), // 097 => sys_getrlimit(),
// 098 => sys_getrusage(), 098 => sys_getrusage(args[0], args[1] as *mut RUsage),
099 => sys_sysinfo(args[0] as *mut SysInfo), 099 => sys_sysinfo(args[0] as *mut SysInfo),
110 => sys_getppid(), 110 => sys_getppid(),
// 133 => sys_mknod(), // 133 => sys_mknod(),

@ -18,6 +18,7 @@ const SOCK_TYPE_MASK: usize = 0xf;
const IPPROTO_IP: usize = 0; const IPPROTO_IP: usize = 0;
const IPPROTO_ICMP: usize = 1; const IPPROTO_ICMP: usize = 1;
const IPPROTO_TCP: usize = 6;
fn get_ephemeral_port() -> u16 { fn get_ephemeral_port() -> u16 {
// TODO selects non-conflict high port // TODO selects non-conflict high port
@ -127,6 +128,13 @@ pub fn sys_setsockopt(
Ok(0) Ok(0)
} }
const SOL_SOCKET: usize = 1;
const SO_SNDBUF: usize = 7;
const SO_RCVBUF: usize = 8;
const SO_LINGER: usize = 13;
const TCP_CONGESTION: usize = 13;
pub fn sys_getsockopt( pub fn sys_getsockopt(
fd: usize, fd: usize,
level: usize, level: usize,
@ -138,8 +146,32 @@ pub fn sys_getsockopt(
"getsockopt: fd: {}, level: {}, optname: {} optval: {:?} optlen: {:?}", "getsockopt: fd: {}, level: {}, optname: {} optval: {:?} optlen: {:?}",
fd, level, optname, optval, optlen fd, level, optname, optval, optlen
); );
warn!("sys_getsockopt is unimplemented"); let proc = process();
Err(SysError::ENOPROTOOPT) proc.memory_set.check_mut_ptr(optlen)?;
match level {
SOL_SOCKET => {
match optname {
SO_SNDBUF | SO_RCVBUF => {
proc.memory_set.check_mut_array(optval, 4)?;
unsafe {
*(optval as *mut u32) = 1024;
*optlen = 4;
}
Ok(0)
}
_ => Err(SysError::ENOPROTOOPT)
}
}
IPPROTO_TCP => {
match optname {
TCP_CONGESTION => {
Ok(0)
}
_ => Err(SysError::ENOPROTOOPT)
}
}
_ => Err(SysError::ENOPROTOOPT)
}
} }
impl Process { impl Process {
@ -685,23 +717,12 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> Sy
fd, addr, addr_len fd, addr, addr_len
); );
// smoltcp tcp sockets do not support backlog
// open multiple sockets for each connection
let mut proc = process(); let mut proc = process();
if addr.is_null() { if addr.is_null() {
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL);
}
proc.memory_set.check_mut_array(addr, max_addr_len)?;
let iface = &*(NET_DRIVERS.read()[0]); let iface = &*(NET_DRIVERS.read()[0]);
let wrapper = proc.get_socket_mut(fd)?; let wrapper = proc.get_socket_mut(fd)?;
if let SocketType::Tcp(state) = &wrapper.socket_type { if let SocketType::Tcp(state) = &wrapper.socket_type {
@ -712,7 +733,18 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> Sy
} }
Ok(0) Ok(0)
} else { } else {
Err(SysError::EINVAL) let mut sockets = iface.sockets();
let socket = sockets.get::<TcpSocket>(wrapper.handle);
let endpoint = socket.local_endpoint();
if endpoint.is_specified() {
let sockaddr_in = SockAddr::from(socket.local_endpoint());
unsafe {
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
Ok(0)
} else {
Err(SysError::EINVAL)
}
} }
} else { } else {
Err(SysError::EINVAL) Err(SysError::EINVAL)
@ -733,15 +765,6 @@ pub fn sys_getpeername(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> Sy
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL);
}
proc.memory_set.check_mut_array(addr, max_addr_len)?;
let iface = &*(NET_DRIVERS.read()[0]); let iface = &*(NET_DRIVERS.read()[0]);
let wrapper = proc.get_socket_mut(fd)?; let wrapper = proc.get_socket_mut(fd)?;
if let SocketType::Tcp(_) = wrapper.socket_type { if let SocketType::Tcp(_) = wrapper.socket_type {
@ -800,9 +823,9 @@ pub fn sys_dup2_socket(proc: &mut Process, wrapper: SocketWrapper, fd: usize) ->
Ok(fd) Ok(fd)
} }
#[repr(C)] // cancel alignment
#[repr(packed)]
pub struct SockAddrIn { pub struct SockAddrIn {
sin_family: u16,
sin_port: u16, sin_port: u16,
sin_addr: u32, sin_addr: u32,
sin_zero: [u8; 8], sin_zero: [u8; 8],
@ -810,7 +833,6 @@ pub struct SockAddrIn {
#[repr(C)] #[repr(C)]
pub struct SockAddrUn { pub struct SockAddrUn {
sun_family: u16,
sun_path: [u8; 108], sun_path: [u8; 108],
} }
@ -833,7 +855,6 @@ impl From<IpEndpoint> for SockAddr {
family: AF_INET as u16, family: AF_INET as u16,
payload: SockAddrPayload { payload: SockAddrPayload {
addr_in: SockAddrIn { addr_in: SockAddrIn {
sin_family: AF_INET as u16,
sin_port: u16::to_be(endpoint.port), sin_port: u16::to_be(endpoint.port),
sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)), sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)),
sin_zero: [0; 8], sin_zero: [0; 8],

@ -112,3 +112,35 @@ pub fn sys_time(time: *mut u64) -> SysResult {
} }
Ok(sec as usize) Ok(sec as usize)
} }
// ignore other fields for now
#[repr(C)]
pub struct RUsage {
utime: TimeVal,
stime: TimeVal
}
pub fn sys_getrusage(who: usize, rusage: *mut RUsage) -> SysResult {
info!("getrusage: who: {}, rusage: {:?}", who, rusage);
let proc = process();
proc.memory_set.check_mut_ptr(rusage)?;
let tick_base = *TICK_BASE;
let tick = unsafe { crate::trap::TICK as u64 };
let usec = (tick - tick_base) * USEC_PER_TICK as u64;
let new_rusage = RUsage {
utime: TimeVal {
sec: usec / USEC_PER_SEC,
usec: usec % USEC_PER_SEC,
},
stime: TimeVal {
sec: usec / USEC_PER_SEC,
usec: usec % USEC_PER_SEC,
}
};
unsafe {
*rusage = new_rusage
};
Ok(0)
}

Loading…
Cancel
Save