Use union to implement sockaddr, and eliminate many warnings

master
Jiajie Chen 6 years ago
parent d041884cc2
commit cb0a51d28d

@ -279,7 +279,7 @@ impl Process {
fn memory_set_from(elf: &ElfFile<'_>) -> (MemorySet, usize) {
debug!("creating MemorySet from ELF");
let mut ms = MemorySet::new();
let mut entry = elf.header.pt2.entry_point() as usize;
let entry = elf.header.pt2.entry_point() as usize;
// [NoMMU] Get total memory size and alloc space
let va_begin = elf.program_iter()

@ -68,7 +68,7 @@ pub fn sys_write_file(proc: &mut Process, fd: usize, base: *const u8, len: usize
pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResult {
info!("poll: ufds: {:?}, nfds: {}, timeout_msecs: {:#x}", ufds, nfds, timeout_msecs);
let mut proc = process();
let proc = process();
proc.memory_set.check_mut_array(ufds, nfds)?;
let polls = unsafe { slice::from_raw_parts_mut(ufds, nfds) };
@ -82,7 +82,7 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu
let begin_time_ms = crate::trap::uptime_msec();
loop {
use PollEvents as PE;
let mut proc = process();
let proc = process();
let mut events = 0;
for poll in polls.iter_mut() {
poll.revents = PE::NONE;
@ -192,7 +192,7 @@ impl FdSet {
pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, timeout: *const TimeVal) -> SysResult {
info!("select: nfds: {}, read: {:?}, write: {:?}, err: {:?}, timeout: {:?}", nfds, read, write, err, timeout);
let mut proc = process();
let proc = process();
let mut read_fds = FdSet::new(&proc, read, nfds)?;
let mut write_fds = FdSet::new(&proc, write, nfds)?;
let mut err_fds = FdSet::new(&proc, err, nfds)?;
@ -207,7 +207,7 @@ pub fn sys_select(nfds: usize, read: *mut u32, write: *mut u32, err: *mut u32, t
let begin_time_ms = crate::trap::uptime_msec();
loop {
let mut proc = process();
let proc = process();
let mut events = 0;
for (fd, file) in proc.files.iter() {
if *fd < nfds {
@ -336,7 +336,7 @@ pub fn sys_access(path: *const u8, mode: usize) -> SysResult {
pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult {
info!("getcwd: buf: {:?}, len: {:#x}", buf, len);
let mut proc = process();
let proc = process();
proc.memory_set.check_mut_array(buf, len)?;
if proc.cwd.len() + 1 > len {
return Err(SysError::ERANGE);
@ -364,7 +364,7 @@ pub fn sys_fstat(fd: usize, stat_ptr: *mut Stat) -> SysResult {
}
pub fn sys_lstat(path: *const u8, stat_ptr: *mut Stat) -> SysResult {
let mut proc = process();
let proc = process();
let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
proc.memory_set.check_mut_ptr(stat_ptr)?;
info!("lstat: path: {}", path);
@ -403,7 +403,7 @@ pub fn sys_fdatasync(fd: usize) -> SysResult {
}
pub fn sys_truncate(path: *const u8, len: usize) -> SysResult {
let mut proc = process();
let proc = process();
let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
info!("truncate: path: {:?}, len: {}", path, len);
proc.lookup_inode(&path)?.resize(len)?;
@ -480,7 +480,7 @@ pub fn sys_chdir(path: *const u8) -> SysResult {
}
pub fn sys_rename(oldpath: *const u8, newpath: *const u8) -> SysResult {
let mut proc = process();
let proc = process();
let oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath)? };
let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? };
info!("rename: oldpath: {:?}, newpath: {:?}", oldpath, newpath);
@ -499,7 +499,7 @@ pub fn sys_rename(oldpath: *const u8, newpath: *const u8) -> SysResult {
}
pub fn sys_mkdir(path: *const u8, mode: usize) -> SysResult {
let mut proc = process();
let proc = process();
let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
// TODO: check pathname
info!("mkdir: path: {:?}, mode: {:#o}", path, mode);
@ -514,7 +514,7 @@ pub fn sys_mkdir(path: *const u8, mode: usize) -> SysResult {
}
pub fn sys_link(oldpath: *const u8, newpath: *const u8) -> SysResult {
let mut proc = process();
let proc = process();
let oldpath = unsafe { proc.memory_set.check_and_clone_cstr(oldpath)? };
let newpath = unsafe { proc.memory_set.check_and_clone_cstr(newpath)? };
info!("link: oldpath: {:?}, newpath: {:?}", oldpath, newpath);
@ -527,7 +527,7 @@ pub fn sys_link(oldpath: *const u8, newpath: *const u8) -> SysResult {
}
pub fn sys_unlink(path: *const u8) -> SysResult {
let mut proc = process();
let proc = process();
let path = unsafe { proc.memory_set.check_and_clone_cstr(path)? };
info!("unlink: path: {:?}", path);

@ -8,10 +8,20 @@ use crate::memory::GlobalFrameAlloc;
use super::*;
pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd: i32, offset: usize) -> SysResult {
pub fn sys_mmap(
mut addr: usize,
len: usize,
prot: usize,
flags: usize,
fd: i32,
offset: usize,
) -> SysResult {
let prot = MmapProt::from_bits_truncate(prot);
let flags = MmapFlags::from_bits_truncate(flags);
info!("mmap: addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}", addr, len, prot, flags, fd, offset);
info!(
"mmap: addr={:#x}, size={:#x}, prot={:?}, flags={:?}, fd={}, offset={:#x}",
addr, len, prot, flags, fd, offset
);
let mut proc = process();
if addr == 0 {
@ -32,7 +42,13 @@ pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd:
if flags.contains(MmapFlags::SHARED) {
return Err(SysError::EINVAL);
}
proc.memory_set.push(addr, addr + len, prot.to_attr(), Delay::new(GlobalFrameAlloc), "mmap");
proc.memory_set.push(
addr,
addr + len,
prot.to_attr(),
Delay::new(GlobalFrameAlloc),
"mmap",
);
return Ok(addr);
}
unimplemented!()
@ -40,7 +56,10 @@ pub fn sys_mmap(mut addr: usize, mut len: usize, prot: usize, flags: usize, fd:
pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult {
let prot = MmapProt::from_bits_truncate(prot);
info!("mprotect: addr={:#x}, size={:#x}, prot={:?}", addr, len, prot);
info!(
"mprotect: addr={:#x}, size={:#x}, prot={:?}",
addr, len, prot
);
let mut proc = process();
let attr = prot.to_attr();
@ -53,7 +72,9 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult {
}
proc.memory_set.edit(|pt| {
for page in Page::range_of(addr, addr + len) {
let entry = pt.get_entry(page.start_address()).expect("failed to get entry");
let entry = pt
.get_entry(page.start_address())
.expect("failed to get entry");
attr.apply(entry);
}
});
@ -96,9 +117,11 @@ bitflags! {
impl MmapProt {
fn to_attr(self) -> MemoryAttr {
let mut attr = MemoryAttr::default().user();
if self.contains(MmapProt::EXEC) { attr = attr.execute(); }
if self.contains(MmapProt::EXEC) {
attr = attr.execute();
}
// FIXME: see sys_mprotect
// if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); }
// if !self.contains(MmapProt::WRITE) { attr = attr.readonly(); }
attr
}
}

@ -54,23 +54,29 @@ pub fn sys_sysinfo(sys_info: *mut SysInfo) -> SysResult {
proc.memory_set.check_mut_ptr(sys_info)?;
let sysinfo = SysInfo::default();
unsafe {
*sys_info = sysinfo
};
unsafe { *sys_info = sysinfo };
Ok(0)
}
pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> SysResult {
info!("futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}",
thread::current().id(), uaddr, op, val, timeout);
// if op & OP_PRIVATE == 0 {
// unimplemented!("futex only support process-private");
// return Err(SysError::ENOSYS);
// }
info!(
"futex: [{}] uaddr: {:#x}, op: {:#x}, val: {}, timeout_ptr: {:?}",
thread::current().id(),
uaddr,
op,
val,
timeout
);
// if op & OP_PRIVATE == 0 {
// unimplemented!("futex only support process-private");
// return Err(SysError::ENOSYS);
// }
if uaddr % size_of::<u32>() != 0 {
return Err(SysError::EINVAL);
}
process().memory_set.check_mut_ptr(uaddr as *mut AtomicI32)?;
process()
.memory_set
.check_mut_ptr(uaddr as *mut AtomicI32)?;
let atomic = unsafe { &mut *(uaddr as *mut AtomicI32) };
let timeout = if timeout.is_null() {
None
@ -101,7 +107,7 @@ pub fn sys_futex(uaddr: usize, op: u32, val: i32, timeout: *const TimeSpec) -> S
_ => {
warn!("unsupported futex operation: {}", op);
Err(SysError::ENOSYS)
},
}
}
}
@ -119,5 +125,5 @@ pub struct SysInfo {
procs: u16,
totalhigh: u64,
freehigh: u64,
mem_unit: u32
}
mem_unit: u32,
}

@ -59,17 +59,17 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
035 => sys_nanosleep(args[0] as *const TimeSpec),
039 => sys_getpid(),
041 => sys_socket(args[0], args[1], args[2]),
042 => sys_connect(args[0], args[1] as *const SockaddrIn, args[2]),
043 => sys_accept(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32),
044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const SockaddrIn, args[5]),
045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut SockaddrIn, args[5] as *mut u32),
042 => sys_connect(args[0], args[1] as *const SockAddr, args[2]),
043 => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const SockAddr, args[5]),
045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut SockAddr, args[5] as *mut u32),
// 046 => sys_sendmsg(),
// 047 => sys_recvmsg(),
048 => sys_shutdown(args[0], args[1]),
049 => sys_bind(args[0], args[1] as *const SockaddrIn, args[2]),
049 => sys_bind(args[0], args[1] as *const SockAddr, args[2]),
050 => sys_listen(args[0], args[1]),
051 => sys_getsockname(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32),
052 => sys_getpeername(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32),
051 => sys_getsockname(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
052 => sys_getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32),
054 => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]),
055 => sys_getsockopt(args[0], args[1], args[2], args[3] as *mut u8, args[4] as *mut u32),
056 => sys_clone(args[0], args[1], args[2] as *mut u32, args[3] as *mut u32, args[4], tf),
@ -109,7 +109,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
204 => sys_sched_getaffinity(args[0], args[1], args[2] as *mut u32),
217 => sys_getdents64(args[0], args[1] as *mut LinuxDirent64, args[2]),
228 => sys_clock_gettime(args[0], args[1] as *mut TimeSpec),
288 => sys_accept(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), // use accept for accept4
288 => sys_accept(args[0], args[1] as *mut SockAddr, args[2] as *mut u32), // use accept for accept4
// 293 => sys_pipe(),
// for musl: empty impl

@ -3,6 +3,7 @@
use super::*;
use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY};
use crate::process::structs::TcpSocketState;
use core::cmp::min;
use core::mem::size_of;
use smoltcp::socket::*;
use smoltcp::wire::*;
@ -159,18 +160,15 @@ impl Process {
}
}
pub fn sys_connect(fd: usize, addr: *const SockaddrIn, addrlen: usize) -> SysResult {
pub fn sys_connect(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult {
info!(
"sys_connect: fd: {}, addr: {:?}, addrlen: {}",
fd, addr, addrlen
"sys_connect: fd: {}, addr: {:?}, addr_len: {}",
fd, addr, addr_len
);
let mut proc = process();
proc.memory_set.check_ptr(addr)?;
// FIXME: check size as per sin_family
let sockaddr_in = unsafe { &*(addr) };
let endpoint = sockaddr_in.to_endpoint()?;
let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?;
let wrapper = proc.get_socket(fd)?;
if let SocketType::Tcp(_) = wrapper.socket_type {
@ -192,7 +190,7 @@ pub fn sys_connect(fd: usize, addr: *const SockaddrIn, addrlen: usize) -> SysRes
iface.poll();
let mut sockets = iface.sockets();
let mut socket = sockets.get::<TcpSocket>(wrapper.handle);
let socket = sockets.get::<TcpSocket>(wrapper.handle);
if socket.state() == TcpState::SynSent {
// still connecting
drop(socket);
@ -308,7 +306,7 @@ pub fn sys_sendto(
buffer: *const u8,
len: usize,
flags: usize,
addr: *const SockaddrIn,
addr: *const SockAddr,
addr_len: usize,
) -> SysResult {
info!(
@ -317,11 +315,9 @@ pub fn sys_sendto(
);
let mut proc = process();
proc.memory_set.check_ptr(addr)?;
proc.memory_set.check_array(buffer, len)?;
let sockaddr_in = unsafe { &*(addr) };
let endpoint = sockaddr_in.to_endpoint()?;
let endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?;
let iface = &*(NET_DRIVERS.read()[0]);
@ -389,7 +385,7 @@ pub fn sys_recvfrom(
buffer: *mut u8,
len: usize,
flags: usize,
addr: *mut SockaddrIn,
addr: *mut SockAddr,
addr_len: *mut u32,
) -> SysResult {
info!(
@ -404,7 +400,7 @@ pub fn sys_recvfrom(
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() {
if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL);
}
@ -423,16 +419,16 @@ pub fn sys_recvfrom(
let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) };
if let Ok(size) = socket.recv_slice(&mut slice) {
let mut packet = Ipv4Packet::new_unchecked(&slice);
let packet = Ipv4Packet::new_unchecked(&slice);
if !addr.is_null() {
// FIXME: check size as per sin_family
let sockaddr_in = SockaddrIn::from(IpEndpoint {
let sockaddr_in = SockAddr::from(IpEndpoint {
addr: IpAddress::Ipv4(packet.src_addr()),
port: 0,
});
unsafe {
sockaddr_in.write_to(addr, addr_len);
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
}
@ -452,9 +448,9 @@ pub fn sys_recvfrom(
let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) };
if let Ok((size, endpoint)) = socket.recv_slice(&mut slice) {
if !addr.is_null() {
let sockaddr_in = SockaddrIn::from(endpoint);
let sockaddr_in = SockAddr::from(endpoint);
unsafe {
sockaddr_in.write_to(addr, addr_len);
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
}
@ -474,9 +470,9 @@ pub fn sys_recvfrom(
let mut slice = unsafe { slice::from_raw_parts_mut(buffer, len) };
if let Ok(size) = socket.recv_slice(&mut slice) {
if !addr.is_null() {
let sockaddr_in = SockaddrIn::from(socket.remote_endpoint());
let sockaddr_in = SockAddr::from(socket.remote_endpoint());
unsafe {
sockaddr_in.write_to(addr, addr_len);
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
}
@ -519,16 +515,11 @@ impl Drop for SocketWrapper {
}
}
pub fn sys_bind(fd: usize, addr: *const SockaddrIn, len: usize) -> SysResult {
info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, len);
pub fn sys_bind(fd: usize, addr: *const SockAddr, addr_len: usize) -> SysResult {
info!("sys_bind: fd: {} addr: {:?} len: {}", fd, addr, addr_len);
let mut proc = process();
if len < size_of::<SockaddrIn>() {
return Err(SysError::EINVAL);
}
let sockaddr_in = unsafe { &*(addr) };
let mut endpoint = sockaddr_in.to_endpoint()?;
let mut endpoint = sockaddr_to_endpoint(&mut proc, addr, addr_len)?;
if endpoint.port == 0 {
endpoint.port = get_ephemeral_port();
}
@ -598,7 +589,7 @@ pub fn sys_shutdown(fd: usize, how: usize) -> SysResult {
}
}
pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysResult {
pub fn sys_accept(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult {
info!(
"sys_accept: fd: {} addr: {:?} addr_len: {:?}",
fd, addr, addr_len
@ -611,7 +602,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() {
if max_addr_len < size_of::<SockAddr>() {
debug!("length too short {}", max_addr_len);
return Err(SysError::EINVAL);
}
@ -625,7 +616,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe
loop {
let iface = &*(NET_DRIVERS.read()[0]);
let mut sockets = iface.sockets();
let mut socket = sockets.get::<TcpSocket>(wrapper.handle);
let socket = sockets.get::<TcpSocket>(wrapper.handle);
if socket.is_active() {
let remote_endpoint = socket.remote_endpoint();
@ -665,9 +656,9 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe
proc.files.insert(new_fd, orig_socket);
if !addr.is_null() {
let sockaddr_in = SockaddrIn::from(remote_endpoint);
let sockaddr_in = SockAddr::from(remote_endpoint);
unsafe {
sockaddr_in.write_to(addr, addr_len);
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
}
return Ok(new_fd);
@ -688,7 +679,7 @@ pub fn sys_accept(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysRe
}
}
pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysResult {
pub fn sys_getsockname(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult {
info!(
"sys_getsockname: fd: {} addr: {:?} addr_len: {:?}",
fd, addr, addr_len
@ -705,7 +696,7 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) ->
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() {
if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL);
}
@ -715,9 +706,9 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) ->
let wrapper = proc.get_socket_mut(fd)?;
if let SocketType::Tcp(state) = &wrapper.socket_type {
if let Some(endpoint) = state.local_endpoint {
let sockaddr_in = SockaddrIn::from(endpoint);
let sockaddr_in = SockAddr::from(endpoint);
unsafe {
sockaddr_in.write_to(addr, addr_len);
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
Ok(0)
} else {
@ -728,7 +719,7 @@ pub fn sys_getsockname(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) ->
}
}
pub fn sys_getpeername(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) -> SysResult {
pub fn sys_getpeername(fd: usize, addr: *mut SockAddr, addr_len: *mut u32) -> SysResult {
info!(
"sys_getpeername: fd: {} addr: {:?} addr_len: {:?}",
fd, addr, addr_len
@ -745,7 +736,7 @@ pub fn sys_getpeername(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) ->
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = unsafe { *addr_len } as usize;
if max_addr_len < size_of::<SockaddrIn>() {
if max_addr_len < size_of::<SockAddr>() {
return Err(SysError::EINVAL);
}
@ -759,9 +750,9 @@ pub fn sys_getpeername(fd: usize, addr: *mut SockaddrIn, addr_len: *mut u32) ->
if socket.is_open() {
let remote_endpoint = socket.remote_endpoint();
let sockaddr_in = SockaddrIn::from(remote_endpoint);
let sockaddr_in = SockAddr::from(remote_endpoint);
unsafe {
sockaddr_in.write_to(addr, addr_len);
sockaddr_in.write_to(&mut proc, addr, addr_len)?;
}
Ok(0)
} else {
@ -781,7 +772,7 @@ pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) {
if let SocketType::Tcp(state) = wrapper.socket_type.clone() {
let iface = &*(NET_DRIVERS.read()[0]);
let mut sockets = iface.sockets();
let mut socket = sockets.get::<TcpSocket>(wrapper.handle);
let socket = sockets.get::<TcpSocket>(wrapper.handle);
if state.is_listening && socket.is_active() {
// a new connection
@ -805,55 +796,115 @@ pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) {
}
pub fn sys_dup2_socket(proc: &mut Process, wrapper: SocketWrapper, fd: usize) -> SysResult {
let iface = &*(NET_DRIVERS.read()[0]);
let mut sockets = iface.sockets();
sockets.retain(wrapper.handle);
proc.files.insert(fd, FileLike::Socket(wrapper));
Ok(fd)
}
#[repr(C)]
pub struct SockaddrIn {
pub struct SockAddrIn {
sin_family: u16,
sin_port: u16,
sin_addr: u32,
sin_zero: [u8; 8],
}
impl From<IpEndpoint> for SockaddrIn {
#[repr(C)]
pub struct SockAddrUn {
sun_family: u16,
sun_path: [u8; 108],
}
#[repr(C)]
pub union SockAddrPayload {
addr_in: SockAddrIn,
addr_un: SockAddrUn,
}
#[repr(C)]
pub struct SockAddr {
family: u16,
payload: SockAddrPayload,
}
impl From<IpEndpoint> for SockAddr {
fn from(endpoint: IpEndpoint) -> Self {
match endpoint.addr {
IpAddress::Ipv4(ipv4) => 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],
IpAddress::Ipv4(ipv4) => 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],
},
},
},
_ => unimplemented!("ipv6"),
}
}
}
impl SockaddrIn {
fn to_endpoint(&self) -> Result<IpEndpoint, SysError> {
// FIXME: check size as per sin_family
if self.sin_family == AF_INET as u16 {
let port = u16::from_be(self.sin_port);
let addr = IpAddress::from(Ipv4Address::from_bytes(
&u32::from_be(self.sin_addr).to_be_bytes()[..],
));
Ok((addr, port).into())
} else if self.sin_family == AF_UNIX as u16 {
debug!("unix socket path {}", unsafe {
util::from_cstr((self as *const SockaddrIn as *const u8).add(2))
});
Err(SysError::EINVAL)
} else {
Err(SysError::EINVAL)
/// Convert sockaddr to endpoint
// Check len is long enough
fn sockaddr_to_endpoint(
proc: &mut Process,
addr: *const SockAddr,
len: usize,
) -> Result<IpEndpoint, SysError> {
if len < size_of::<u16>() {
return Err(SysError::EINVAL);
}
proc.memory_set.check_array(addr as *const u8, len)?;
unsafe {
match (*addr).family as usize {
AF_INET => {
if len < size_of::<u16>() + size_of::<SockAddrIn>() {
return Err(SysError::EINVAL);
}
let port = u16::from_be((*addr).payload.addr_in.sin_port);
let addr = IpAddress::from(Ipv4Address::from_bytes(
&u32::from_be((*addr).payload.addr_in.sin_addr).to_be_bytes()[..],
));
Ok((addr, port).into())
}
AF_UNIX => Err(SysError::EINVAL),
_ => Err(SysError::EINVAL),
}
}
unsafe fn write_to(self, addr: *mut SockaddrIn, addr_len: *mut u32) {
addr.write(self);
addr_len.write(size_of::<SockaddrIn>() as u32);
}
impl SockAddr {
/// Write to user sockaddr
/// Check mutability for user
unsafe fn write_to(
self,
proc: &mut Process,
addr: *mut SockAddr,
addr_len: *mut u32,
) -> SysResult {
// Ignore NULL
if addr.is_null() {
return Ok(0);
}
proc.memory_set.check_mut_ptr(addr_len)?;
let max_addr_len = *addr_len as usize;
let full_len = match self.family as usize {
AF_INET => size_of::<u16>() + size_of::<SockAddrIn>(),
AF_UNIX => return Err(SysError::EINVAL),
_ => return Err(SysError::EINVAL),
};
let written_len = min(max_addr_len, full_len);
if written_len > 0 {
proc.memory_set
.check_mut_array(addr as *mut u8, written_len)?;
let source = slice::from_raw_parts(&self as *const SockAddr as *const u8, written_len);
let target = slice::from_raw_parts_mut(addr as *mut u8, written_len);
target.copy_from_slice(source);
}
addr_len.write(full_len as u32);
return Ok(0);
}
}

@ -47,7 +47,7 @@ pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
return Err(SysError::EINVAL);
}
let mut proc = process();
let proc = process();
proc.memory_set.check_mut_ptr(tv)?;
let tick_base = *TICK_BASE;
@ -69,7 +69,7 @@ pub fn sys_gettimeofday(tv: *mut TimeVal, tz: *const u8) -> SysResult {
pub fn sys_clock_gettime(clock: usize, ts: *mut TimeSpec) -> SysResult {
info!("clock_gettime: clock: {:?}, ts: {:?}", clock, ts);
let mut proc = process();
let proc = process();
proc.memory_set.check_mut_ptr(ts)?;
let tick_base = *TICK_BASE;
@ -96,7 +96,7 @@ pub fn sys_time(time: *mut u64) -> SysResult {
let usec = (tick - tick_base) * USEC_PER_TICK as u64;
let sec = epoch_base + usec / 1_000_000;
if time as usize != 0 {
let mut proc = process();
let proc = process();
proc.memory_set.check_mut_ptr(time)?;
unsafe {
time.write(sec as u64);

Loading…
Cancel
Save