X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Flaunch.c;h=310a88dd7b2f03b4be76c853b870badfe9b44785;hb=7e484865894b98de7a976a688c19e64bdd13dade;hp=a4dc98f1e5d3b0cafab3d99c828758c214f58faf;hpb=1700f8fc7482bd73efd37709d301d76f610720fb;p=libguestfs.git diff --git a/src/launch.c b/src/launch.c index a4dc98f..310a88d 100644 --- a/src/launch.c +++ b/src/launch.c @@ -64,6 +64,7 @@ #include "c-ctype.h" #include "glthread/lock.h" +#include "ignore-value.h" #include "guestfs.h" #include "guestfs-internal.h" @@ -625,7 +626,7 @@ launch_appliance (guestfs_h *g) guestfs___print_timestamped_argv (g, (const char **)g->cmdline); if (!g->direct) { - /* Set up stdin, stdout. */ + /* Set up stdin, stdout, stderr. */ close (0); close (1); close (wfd[1]); @@ -641,6 +642,14 @@ launch_appliance (guestfs_h *g) if (dup (rfd[1]) == -1) goto dup_failed; + /* Particularly since qemu 0.15, qemu spews all sorts of debug + * information on stderr. It is useful to both capture this and + * not confuse casual users, so send stderr to the pipe as well. + */ + close (2); + if (dup (rfd[1]) == -1) + goto dup_failed; + close (wfd[0]); close (rfd[1]); } @@ -680,7 +689,7 @@ launch_appliance (guestfs_h *g) pid_t parent_pid = getppid (); /* Writing to argv is hideously complicated and error prone. See: - * http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/misc/ps_status.c?rev=1.33.2.1;content-type=text%2Fplain + * http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/misc/ps_status.c;hb=HEAD */ /* Loop around waiting for one or both of the other processes to @@ -1022,6 +1031,7 @@ guestfs___print_timestamped_message (guestfs_h *g, const char *fs, ...) free (msg); } +static int test_qemu_cmd (guestfs_h *g, const char *cmd, char **ret); static int read_all (guestfs_h *g, FILE *fp, char **ret); /* Test qemu binary (or wrapper) runs, and do 'qemu -help' and @@ -1034,38 +1044,48 @@ test_qemu (guestfs_h *g) char cmd[1024]; FILE *fp; + free (g->qemu_help); + g->qemu_help = NULL; + free (g->qemu_version); + g->qemu_version = NULL; + snprintf (cmd, sizeof cmd, "LC_ALL=C '%s' -nographic -help", g->qemu); - fp = popen (cmd, "r"); /* qemu -help should always work (qemu -version OTOH wasn't * supported by qemu 0.9). If this command doesn't work then it * probably indicates that the qemu binary is missing. */ - if (!fp) { - /* XXX This error is never printed, even if the qemu binary - * doesn't exist. Why? - */ - error: + if (test_qemu_cmd (g, cmd, &g->qemu_help) == -1) { perrorf (g, _("%s: command failed: If qemu is located on a non-standard path, try setting the LIBGUESTFS_QEMU environment variable."), cmd); return -1; } - if (read_all (g, fp, &g->qemu_help) == -1) - goto error; - - if (pclose (fp) == -1) - goto error; - snprintf (cmd, sizeof cmd, "LC_ALL=C '%s' -nographic -version 2>/dev/null", g->qemu); + /* Intentionally ignore errors from qemu -version. */ + ignore_value (test_qemu_cmd (g, cmd, &g->qemu_version)); + + return 0; +} + +static int +test_qemu_cmd (guestfs_h *g, const char *cmd, char **ret) +{ + FILE *fp; + fp = popen (cmd, "r"); - if (fp) { - /* Intentionally ignore errors. */ - read_all (g, fp, &g->qemu_version); + if (fp == NULL) + return -1; + + if (read_all (g, fp, ret) == -1) { pclose (fp); + return -1; } + if (pclose (fp) != 0) + return -1; + return 0; }