From: Peter Krempa <[email protected]>

Extract the lookup of used FDs and their setup to virCommandMassClose
rather than duplicate it in the two functions we have for using
different modes of FD closing.

Signed-off-by: Peter Krempa <[email protected]>
---
 src/util/vircommand.c | 85 ++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 46 deletions(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index e871d572a6..2d13cf629c 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -520,16 +520,12 @@ virCommandMassCloseGetFDs(virBitmap *fds)
 }

 static int
-virCommandMassCloseFrom(virCommand *cmd,
-                        int childin,
-                        int childout,
-                        int childerr)
+virCommandMassCloseFrom(virBitmap *keep)
 {
     g_autoptr(virBitmap) fds = NULL;
     int openmax = sysconf(_SC_OPEN_MAX);
-    int lastfd = -1;
+    int lastfd = virBitmapLastSetBit(keep);
     int fd = -1;
-    size_t i;

     /* In general, it is not safe to call malloc() between fork() and exec()
      * because the child might have forked at the worst possible time, i.e.
@@ -551,24 +547,14 @@ virCommandMassCloseFrom(virCommand *cmd,
     if (virCommandMassCloseGetFDs(fds) < 0)
         return -1;

-    lastfd = MAX(lastfd, childin);
-    lastfd = MAX(lastfd, childout);
-    lastfd = MAX(lastfd, childerr);
-
-    for (i = 0; i < cmd->npassfd; i++)
-        lastfd = MAX(lastfd, cmd->passfd[i].fd);
-
     fd = virBitmapNextSetBit(fds, 2);
     for (; fd >= 0 && fd <= lastfd; fd = virBitmapNextSetBit(fds, fd)) {
-        if (fd == childin || fd == childout || fd == childerr)
+        int tmpfd = fd;
+
+        if (virBitmapIsBitSet(keep, fd))
             continue;
-        if (!virCommandFDIsSet(cmd, fd)) {
-            int tmpfd = fd;
-            VIR_MASS_CLOSE(tmpfd);
-        } else if (virSetInherit(fd, true) < 0) {
-            virReportSystemError(errno, _("failed to preserve fd %1$d"), fd);
-            return -1;
-        }
+
+        VIR_MASS_CLOSE(tmpfd);
     }

     if (virCloseFrom(lastfd + 1) < 0) {
@@ -588,33 +574,13 @@ virCommandMassCloseFrom(virCommand *cmd,


 static int
-virCommandMassCloseRange(virCommand *cmd,
-                         int childin,
-                         int childout,
-                         int childerr)
+virCommandMassCloseRange(virBitmap *keep)
 {
-    g_autoptr(virBitmap) fds = virBitmapNew(0);
     ssize_t first;
     ssize_t last;
-    size_t i;
-
-    virBitmapSetBitExpand(fds, childin);
-    virBitmapSetBitExpand(fds, childout);
-    virBitmapSetBitExpand(fds, childerr);
-
-    for (i = 0; i < cmd->npassfd; i++) {
-        int fd = cmd->passfd[i].fd;
-
-        virBitmapSetBitExpand(fds, fd);
-
-        if (virSetInherit(fd, true) < 0) {
-            virReportSystemError(errno, _("failed to preserve fd %1$d"), fd);
-            return -1;
-        }
-    }

     first = 2;
-    while ((last = virBitmapNextSetBit(fds, first)) >= 0) {
+    while ((last = virBitmapNextSetBit(keep, first)) >= 0) {
         if (first + 1 == last) {
             first = last;
             continue;
@@ -642,17 +608,44 @@ virCommandMassCloseRange(virCommand *cmd,
 }


-
+/**
+ * virCommandMassClose:
+ * @cmd: command structure
+ * @childin: fd passed to child as stdin
+ * @childout: fd passed to child as stdout
+ * @childerr: fd passed to child as stderr
+ *
+ * Prepares FDs to be passed to the child process spawned by @cmd and closes
+ * every other FD.
+ */
 static int
 virCommandMassClose(virCommand *cmd,
                     int childin,
                     int childout,
                     int childerr)
 {
+    g_autoptr(virBitmap) fds = virBitmapNew(0);
+    size_t i;
+
+    virBitmapSetBitExpand(fds, childin);
+    virBitmapSetBitExpand(fds, childout);
+    virBitmapSetBitExpand(fds, childerr);
+
+    for (i = 0; i < cmd->npassfd; i++) {
+        int fd = cmd->passfd[i].fd;
+
+        virBitmapSetBitExpand(fds, fd);
+
+        if (virSetInherit(fd, true) < 0) {
+            virReportSystemError(errno, _("failed to preserve fd %1$d"), fd);
+            return -1;
+        }
+    }
+
     if (virCloseRangeIsSupported())
-        return virCommandMassCloseRange(cmd, childin, childout, childerr);
+        return virCommandMassCloseRange(fds);

-    return virCommandMassCloseFrom(cmd, childin, childout, childerr);
+    return virCommandMassCloseFrom(fds);
 }


-- 
2.54.0

Reply via email to