It is handy to close all FDs from given FD to infinity. On
FreeBSD the libc even has a function for that: closefrom(). It
was ported to glibc too, but not musl. At least glibc
implementation falls back to calling:
close_range(from, ~0U, 0);
Now that we have a wrapper for close_range() we implement
closefrom() trivially.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virfile.c | 21 +++++++++++++++++++++
src/util/virfile.h | 1 +
3 files changed, 23 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3782f7f3c7..9477a07834 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2269,6 +2269,7 @@ saferead;
safewrite;
safezero;
virBuildPathInternal;
+virCloseFrom;
virCloseRange;
virCloseRangeInit;
virCloseRangeIsSupported;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 7696910e00..c74bdd1264 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -265,6 +265,27 @@ virCloseRangeIsSupported(void)
}
+/**
+ * virCloseFrom:
+ *
+ * Closes all open file descriptors greater than or equal to @fromfd.
+ *
+ * Returns: 0 on success,
+ * -1 on error (with errno set).
+ */
+int
+virCloseFrom(int fromfd)
+{
+#ifdef __FreeBSD__
+ /* FreeBSD has closefrom() since FreeBSD-8.0, i.e. since 2009. */
+ closefrom(fromfd);
+ return 0;
+#else /* !__FreeBSD__ */
+ return virCloseRange(fromfd, ~0U);
+#endif /* !__FreeBSD__ */
+}
+
+
/**
* virFileDirectFdFlag:
*
diff --git a/src/util/virfile.h b/src/util/virfile.h
index be0b02fdf0..adc032ba33 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -64,6 +64,7 @@ static inline void virForceCloseHelper(int *fd)
int virCloseRange(unsigned int from, unsigned int to);
int virCloseRangeInit(void);
bool virCloseRangeIsSupported(void);
+int virCloseFrom(int fromfd);
/* For use on normal paths; caller must check return value,
and failure sets errno per close. */
--
2.41.0