From 3e6860ae8a1d53b36e21b471412f407533c769a1 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 6 Mar 2019 10:57:28 +0800 Subject: [PATCH] Fix lookup_inode for absolute path, and implement sys_accept for tcp --- kernel/src/syscall/fs.rs | 14 +++++++-- kernel/src/syscall/mod.rs | 2 +- kernel/src/syscall/net.rs | 65 ++++++++++++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index 580cd11..a4afd75 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -332,9 +332,17 @@ impl Process { }) } fn lookup_inode(&self, path: &str) -> Result, SysError> { - let cwd = self.cwd.split_at(1).1; // skip start '/' - let inode = ROOT_INODE.lookup(cwd)?.lookup(path)?; - Ok(inode) + if path.len() > 0 && path.as_bytes()[0] == b'/' { + // absolute path + let abs_path = path.split_at(1).1; // skip start '/' + let inode = ROOT_INODE.lookup(abs_path)?; + Ok(inode) + } else { + // relative path + let cwd = self.cwd.split_at(1).1; // skip start '/' + let inode = ROOT_INODE.lookup(cwd)?.lookup(path)?; + Ok(inode) + } } } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 54cd20e..aed192f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -53,7 +53,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 039 => sys_getpid(), 041 => sys_socket(args[0], args[1], args[2]), 042 => sys_connect(args[0], args[1] as *const u8, args[2]), -// 043 => sys_accept(), + 043 => sys_accept(args[0], args[1] as *mut u8, args[2] as *mut u32), 044 => sys_sendto(args[0], args[1] as *const u8, args[2], args[3], args[4] as *const u8, args[5]), 045 => sys_recvfrom(args[0], args[1] as *mut u8, args[2], args[3], args[4] as *mut u8, args[5] as *mut u32), // 046 => sys_sendmsg(), diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index cd38682..ea3c21a 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -292,7 +292,7 @@ pub fn sys_read_socket(proc: &mut Process, fd: usize, base: *mut u8, len: usize) drop(socket); SOCKET_ACTIVITY._wait() } - } else if let SocketType::Udp = wrapper.socket_type { + } else if let SocketType::Udp = wrapper.socket_type { loop { let mut sockets = iface.sockets(); let mut socket = sockets.get::(wrapper.handle); @@ -565,21 +565,70 @@ pub fn sys_listen(fd: usize, backlog: usize) -> SysResult { let mut sockets = iface.sockets(); let mut socket = sockets.get::(wrapper.handle); - if let Err(_) = socket.listen(endpoint) { + match socket.listen(endpoint) { + Ok(()) => Ok(0), + Err(_) => Err(SysError::EINVAL), + } + } else { + Err(SysError::EINVAL) + } +} + +pub fn sys_accept(fd: usize, addr: *mut u8, addr_len: *mut u32) -> SysResult { + // smoltcp tcp sockets do not support backlog + // open multiple sockets for each connection + let mut proc = process(); + + if addr as usize != 0 { + 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); } - // avoid deadlock - drop(socket); - drop(sockets); + proc.memory_set.check_mut_array(addr, max_addr_len)?; + } + let iface = &mut *(NET_DRIVERS.lock()[0]); + let wrapper = proc.get_socket_mut(fd)?; + if let SocketType::Tcp(Some(endpoint)) = wrapper.socket_type { loop { let mut sockets = iface.sockets(); let mut socket = sockets.get::(wrapper.handle); if socket.is_active() { - // use the same one for now, but we should create a new one instead - return Ok(fd as isize); + let endpoint = socket.remote_endpoint(); + drop(socket); + + // move the current one to new_fd + // create a new one in fd + let new_fd = proc.get_free_inode(); + + let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; 2048]); + let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; 2048]); + let mut tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); + tcp_socket.listen(endpoint).unwrap(); + + let tcp_handle = sockets.add(tcp_socket); + let orig_handle = proc + .files + .insert( + fd, + FileLike::Socket(SocketWrapper { + handle: tcp_handle, + socket_type: SocketType::Tcp(None), + }), + ) + .unwrap(); + proc.files.insert(new_fd, orig_handle); + + if addr as usize != 0 { + let mut sockaddr_in = unsafe { &mut *(addr as *mut SockaddrIn) }; + fill_addr(&mut sockaddr_in, endpoint.addr, endpoint.port); + unsafe { *addr_len = size_of::() as u32 }; + } + return Ok(new_fd as isize); } // avoid deadlock @@ -590,4 +639,4 @@ pub fn sys_listen(fd: usize, backlog: usize) -> SysResult { } else { Err(SysError::EINVAL) } -} \ No newline at end of file +}