This hides the differences between Windows and UNIX,
and adds standard error reporting.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
configure.ac | 1 +
src/libvirt_private.syms | 3 ++
src/util/virutil.c | 64 ++++++++++++++++++++++++++++++++++++++++
src/util/virutil.h | 34 +++++++++++++++++++++
4 files changed, 102 insertions(+)
diff --git a/configure.ac b/configure.ac
index 0964ab8d51..005753e8a1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -369,6 +369,7 @@ AC_CHECK_FUNCS_ONCE([\
newlocale \
posix_fallocate \
posix_memalign \
+ pipe2 \
prlimit \
sched_getaffinity \
sched_setscheduler \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 674f553403..56981541c5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3394,6 +3394,9 @@ virMemoryLimitTruncate;
virMemoryMaxValue;
virParseOwnershipIds;
virParseVersionString;
+virPipe;
+virPipeNonBlock;
+virPipeQuiet;
virScaleInteger;
virSetBlocking;
virSetCloseExec;
diff --git a/src/util/virutil.c b/src/util/virutil.c
index fa6b56fd79..d5f3e72ba9 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -1769,3 +1769,67 @@ char *virGetPassword(void)
return g_strdup(getpass(""));
#endif /* ! WIN32 */
}
+
+
+static int
+virPipeImpl(int fds[2], bool nonblock, bool errreport)
+{
+#ifdef HAVE_PIPE2
+ int flags = O_CLOEXEC;
+ if (nonblock)
+ flags |= O_NONBLOCK;
+ int rv = pipe2(fds, flags);
+#else /* !HAVE_PIPE2 */
+# ifdef WIN32
+ int rv = _pipe(fds, 4096, _O_BINARY);
+# else /* !WIN32 */
+ int rv = pipe(fds);
+# endif /* !WIN32 */
+#endif /* !HAVE_PIPE2 */
+
+ if (rv < 0) {
+ if (errreport)
+ virReportSystemError(errno, "%s",
+ _("Unable to create pipes"));
+ return rv;
+ }
+
+#ifndef HAVE_PIPE2
+ if (nonblock) {
+ if (virSetNonBlock(fds[0]) < 0 ||
+ virSetNonBlock(fds[1]) < 0) {
+ if (errreport)
+ virReportSystemError(errno, "%s",
+ _("Unable to set pipes to
non-blocking"));
+ virReportSystemError(errno, "%s",
+ _("Unable to create pipes"));
+ VIR_FORCE_CLOSE(fds[0]);
+ VIR_FORCE_CLOSE(fds[1]);
+ return -1;
+ }
+ }
+#endif /* !HAVE_PIPE2 */
+
+ return 0;
+}
+
+
+int
+virPipe(int fds[2])
+{
+ return virPipeImpl(fds, false, true);
+}
+
+
+int
+virPipeQuiet(int fds[2])
+{
+ return virPipeImpl(fds, false, false);
+}
+
+
+int
+virPipeNonBlock(int fds[2])
+{
+ return virPipeImpl(fds, true, true);
+}
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 62a53f34cb..7377c8c8da 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -161,3 +161,37 @@ char *virHostGetDRMRenderNode(void) G_GNUC_NO_INLINE;
(((lvalue) = (rvalue)) != (rvalue))
char *virGetPassword(void);
+
+/*
+ * virPipe:
+ *
+ * Open a pair of FDs which can be used to communicate
+ * with each other. The FDs will have O_CLOEXEC set.
+ * This will report a libvirt error on failure.
+ *
+ * Returns: -1 on error, 0 on success
+ */
+int virPipe(int fds[2]);
+
+/*
+ * virPipeQuiet:
+ *
+ * Open a pair of FDs which can be used to communicate
+ * with each other. The FDs will have O_CLOEXEC set.
+ * This will set errno on failure.
+ *
+ * Returns: -1 on error, 0 on success
+ */
+int virPipeQuiet(int fds[2]);
+
+/*
+ * virPipe:
+ *
+ * Open a pair of FDs which can be used to communicate
+ * with each other. The FDs will have O_CLOEXEC and
+ * O_NONBLOCK set.
+ * This will report a libvirt error on failure.
+ *
+ * Returns: -1 on error, 0 on success
+ */
+int virPipeNonBlock(int fds[2]);
--
2.24.1