]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: command: Extract common parts of FD closing to virCommandMassClose
authorPeter Krempa <pkrempa@redhat.com>
Wed, 13 May 2026 09:15:03 +0000 (11:15 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 25 May 2026 11:28:57 +0000 (13:28 +0200)
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 <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/util/vircommand.c

index e871d572a66a94096989a2c401b2197c0328f88c..2d13cf629cb350ed47a3e589a2d8c66a9a48db65 100644 (file)
@@ -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);
 }