]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: virDirCreate: Child now exits with positive errno-code
authorErik Skultety <eskultet@redhat.com>
Tue, 16 Jun 2015 11:43:38 +0000 (13:43 +0200)
committerErik Skultety <eskultet@redhat.com>
Tue, 16 Jun 2015 14:26:20 +0000 (16:26 +0200)
Previous patch of this series proposed a fix to virDirCreate, so that parent
process reports an error if child process failed its task.
However our logic still permits the child to exit with negative errno followed
by a check of the status on the parent side using WEXITSTATUS which, being
POSIX compliant, takes the lower 8 bits of the exit code and returns is to
the caller. However, by taking 8 bits from a negative exit code
(two's complement) the status value we read and append to stream is
'2^8 - abs(original exit code)' which doesn't quite reflect the real cause when
compared to the meaning of errno values.

src/util/virfile.c

index 5ff4668ea733588c107f4deba9544caf352548db..4b64225b534fa7879c7a452a67cd0b818eae25cd 100644 (file)
@@ -2397,12 +2397,12 @@ virDirCreate(const char *path,
 
     /* set desired uid/gid, then attempt to create the directory */
     if (virSetUIDGID(uid, gid, groups, ngroups) < 0) {
-        ret = -errno;
+        ret = errno;
         goto childerror;
     }
     if (mkdir(path, mode) < 0) {
-        ret = -errno;
-        if (ret != -EACCES) {
+        ret = errno;
+        if (ret != EACCES) {
             /* in case of EACCES, the parent will retry */
             virReportSystemError(errno, _("child failed to create directory '%s'"),
                                  path);
@@ -2412,13 +2412,13 @@ virDirCreate(const char *path,
     /* check if group was set properly by creating after
      * setgid. If not, try doing it with chown */
     if (stat(path, &st) == -1) {
-        ret = -errno;
+        ret = errno;
         virReportSystemError(errno,
                              _("stat of '%s' failed"), path);
         goto childerror;
     }
     if ((st.st_gid != gid) && (chown(path, (uid_t) -1, gid) < 0)) {
-        ret = -errno;
+        ret = errno;
         virReportSystemError(errno,
                              _("cannot chown '%s' to group %u"),
                              path, (unsigned int) gid);
@@ -2431,6 +2431,10 @@ virDirCreate(const char *path,
         goto childerror;
     }
  childerror:
+    if ((ret & 0xff) != ret) {
+        VIR_WARN("unable to pass desired return value %d", ret);
+        ret = 0xff;
+    }
     _exit(ret);
 }