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)?;
// 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 len = file.read(buf.as_mut_slice())?;
// 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),
096 => sys_gettimeofday(args[0] as *mut TimeVal, args[1] as *const u8),
// 097 => sys_getrlimit(),
// 098 => sys_getrusage(),
098 => sys_getrusage(args[0], args[1] as *mut RUsage),
099 => sys_sysinfo(args[0] as *mut SysInfo),
110 => sys_getppid(),
// 133 => sys_mknod(),

@ -18,6 +18,7 @@ const SOCK_TYPE_MASK: usize = 0xf;
const IPPROTO_IP: usize = 0;
const IPPROTO_ICMP: usize = 1;
const IPPROTO_TCP: usize = 6;
fn get_ephemeral_port() -> u16 {
// TODO selects non-conflict high port
@ -127,6 +128,13 @@ pub fn sys_setsockopt(
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(
fd: usize,
level: usize,
@ -138,8 +146,32 @@ pub fn sys_getsockopt(
"getsockopt: fd: {}, level: {}, optname: {} optval: {:?} optlen: {:?}",
fd, level, optname, optval, optlen
);
warn!("sys_getsockopt is unimplemented");
Err(SysError::ENOPROTOOPT)
let proc = process();
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 {
@ -685,23 +717,12 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> Sy
fd, addr, addr_len
);
// smoltcp tcp sockets do not support backlog
// open multiple sockets for each connection
let mut proc = process();
if addr.is_null() {
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 wrapper = proc.get_socket_mut(fd)?;
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)
} 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 {
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);
}
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 wrapper = proc.get_socket_mut(fd)?;
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)
}
#[repr(C)]
// cancel alignment
#[repr(packed)]
pub struct SockAddrIn {
sin_family: u16,
sin_port: u16,
sin_addr: u32,
sin_zero: [u8; 8],
@ -810,7 +833,6 @@ pub struct SockAddrIn {
#[repr(C)]
pub struct SockAddrUn {
sun_family: u16,
sun_path: [u8; 108],
}
@ -833,7 +855,6 @@ impl From<IpEndpoint> for SockAddr {
family: AF_INET as u16,
payload: SockAddrPayload {
addr_in: SockAddrIn {
sin_family: AF_INET as u16,
sin_port: u16::to_be(endpoint.port),
sin_addr: u32::to_be(u32::from_be_bytes(ipv4.0)),
sin_zero: [0; 8],

@ -112,3 +112,35 @@ pub fn sys_time(time: *mut u64) -> SysResult {
}
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