diff --git a/libos/include/libos_handle.h b/libos/include/libos_handle.h index ee8d95ae4a..9a9e62a1b8 100644 --- a/libos/include/libos_handle.h +++ b/libos/include/libos_handle.h @@ -268,6 +268,7 @@ int set_new_fd_handle_above_fd(uint32_t fd, struct libos_handle* hdl, int fd_fla struct libos_handle* __detach_fd_handle(struct libos_fd_handle* fd, int* flags, struct libos_handle_map* map); struct libos_handle* detach_fd_handle(uint32_t fd, int* flags, struct libos_handle_map* map); +void detach_all_fds(void); /* manage handle mapping */ int dup_handle_map(struct libos_handle_map** new_map, struct libos_handle_map* old_map); diff --git a/libos/src/bookkeep/libos_handle.c b/libos/src/bookkeep/libos_handle.c index 1901299d45..72e25f7b5d 100644 --- a/libos/src/bookkeep/libos_handle.c +++ b/libos/src/bookkeep/libos_handle.c @@ -323,6 +323,19 @@ struct libos_handle* detach_fd_handle(uint32_t fd, int* flags, return handle; } +static int detach_fd(struct libos_fd_handle* fd_hdl, struct libos_handle_map* map) { + struct libos_handle* hdl = __detach_fd_handle(fd_hdl, NULL, map); + put_handle(hdl); + return 0; +} + +void detach_all_fds(void) { + struct libos_handle_map* handle_map = get_thread_handle_map(NULL); + assert(handle_map); + + walk_handle_map(&detach_fd, handle_map); +} + struct libos_handle* get_new_handle(void) { struct libos_handle* new_handle = get_mem_obj_from_mgr_enlarge(handle_mgr, size_align_up(HANDLE_MGR_ALLOC)); @@ -651,10 +664,7 @@ int walk_handle_map(int (*callback)(struct libos_fd_handle*, struct libos_handle int ret = 0; lock(&map->lock); - if (map->fd_top == FD_NULL) - goto done; - - for (uint32_t i = 0; i <= map->fd_top; i++) { + for (uint32_t i = 0; map->fd_top != FD_NULL && i <= map->fd_top; i++) { if (!HANDLE_ALLOCATED(map->map[i])) continue; @@ -662,7 +672,6 @@ int walk_handle_map(int (*callback)(struct libos_fd_handle*, struct libos_handle break; } -done: unlock(&map->lock); return ret; } diff --git a/libos/src/sys/libos_exit.c b/libos/src/sys/libos_exit.c index ea47e6fad6..30e623b8c0 100644 --- a/libos/src/sys/libos_exit.c +++ b/libos/src/sys/libos_exit.c @@ -7,6 +7,7 @@ */ #include "libos_fs_lock.h" +#include "libos_handle.h" #include "libos_ipc.h" #include "libos_lock.h" #include "libos_process.h" @@ -99,6 +100,8 @@ noreturn void thread_exit(int error_code, int term_signal) { if (ret < 0) log_warning("error clearing POSIX locks: %d", ret); + detach_all_fds(); + /* This is the last thread of the process. Let parent know we exited. */ ret = ipc_cld_exit_send(error_code, term_signal); if (ret < 0) {