From a1576b12ade74163292b54f0617f97251bd904fb Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 7 Mar 2019 14:55:31 +0800 Subject: [PATCH] Fix dup2 socket ref count and sys_accept, close sockets on sys_exit --- kernel/src/syscall/fs.rs | 4 ++-- kernel/src/syscall/net.rs | 11 +++++++++-- kernel/src/syscall/proc.rs | 11 ++++++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index d1b6657..3f64336 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -304,7 +304,7 @@ pub fn sys_close(fd: usize) -> SysResult { sys_close_internal(&mut proc, fd) } -fn sys_close_internal(proc: &mut Process, fd: usize) -> SysResult { +pub fn sys_close_internal(proc: &mut Process, fd: usize) -> SysResult { match proc.files.remove(&fd) { Some(FileLike::File(_)) => Ok(0), Some(FileLike::Socket(wrapper)) => sys_close_socket(proc, fd, wrapper.handle), @@ -417,7 +417,7 @@ pub fn sys_getdents64(fd: usize, buf: *mut LinuxDirent64, buf_size: usize) -> Sy } pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult { - info!("dup2: {} {}", fd1, fd2); + info!("dup2: from {} to {}", fd1, fd2); let mut proc = process(); if proc.files.contains_key(&fd2) { // close fd2 first if it is opened diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index 88ba1e9..dc46e39 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -526,6 +526,10 @@ pub fn sys_close_socket(proc: &mut Process, fd: usize, handle: SocketHandle) -> let mut sockets = iface.sockets(); sockets.release(handle); sockets.prune(); + + // send FIN immediately when applicable + drop(sockets); + iface.poll(); Ok(0) } @@ -608,7 +612,7 @@ pub fn sys_accept(fd: usize, addr: *mut u8, addr_len: *mut u32) -> SysResult { let mut socket = sockets.get::(wrapper.handle); if socket.is_active() { - let endpoint = socket.remote_endpoint(); + let remote_endpoint = socket.remote_endpoint(); drop(socket); // move the current one to new_fd @@ -635,7 +639,7 @@ pub fn sys_accept(fd: usize, addr: *mut u8, addr_len: *mut u32) -> SysResult { if addr as usize != 0 { let mut sockaddr_in = unsafe { &mut *(addr as *mut SockaddrIn) }; - fill_addr(&mut sockaddr_in, endpoint.addr, endpoint.port); + fill_addr(&mut sockaddr_in, remote_endpoint.addr, remote_endpoint.port); unsafe { *addr_len = size_of::() as u32 }; } return Ok(new_fd as isize); @@ -717,6 +721,9 @@ 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), diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 1bcfc02..4fbd9ab 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -69,7 +69,6 @@ pub fn sys_exec(name: *const u8, argv: *const *const u8, envp: *const *const u8, } } info!("exec: args {:?}", args); - info!("exec {:?}", proc.files); // Read program file let path = args[0].as_str(); @@ -129,6 +128,16 @@ pub fn sys_getppid() -> SysResult { pub fn sys_exit(exit_code: isize) -> ! { let pid = thread::current().id(); info!("exit: {}, code: {}", pid, exit_code); + + // close all files. + // TODO: close them in all possible ways a process can exit + let mut proc = process(); + let fds: Vec = proc.files.keys().cloned().collect(); + for fd in fds.into_iter() { + sys_close_internal(&mut proc, fd); + } + drop(proc); + processor().manager().exit(pid, exit_code as usize); processor().yield_now(); unreachable!();