X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Flaunch.c;h=e58add54362b7933ab28e023bff492462d8ceee0;hp=0b15ce98d79fac55032a7e93788f62d0011e8c34;hb=3cf31c2fe0b356ea5c04117c5235b0a3cfe34971;hpb=64841fe8957f798df12a38bd81843c7011f2c278 diff --git a/src/launch.c b/src/launch.c index 0b15ce9..e58add5 100644 --- a/src/launch.c +++ b/src/launch.c @@ -63,6 +63,7 @@ #include #include "c-ctype.h" +#include "ignore-value.h" #include "glthread/lock.h" #include "guestfs.h" @@ -75,6 +76,34 @@ static int64_t timeval_diff (const struct timeval *x, const struct timeval *y); static int connect_unix_socket (guestfs_h *g, const char *sock); static int qemu_supports (guestfs_h *g, const char *option); +#if 0 +static int qemu_supports_re (guestfs_h *g, const pcre *option_regex); + +static void compile_regexps (void) __attribute__((constructor)); +static void free_regexps (void) __attribute__((destructor)); + +static void +compile_regexps (void) +{ + const char *err; + int offset; + +#define COMPILE(re,pattern,options) \ + do { \ + re = pcre_compile ((pattern), (options), &err, &offset, NULL); \ + if (re == NULL) { \ + ignore_value (write (2, err, strlen (err))); \ + abort (); \ + } \ + } while (0) +} + +static void +free_regexps (void) +{ +} +#endif + /* Add a string to the current command line. */ static void incr_cmdline_size (guestfs_h *g) @@ -625,17 +654,27 @@ 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]); close (rfd[0]); + /* Stdin. */ if (dup (wfd[0]) == -1) { dup_failed: perror ("dup failed"); _exit (EXIT_FAILURE); } + /* Stdout. */ + 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; @@ -643,12 +682,9 @@ launch_appliance (guestfs_h *g) close (rfd[1]); } -#if 0 - /* Set up a new process group, so we can signal this process - * and all subprocesses (eg. if qemu is really a shell script). - */ - setpgid (0, 0); -#endif + /* Put qemu in a new process group. */ + if (g->pgroup) + setpgid (0, 0); setenv ("LC_ALL", "C", 1); @@ -677,8 +713,16 @@ launch_appliance (guestfs_h *g) pid_t qemu_pid = g->pid; pid_t parent_pid = getppid (); + /* It would be nice to be able to put this in the same process + * group as qemu (ie. setpgid (0, qemu_pid)). However this is + * not possible because we don't have any guarantee here that + * the qemu process has started yet. + */ + if (g->pgroup) + 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 @@ -1115,6 +1159,20 @@ qemu_supports (guestfs_h *g, const char *option) return strstr (g->qemu_help, option) != NULL; } +#if 0 +/* As above but using a regex instead of a fixed string. */ +static int +qemu_supports_re (guestfs_h *g, const pcre *option_regex) +{ + if (!g->qemu_help) { + if (test_qemu (g) == -1) + return -1; + } + + return match (g, g->qemu_help, option_regex); +} +#endif + /* Check if a file can be opened. */ static int is_openable (guestfs_h *g, const char *path, int flags)