X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Flaunch.c;h=234f42e40f9398f771dec93bb6af1028b41eaba4;hp=56aa288b16665c6901c77c9960fef14e4a14cd39;hb=635af5be04265f845186b40e9a9fe7b102ad6909;hpb=5d7dc0dfb65f367dab3560ee23e404fe21373f45;ds=sidebyside diff --git a/src/launch.c b/src/launch.c index 56aa288..234f42e 100644 --- a/src/launch.c +++ b/src/launch.c @@ -73,6 +73,7 @@ static int launch_appliance (guestfs_h *g); static int64_t timeval_diff (const struct timeval *x, const struct timeval *y); +static void print_qemu_command_line (guestfs_h *g, char **argv); static int connect_unix_socket (guestfs_h *g, const char *sock); static int qemu_supports (guestfs_h *g, const char *option); @@ -650,9 +651,6 @@ launch_appliance (guestfs_h *g) incr_cmdline_size (g); g->cmdline[g->cmdline_size-1] = NULL; - if (g->verbose) - guestfs___print_timestamped_argv (g, (const char **)g->cmdline); - if (!g->direct) { /* Set up stdin, stdout, stderr. */ close (0); @@ -682,6 +680,10 @@ launch_appliance (guestfs_h *g) close (rfd[1]); } + /* Dump the command line (after setting up stderr above). */ + if (g->verbose) + print_qemu_command_line (g, g->cmdline); + /* Put qemu in a new process group. */ if (g->pgroup) setpgid (0, 0); @@ -722,7 +724,7 @@ launch_appliance (guestfs_h *g) setpgid (0, 0); /* 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 @@ -1002,47 +1004,9 @@ timeval_diff (const struct timeval *x, const struct timeval *y) return msec; } -void -guestfs___print_timestamped_argv (guestfs_h *g, const char * argv[]) -{ - int i = 0; - int needs_quote; - char *buf = NULL; - size_t len; - FILE *fp; - - fp = open_memstream (&buf, &len); - if (fp == NULL) { - warning (g, "open_memstream: %m"); - return; - } - - struct timeval tv; - gettimeofday (&tv, NULL); - fprintf (fp, "[%05" PRIi64 "ms] ", timeval_diff (&g->launch_t, &tv)); - - while (argv[i]) { - if (argv[i][0] == '-') /* -option starts a new line */ - fprintf (fp, " \\\n "); - - if (i > 0) fputc (' ', fp); - - /* Does it need shell quoting? This only deals with simple cases. */ - needs_quote = strcspn (argv[i], " ") != strlen (argv[i]); - - if (needs_quote) fputc ('\'', fp); - fprintf (fp, "%s", argv[i]); - if (needs_quote) fputc ('\'', fp); - i++; - } - - fclose (fp); - - debug (g, "%s", buf); - - free (buf); -} - +/* Note that since this calls 'debug' it should only be called + * from the parent process. + */ void guestfs___print_timestamped_message (guestfs_h *g, const char *fs, ...) { @@ -1064,6 +1028,36 @@ guestfs___print_timestamped_message (guestfs_h *g, const char *fs, ...) free (msg); } +/* This is called from the forked subprocess just before qemu runs, so + * it can just print the message straight to stderr, where it will be + * picked up and funnelled through the usual appliance event API. + */ +static void +print_qemu_command_line (guestfs_h *g, char **argv) +{ + int i = 0; + int needs_quote; + + struct timeval tv; + gettimeofday (&tv, NULL); + fprintf (stderr, "[%05" PRIi64 "ms] ", timeval_diff (&g->launch_t, &tv)); + + while (argv[i]) { + if (argv[i][0] == '-') /* -option starts a new line */ + fprintf (stderr, " \\\n "); + + if (i > 0) fputc (' ', stderr); + + /* Does it need shell quoting? This only deals with simple cases. */ + needs_quote = strcspn (argv[i], " ") != strlen (argv[i]); + + if (needs_quote) fputc ('\'', stderr); + fprintf (stderr, "%s", argv[i]); + if (needs_quote) fputc ('\'', stderr); + i++; + } +} + static int read_all (guestfs_h *g, FILE *fp, char **ret); /* Test qemu binary (or wrapper) runs, and do 'qemu -help' and