]> xenbits.xensource.com Git - libvirt.git/commitdiff
src: introduce a wrapper for the pipe2() system call
authorDaniel P. Berrangé <berrange@redhat.com>
Fri, 24 Jan 2020 15:21:00 +0000 (15:21 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Tue, 4 Feb 2020 14:00:44 +0000 (14:00 +0000)
This hides the differences between Windows and UNIX,
and adds standard error reporting.

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
configure.ac
src/libvirt_private.syms
src/util/virutil.c
src/util/virutil.h

index 0e68834b9200a2b16c42987bed36e189e99e5379..141c0cc5d83fb55ec1b5c79e09bca1a0f7c0e649 100644 (file)
@@ -368,6 +368,7 @@ AC_CHECK_FUNCS_ONCE([\
   newlocale \
   posix_fallocate \
   posix_memalign \
+  pipe2 \
   prlimit \
   sched_getaffinity \
   sched_setscheduler \
index 3facfe581d69f7a57401ae45debe5b5da2ae7920..5c81bb2c3fca3e0021217a55d9deced3e2146b70 100644 (file)
@@ -3410,6 +3410,9 @@ virMemoryLimitTruncate;
 virMemoryMaxValue;
 virParseOwnershipIds;
 virParseVersionString;
+virPipe;
+virPipeNonBlock;
+virPipeQuiet;
 virScaleInteger;
 virSetBlocking;
 virSetCloseExec;
index fa6b56fd79f63387957f65e9cfda308d1df08186..d5f3e72ba93401a21dda9660499b919f5b89b6cb 100644 (file)
@@ -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);
+}
index 62a53f34cb5c94e616d8780158beebc521f9899f..7377c8c8da81c6c5970e07f636ee03fec158fc5c 100644 (file)
@@ -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]);