#include "virlog.h"
#include "virprocess.h"
#include "virstring.h"
+#include "virthread.h"
#include "virutil.h"
#include "virsocket.h"
# define O_DIRECT 0
#endif
+static virOnceControl virCloseRangeOnce = VIR_ONCE_CONTROL_INITIALIZER;
+static bool virCloseRangeSupported;
+
int virFileClose(int *fdptr, virFileCloseFlags flags)
{
int saved_errno = 0;
}
+static int
+virCloseRangeImpl(unsigned int first G_GNUC_UNUSED,
+ unsigned int last G_GNUC_UNUSED)
+{
+#if defined(WITH_SYS_SYSCALL_H) && defined(__NR_close_range)
+ return syscall(__NR_close_range, first, last, 0);
+#endif
+
+ errno = ENOSYS;
+ return -1;
+}
+
+
+static void
+virCloseRangeOnceInit(void)
+{
+ int fd[2] = {-1, -1};
+
+ if (virPipeQuiet(fd) < 0)
+ return;
+
+ VIR_FORCE_CLOSE(fd[1]);
+ if (virCloseRangeImpl(fd[0], fd[0]) < 0) {
+ VIR_FORCE_CLOSE(fd[0]);
+ return;
+ }
+
+ virCloseRangeSupported = true;
+}
+
+
+/**
+ * virCloseRange:
+ *
+ * Closes all open file descriptors from @first to @last (included).
+ *
+ * Returns: 0 on success,
+ * -1 on failure (with errno set).
+ */
+int
+virCloseRange(unsigned int first,
+ unsigned int last)
+{
+ if (virCloseRangeInit() < 0)
+ return -1;
+
+ if (!virCloseRangeSupported) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return virCloseRangeImpl(first, last);
+}
+
+
+/**
+ * virCloseRangeInit:
+ *
+ * Detects whether close_range() is available and cache the result.
+ */
+int
+virCloseRangeInit(void)
+{
+ if (virOnce(&virCloseRangeOnce, virCloseRangeOnceInit) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+/**
+ * virCloseRangeIsSupported:
+ *
+ * Returns whether close_range() is supported or not.
+ */
+bool
+virCloseRangeIsSupported(void)
+{
+ if (virCloseRangeInit() < 0)
+ return false;
+
+ return virCloseRangeSupported;
+}
+
+
/**
* virFileDirectFdFlag:
*
ignore_value(virFileClose(fd, VIR_FILE_CLOSE_PRESERVE_ERRNO));
}
+int virCloseRange(unsigned int from, unsigned int to);
+int virCloseRangeInit(void);
+bool virCloseRangeIsSupported(void);
+
/* For use on normal paths; caller must check return value,
and failure sets errno per close. */
#define VIR_CLOSE(FD) virFileClose(&(FD), 0)