diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 3f64336..39eedda 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -85,8 +85,8 @@ pub fn sys_poll(ufds: *mut PollFd, nfds: usize, timeout_msecs: usize) -> SysResu poll.revents = poll.revents | PE::IN; events = events + 1; } - if output && poll.events.contains(PE::IN) { - poll.revents = poll.revents | PE::IN; + if output && poll.events.contains(PE::OUT) { + poll.revents = poll.revents | PE::OUT; events = events + 1; } } @@ -312,6 +312,12 @@ pub fn sys_close_internal(proc: &mut Process, fd: usize) -> SysResult { } } +pub fn sys_access(path: *const u8, mode: usize) -> SysResult { + info!("access: path: {:?}, mode: {}", path, mode); + // TODO: check permissions based on uid/git + Ok(0) +} + pub fn sys_getcwd(buf: *mut u8, len: usize) -> SysResult { info!("getcwd: buf: {:?}, len: {:#x}", buf, len); let mut proc = process(); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index ea1bb79..f6933c5 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -49,7 +49,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 011 => sys_munmap(args[0], args[1]), 019 => sys_readv(args[0], args[1] as *const IoVec, args[2]), 020 => sys_writev(args[0], args[1] as *const IoVec, args[2]), -// 021 => sys_access(), + 021 => sys_access(args[0] as *const u8, args[1]), 023 => sys_select(args[0], args[1] as *mut u32, args[2] as *mut u32, args[3] as *mut u32, args[4] as *const TimeVal), 024 => sys_yield(), 033 => sys_dup2(args[0], args[1]), @@ -67,6 +67,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 049 => sys_bind(args[0], args[1] as *const SockaddrIn, 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), 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(), diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index a8ca6b4..b14c0e9 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -621,6 +621,48 @@ 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 { + info!( + "sys_getpeername: 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(); + + if addr as usize == 0 { + 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::() { + 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(Some(endpoint)) = wrapper.socket_type { + let mut sockets = iface.sockets(); + let socket = sockets.get::(wrapper.handle); + + if socket.is_open() { + let remote_endpoint = socket.remote_endpoint(); + let sockaddr_in = SockaddrIn::from(remote_endpoint); + unsafe { sockaddr_in.write_to(addr, addr_len); } + Ok(0) + } else { + Err(SysError::EINVAL) + } + } else { + Err(SysError::EINVAL) + } +} + /// Check socket state /// return (in, out, err) pub fn poll_socket(wrapper: &SocketWrapper) -> (bool, bool, bool) {