]> xenbits.xensource.com Git - libvirt.git/commitdiff
build: use gnulib passfd for simpler SCM_RIGHTS code
authorEric Blake <eblake@redhat.com>
Wed, 20 Apr 2011 19:56:50 +0000 (13:56 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 26 Apr 2011 16:36:56 +0000 (10:36 -0600)
* .gnulib: Update to latest for passfd fixes.
* bootstrap.conf (gnulib_modules): Add passfd.
* src/util/util.c (virFileOpenAs): Simplify.

.gnulib
bootstrap.conf
src/util/util.c

diff --git a/.gnulib b/.gnulib
index fb799692f5bb43310424977e0ca15599fc68d776..7d06b32684363a39fae65c616b84bc7589768106 160000 (submodule)
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit fb799692f5bb43310424977e0ca15599fc68d776
+Subproject commit 7d06b32684363a39fae65c616b84bc7589768106
index 293f86eb9e2119b9ce446a43175ee246cbd8aa8d..3b3a90fd5e02b624e6ca3786d2d51a8820f62444 100644 (file)
@@ -52,6 +52,7 @@ mkstemps
 mktempd
 netdb
 nonblocking
+passfd
 perror
 physmem
 pipe-posix
index d4d2610b1e5f02b03058b19ed19e4000a11a9e44..de4e3b33f7dd138ac6bae294a0af1a3df51a9667 100644 (file)
@@ -78,6 +78,7 @@
 #include "files.h"
 #include "command.h"
 #include "nonblocking.h"
+#include "passfd.h"
 
 #ifndef NSIG
 # define NSIG 32
@@ -1480,11 +1481,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
     int waitret, status, ret = 0;
     int fd = -1;
     int pair[2] = { -1, -1 };
-    struct msghdr msg;
-    struct cmsghdr *cmsg;
-    char buf[CMSG_SPACE(sizeof(fd))];
-    char dummy = 0;
-    struct iovec iov;
     int forkRet;
 
     if ((!(flags & VIR_FILE_OPEN_AS_UID))
@@ -1506,18 +1502,6 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
         return ret;
     }
 
-    memset(&msg, 0, sizeof(msg));
-    iov.iov_base = &dummy;
-    iov.iov_len = 1;
-    msg.msg_iov = &iov;
-    msg.msg_iovlen = 1;
-    msg.msg_control = buf;
-    msg.msg_controllen = sizeof(buf);
-    cmsg = CMSG_FIRSTHDR(&msg);
-    cmsg->cmsg_level = SOL_SOCKET;
-    cmsg->cmsg_type = SCM_RIGHTS;
-    cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
-
     forkRet = virFork(&pid);
 
     if (pid < 0) {
@@ -1529,26 +1513,20 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
         VIR_FORCE_CLOSE(pair[1]);
 
         do {
-            ret = recvmsg(pair[0], &msg, 0);
+            ret = recvfd(pair[0], 0);
         } while (ret < 0 && errno == EINTR);
 
-        if (ret < 0) {
+        if (ret < 0 && errno != EACCES) {
             ret = -errno;
             VIR_FORCE_CLOSE(pair[0]);
             while ((waitret = waitpid(pid, NULL, 0) == -1)
                    && (errno == EINTR));
             goto parenterror;
+        } else {
+            fd = ret;
         }
         VIR_FORCE_CLOSE(pair[0]);
 
-        /* See if fd was transferred.  */
-        cmsg = CMSG_FIRSTHDR(&msg);
-        if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(fd)) &&
-            cmsg->cmsg_level == SOL_SOCKET &&
-            cmsg->cmsg_type == SCM_RIGHTS) {
-            memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
-        }
-
         /* wait for child to complete, and retrieve its exit code */
         while ((waitret = waitpid(pid, &status, 0) == -1)
                && (errno == EINTR));
@@ -1557,12 +1535,14 @@ virFileOpenAs(const char *path, int openflags, mode_t mode,
             virReportSystemError(errno,
                                  _("failed to wait for child creating '%s'"),
                                  path);
+            VIR_FORCE_CLOSE(fd);
             goto parenterror;
         }
         if (!WIFEXITED(status) || (ret = -WEXITSTATUS(status)) == -EACCES ||
             fd == -1) {
             /* fall back to the simpler method, which works better in
              * some cases */
+            VIR_FORCE_CLOSE(fd);
             return virFileOpenAsNoFork(path, openflags, mode, uid, gid, flags);
         }
         if (!ret)
@@ -1627,10 +1607,9 @@ parenterror:
                              path, mode);
         goto childerror;
     }
-    memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
 
     do {
-        ret = sendmsg(pair[1], &msg, 0);
+        ret = sendfd(pair[1], fd);
     } while (ret < 0 && errno == EINTR);
 
     if (ret < 0) {
@@ -1638,7 +1617,6 @@ parenterror:
         goto childerror;
     }
 
-    ret = 0;
 childerror:
     /* ret tracks -errno on failure, but exit value must be positive.
      * If the child exits with EACCES, then the parent tries again.  */