Fix dup2 socket ref count and sys_accept, close sockets on sys_exit

master
Jiajie Chen 6 years ago
parent c5aa5922bd
commit a1576b12ad

@ -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

@ -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::<TcpSocket>(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::<SockaddrIn>() 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),

@ -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<usize> = 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!();

Loading…
Cancel
Save