In order to make it cleaner, split qemu_close_all_open_fd() logic into
multiple subfunctions (close with close_range(), with /proc/self/fd and
fallback).
Signed-off-by: Clément Léger <cleger@rivosinc.com>
---
util/oslib-posix.c | 51 ++++++++++++++++++++++++++++++++++------------
1 file changed, 38 insertions(+), 13 deletions(-)
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 1e867efa47..a6749d9f9b 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -808,27 +808,16 @@ int qemu_msync(void *addr, size_t length, int fd)
return msync(addr, length, MS_SYNC);
}
-/*
- * Close all open file descriptors.
- */
-void qemu_close_all_open_fd(void)
+static bool qemu_close_all_open_fd_proc(void)
{
struct dirent *de;
int fd, dfd;
DIR *dir;
-#ifdef CONFIG_CLOSE_RANGE
- int r = close_range(0, ~0U, 0);
- if (!r) {
- /* Success, no need to try other ways. */
- return;
- }
-#endif
-
dir = opendir("/proc/self/fd");
if (!dir) {
/* If /proc is not mounted, there is nothing that can be done. */
- return;
+ return false;
}
/* Avoid closing the directory. */
dfd = dirfd(dir);
@@ -840,4 +829,40 @@ void qemu_close_all_open_fd(void)
}
}
closedir(dir);
+
+ return true;
+}
+
+static bool qemu_close_all_open_fd_close_range(void)
+{
+#ifdef CONFIG_CLOSE_RANGE
+ int r = close_range(0, ~0U, 0);
+ if (!r) {
+ /* Success, no need to try other ways. */
+ return true;
+ }
+#endif
+ return false;
+}
+
+/*
+ * Close all open file descriptors.
+ */
+void qemu_close_all_open_fd(void)
+{
+ int open_max = sysconf(_SC_OPEN_MAX);
+ int i;
+
+ if (qemu_close_all_open_fd_close_range()) {
+ return;
+ }
+
+ if (qemu_close_all_open_fd_proc()) {
+ return;
+ }
+
+ /* Fallback */
+ for (i = 0; i < open_max; i++) {
+ close(i);
+ }
}
--
2.45.2