diff --git a/repos/libports/include/libc-plugin/fd_alloc.h b/repos/libports/include/libc-plugin/fd_alloc.h index f046636b5..593529f31 100644 --- a/repos/libports/include/libc-plugin/fd_alloc.h +++ b/repos/libports/include/libc-plugin/fd_alloc.h @@ -112,6 +112,12 @@ namespace Libc { */ File_descriptor *any_cloexec_libc_fd(); + /** + * Return file-descriptor ID of any open file, or -1 if no file is + * open + */ + int any_open_fd(); + void generate_info(Genode::Xml_generator &); }; diff --git a/repos/libports/src/lib/libc/exit.cc b/repos/libports/src/lib/libc/exit.cc index 926de9c5a..bf178584f 100644 --- a/repos/libports/src/lib/libc/exit.cc +++ b/repos/libports/src/lib/libc/exit.cc @@ -14,6 +14,9 @@ #include #include +/* libc-internal includes */ +#include + extern void genode_exit(int status) __attribute__((noreturn)); extern "C" void _exit(int status) @@ -31,6 +34,8 @@ extern "C" { void exit(int status) { + using namespace Libc; + if (__cleanup) (*__cleanup)(); diff --git a/repos/libports/src/lib/libc/fd_alloc.cc b/repos/libports/src/lib/libc/fd_alloc.cc index 57e0c4c0f..27dd9e473 100644 --- a/repos/libports/src/lib/libc/fd_alloc.cc +++ b/repos/libports/src/lib/libc/fd_alloc.cc @@ -125,6 +125,18 @@ File_descriptor *File_descriptor_allocator::any_cloexec_libc_fd() } +int File_descriptor_allocator::any_open_fd() +{ + Lock::Guard guard(_lock); + + int result = -1; + _id_space.apply_any([&] (File_descriptor &fd) { + result = fd.libc_fd; }); + + return result; +} + + void File_descriptor_allocator::generate_info(Xml_generator &xml) { Lock::Guard guard(_lock); diff --git a/repos/libports/src/lib/libc/file_operations.cc b/repos/libports/src/lib/libc/file_operations.cc index 4b467baa7..bb4d274ad 100644 --- a/repos/libports/src/lib/libc/file_operations.cc +++ b/repos/libports/src/lib/libc/file_operations.cc @@ -234,9 +234,14 @@ extern "C" int chdir(const char *path) __SYS_(int, close, (int libc_fd), { File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd); - return (!fd || !fd->plugin) - ? Errno(EBADF) - : fd->plugin->close(fd); + + if (!fd) + return Errno(EBADF); + + if (!fd->plugin || fd->plugin->close(fd) != 0) + file_descriptor_allocator()->free(fd); + + return 0; }) diff --git a/repos/libports/src/lib/libc/kernel.cc b/repos/libports/src/lib/libc/kernel.cc index f04160a5f..222a91b08 100644 --- a/repos/libports/src/lib/libc/kernel.cc +++ b/repos/libports/src/lib/libc/kernel.cc @@ -359,10 +359,23 @@ void Libc::execute_in_application_context(Application_code &app_code) } +static void close_file_descriptors_on_exit() +{ + for (;;) { + int const fd = Libc::file_descriptor_allocator()->any_open_fd(); + if (fd == -1) + break; + close(fd); + } +} + + Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap) : _env(env), _heap(heap) { + atexit(close_file_descriptors_on_exit); + init_pthread_support(env, *this, *this); _env.ep().register_io_progress_handler(*this); diff --git a/repos/libports/src/lib/libc/plugin.cc b/repos/libports/src/lib/libc/plugin.cc index b4932944b..75693078d 100644 --- a/repos/libports/src/lib/libc/plugin.cc +++ b/repos/libports/src/lib/libc/plugin.cc @@ -155,7 +155,6 @@ bool Plugin::supports_mmap() #define DUMMY(ret_type, ret_val, name, args) \ ret_type Plugin::name args \ { \ - error(__func__, ": " #name " not implemented"); \ return ret_val; \ }