[Libguestfs] [PATCH 04/10] launch: appliance: Use command mini-library to parse output of qemu -help etc.

Richard W.M. Jones rjones at redhat.com
Thu Oct 18 21:14:05 UTC 2012


From: "Richard W.M. Jones" <rjones at redhat.com>

---
 src/launch-appliance.c | 112 +++++++++++++++++++++----------------------------
 1 file changed, 48 insertions(+), 64 deletions(-)

diff --git a/src/launch-appliance.c b/src/launch-appliance.c
index 378f121..17e90d9 100644
--- a/src/launch-appliance.c
+++ b/src/launch-appliance.c
@@ -729,8 +729,7 @@ print_qemu_command_line (guestfs_h *g, char **argv)
   }
 }
 
-static int test_qemu_cmd (guestfs_h *g, const char *cmd, char **ret);
-static int read_all (guestfs_h *g, FILE *fp, char **ret);
+static void read_all (guestfs_h *g, void *retv, const char *buf, size_t len);
 
 /* Test qemu binary (or wrapper) runs, and do 'qemu -help' and
  * 'qemu -version' so we know what options this qemu supports and
@@ -739,7 +738,8 @@ static int read_all (guestfs_h *g, FILE *fp, char **ret);
 static int
 test_qemu (guestfs_h *g)
 {
-  char cmd[1024];
+  struct command *cmd;
+  int r;
 
   free (g->app.qemu_help);
   g->app.qemu_help = NULL;
@@ -748,74 +748,58 @@ test_qemu (guestfs_h *g)
   free (g->app.qemu_devices);
   g->app.qemu_devices = NULL;
 
-  snprintf (cmd, sizeof cmd, "LC_ALL=C '%s' -nographic -help", g->qemu);
-
-  /* If this command doesn't work then it probably indicates that the
-   * qemu binary is missing.
-   */
-  if (test_qemu_cmd (g, cmd, &g->app.qemu_help) == -1) {
-  qemu_error:
-    error (g, _("command failed: %s\nerrno: %s\n\nIf qemu is located on a non-standard path, try setting the LIBGUESTFS_QEMU\nenvironment variable.  There may also be errors printed above."),
-           cmd, strerror (errno));
-    return -1;
-  }
-
-  snprintf (cmd, sizeof cmd, "LC_ALL=C '%s' -nographic -version 2>/dev/null",
-            g->qemu);
-
-  if (test_qemu_cmd (g, cmd, &g->app.qemu_version) == -1)
-    goto qemu_error;
-
-  snprintf (cmd, sizeof cmd,
-            "LC_ALL=C '%s' -nographic -machine accel=kvm:tcg -device '?' 2>&1",
-            g->qemu);
-
-  if (test_qemu_cmd (g, cmd, &g->app.qemu_devices) == -1)
-    goto qemu_error;
+  cmd = guestfs___new_command (g);
+  guestfs___cmd_add_arg (cmd, g->qemu);
+  guestfs___cmd_add_arg (cmd, "-nographic");
+  guestfs___cmd_add_arg (cmd, "-help");
+  guestfs___cmd_set_stdout_callback (cmd, read_all, &g->app.qemu_help,
+                                     CMD_STDOUT_FLAG_WHOLE_BUFFER);
+  r = guestfs___cmd_run (cmd);
+  if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
+    goto error;
+  guestfs___cmd_close (cmd);
+
+  cmd = guestfs___new_command (g);
+  guestfs___cmd_add_arg (cmd, g->qemu);
+  guestfs___cmd_add_arg (cmd, "-nographic");
+  guestfs___cmd_add_arg (cmd, "-version");
+  guestfs___cmd_set_stdout_callback (cmd, read_all, &g->app.qemu_version,
+                                     CMD_STDOUT_FLAG_WHOLE_BUFFER);
+  r = guestfs___cmd_run (cmd);
+  if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
+    goto error;
+  guestfs___cmd_close (cmd);
+
+  cmd = guestfs___new_command (g);
+  guestfs___cmd_add_arg (cmd, g->qemu);
+  guestfs___cmd_add_arg (cmd, "-nographic");
+  guestfs___cmd_add_arg (cmd, "-machine");
+  guestfs___cmd_add_arg (cmd, "accel=kvm:tcg");
+  guestfs___cmd_add_arg (cmd, "-device");
+  guestfs___cmd_add_arg (cmd, "?");
+  guestfs___cmd_clear_capture_errors (cmd);
+  guestfs___cmd_set_stderr_to_stdout (cmd);
+  guestfs___cmd_set_stdout_callback (cmd, read_all, &g->app.qemu_devices,
+                                     CMD_STDOUT_FLAG_WHOLE_BUFFER);
+  r = guestfs___cmd_run (cmd);
+  if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
+    goto error;
+  guestfs___cmd_close (cmd);
 
   return 0;
-}
-
-static int
-test_qemu_cmd (guestfs_h *g, const char *cmd, char **ret)
-{
-  FILE *fp;
 
-  fp = popen (cmd, "r");
-  if (fp == NULL)
-    return -1;
-
-  if (read_all (g, fp, ret) == -1) {
-    pclose (fp);
-    return -1;
-  }
-
-  if (pclose (fp) != 0)
-    return -1;
-
-  return 0;
+ error:
+  error (g, _("qemu command failed\nIf qemu is located on a non-standard path, try setting the LIBGUESTFS_QEMU\nenvironment variable.  There may also be errors printed above."));
+  guestfs___cmd_close (cmd);
+  return -1;
 }
 
-static int
-read_all (guestfs_h *g, FILE *fp, char **ret)
+static void
+read_all (guestfs_h *g, void *retv, const char *buf, size_t len)
 {
-  int r, n = 0;
-  char *p;
-
- again:
-  if (feof (fp)) {
-    *ret = safe_realloc (g, *ret, n + 1);
-    (*ret)[n] = '\0';
-    return n;
-  }
+  char **ret = retv;
 
-  *ret = safe_realloc (g, *ret, n + BUFSIZ);
-  p = &(*ret)[n];
-  r = fread (p, 1, BUFSIZ, fp);
-  if (ferror (fp))
-    return -1;
-  n += r;
-  goto again;
+  *ret = safe_memdup (g, buf, len);
 }
 
 /* Test if option is supported by qemu command line (just by grepping
-- 
1.7.11.4




More information about the Libguestfs mailing list