[PATCH v2] virCommandExec: Report error if execve fails

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In an unlikely event of execve() failing, the virCommandExec()
function does not report any error, even though checks that are
at the beginning of the function are verbose when failing.

Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
---

diff to v1:
- Fixed the test (used virFork() instead of plain fork(),
                  prolonged the waiting time for child reply, ...)

 src/util/vircommand.c |  7 +++++-
 tests/commandtest.c   | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index f5bd7af..3c67c90 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -2152,7 +2152,12 @@ int virCommandExec(virCommandPtr cmd)
         return -1;
     }
 
-    return execve(cmd->args[0], cmd->args, cmd->env);
+    execve(cmd->args[0], cmd->args, cmd->env);
+
+    virReportSystemError(errno,
+                         _("cannot execute binary %s"),
+                         cmd->args[0]);
+    return -1;
 }
 #else
 int virCommandExec(virCommandPtr cmd ATTRIBUTE_UNUSED)
diff --git a/tests/commandtest.c b/tests/commandtest.c
index f433ad7..2b77b9b 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -1063,6 +1063,74 @@ static int test24(const void *unused ATTRIBUTE_UNUSED)
     return ret;
 }
 
+
+static int test25(const void *unused ATTRIBUTE_UNUSED)
+{
+    int ret = -1;
+    int pipeFD[2] = { -1, -1};
+    char rv = 0;
+    ssize_t tries = 100;
+    pid_t pid;
+
+    if (pipe(pipeFD) < 0) {
+        fprintf(stderr, "Unable to create pipe\n");
+        goto cleanup;
+    }
+
+    if (virSetNonBlock(pipeFD[0]) < 0) {
+        fprintf(stderr, "Unable to make read end of pipe nonblocking\n");
+        goto cleanup;
+    }
+
+    /* Now, fork and try to exec a nonexistent binary. */
+    pid = virFork();
+    if (pid < 0) {
+        fprintf(stderr, "Unable to spawn child\n");
+        goto cleanup;
+    }
+
+    if (pid == 0) {
+        /* Child */
+        virCommandPtr cmd = virCommandNew("some/nonexistent/binary");
+
+        rv = virCommandExec(cmd);
+        if (safewrite(pipeFD[1], &rv, sizeof(rv)) < 0)
+            fprintf(stderr, "Unable to write to pipe\n");
+        _exit(EXIT_FAILURE);
+    }
+
+    /* Parent */
+    while (--tries) {
+        if (saferead(pipeFD[0], &rv, sizeof(rv)) < 0) {
+            if (errno != EWOULDBLOCK) {
+                fprintf(stderr, "Unable to read from pipe\n");
+                goto cleanup;
+            }
+
+            usleep(10 * 1000);
+        } else {
+            break;
+        }
+    }
+
+    if (!tries) {
+        fprintf(stderr, "Child hasn't returned anything\n");
+        goto cleanup;
+    }
+
+    if (rv >= 0) {
+        fprintf(stderr, "Child should have returned an error\n");
+        goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    VIR_FORCE_CLOSE(pipeFD[0]);
+    VIR_FORCE_CLOSE(pipeFD[1]);
+    return ret;
+}
+
+
 static void virCommandThreadWorker(void *opaque)
 {
     virCommandTestDataPtr test = opaque;
@@ -1215,6 +1283,7 @@ mymain(void)
     DO_TEST(test22);
     DO_TEST(test23);
     DO_TEST(test24);
+    DO_TEST(test25);
 
     virMutexLock(&test->lock);
     if (test->running) {
-- 
2.8.4

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]