X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fguestfsd.c;h=acb44f9908d6c905677504ad5638bd2231197301;hp=bf06c73d1ffe4a160fa7e9f7c2949644f7266db8;hb=8e33cd5f2f2e7e30525cb2a70d86de70e3d6a4f9;hpb=d714547ab361962ca6f76ec07736f1515595b2df diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index bf06c73..acb44f9 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -20,6 +20,10 @@ #define _BSD_SOURCE /* for daemon(3) */ +#ifdef HAVE_WINDOWS_H +# include +#endif + #include #include #include @@ -27,17 +31,22 @@ #include #include #include -#include #include -#include #include -#include #include #include #include -#include +#include +#include +#include + +#ifdef HAVE_PRINTF_H +# include +#endif #include "c-ctype.h" +#include "ignore-value.h" + #include "daemon.h" static char *read_cmdline (void); @@ -46,6 +55,15 @@ static char *read_cmdline (void); #define GUESTFWD_ADDR "10.0.2.4" #define GUESTFWD_PORT "6666" +/* This is only a hint. If not defined, ignore it. */ +#ifndef AI_ADDRCONFIG +# define AI_ADDRCONFIG 0 +#endif + +#ifndef MAX +# define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + int verbose = 0; static int print_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args); @@ -60,6 +78,17 @@ static int print_arginfo (const struct printf_info *info, size_t n, int *argtype #endif #endif +#ifdef WIN32 +static int +daemon (int nochdir, int noclose) +{ + fprintf (stderr, + "On Windows the daemon does not support forking into the " + "background.\nYou *must* run the daemon with the -f option.\n"); + exit (EXIT_FAILURE); +} +#endif /* WIN32 */ + /* Location to mount root device. */ const char *sysroot = "/sysroot"; /* No trailing slash. */ int sysroot_len = 8; @@ -119,17 +148,17 @@ main (int argc, char *argv[]) case '?': usage (); - exit (0); + exit (EXIT_SUCCESS); default: fprintf (stderr, "guestfsd: unexpected command line option 0x%x\n", c); - exit (1); + exit (EXIT_FAILURE); } } if (optind < argc) { usage (); - exit (1); + exit (EXIT_FAILURE); } cmdline = read_cmdline (); @@ -147,6 +176,7 @@ main (int argc, char *argv[]) printf ("could not read linux command line\n"); } +#ifndef WIN32 /* Make sure SIGPIPE doesn't kill us. */ struct sigaction sa; memset (&sa, 0, sizeof sa); @@ -154,7 +184,11 @@ main (int argc, char *argv[]) sa.sa_flags = 0; if (sigaction (SIGPIPE, &sa, NULL) == -1) perror ("sigaction SIGPIPE"); /* but try to continue anyway ... */ +#endif +#ifdef WIN32 +# define setenv(n,v,f) _putenv(n "=" v) +#endif /* Set up a basic environment. After we are called by /init the * environment is essentially empty. * https://bugzilla.redhat.com/show_bug.cgi?id=502074#c5 @@ -163,8 +197,16 @@ main (int argc, char *argv[]) setenv ("SHELL", "/bin/sh", 1); setenv ("LC_ALL", "C", 1); +#ifndef WIN32 /* We document that umask defaults to 022 (it should be this anyway). */ umask (022); +#else + /* This is the default for Windows anyway. It's not even clear if + * Windows ever uses this -- the MSDN documentation for the function + * contains obvious errors. + */ + _umask (0); +#endif /* Get the vmchannel string. * @@ -188,7 +230,7 @@ main (int argc, char *argv[]) vmchannel = strndup (p + 18, len); if (!vmchannel) { perror ("strndup"); - exit (1); + exit (EXIT_FAILURE); } } @@ -202,7 +244,7 @@ main (int argc, char *argv[]) vmchannel = strndup (p + 4, len); if (!vmchannel) { perror ("strndup"); - exit (1); + exit (EXIT_FAILURE); } memcpy (vmchannel, "tcp:", 4); } @@ -214,7 +256,7 @@ main (int argc, char *argv[]) vmchannel = strdup ("tcp:" GUESTFWD_ADDR ":" GUESTFWD_PORT); if (!vmchannel) { perror ("strdup"); - exit (1); + exit (EXIT_FAILURE); } } @@ -224,7 +266,7 @@ main (int argc, char *argv[]) /* Connect to vmchannel. */ int sock = -1; - if (strncmp (vmchannel, "tcp:", 4) == 0) { + if (STREQLEN (vmchannel, "tcp:", 4)) { /* Resolve the hostname. */ struct addrinfo *res, *rr; struct addrinfo hints; @@ -239,7 +281,7 @@ main (int argc, char *argv[]) } else { fprintf (stderr, "vmchannel: expecting \"tcp::\": %s\n", vmchannel); - exit (1); + exit (EXIT_FAILURE); } memset (&hints, 0, sizeof hints); @@ -249,7 +291,7 @@ main (int argc, char *argv[]) if (r != 0) { fprintf (stderr, "%s:%s: %s\n", host, port, gai_strerror (r)); - exit (1); + exit (EXIT_FAILURE); } /* Connect to the given TCP socket. */ @@ -270,7 +312,7 @@ main (int argc, char *argv[]) "unknown vmchannel connection type: %s\n" "expecting \"tcp::\"\n", vmchannel); - exit (1); + exit (EXIT_FAILURE); } if (sock == -1) { @@ -289,7 +331,7 @@ main (int argc, char *argv[]) "or on the libguestfs redhat com mailing list.\n" "\n", vmchannel); - exit (1); + exit (EXIT_FAILURE); } /* Send the magic length message which indicates that @@ -299,10 +341,10 @@ main (int argc, char *argv[]) XDR xdr; uint32_t len = GUESTFS_LAUNCH_FLAG; xdrmem_create (&xdr, lenbuf, sizeof lenbuf, XDR_ENCODE); - xdr_uint32_t (&xdr, &len); + xdr_u_int (&xdr, &len); if (xwrite (sock, lenbuf, sizeof lenbuf) == -1) - exit (1); + exit (EXIT_FAILURE); xdr_destroy (&xdr); @@ -310,14 +352,14 @@ main (int argc, char *argv[]) if (!dont_fork) { if (daemon (0, 1) == -1) { perror ("daemon"); - exit (1); + exit (EXIT_FAILURE); } } /* Enter the main loop, reading and performing actions. */ main_loop (sock); - exit (0); + exit (EXIT_SUCCESS); } /* Read /proc/cmdline. */ @@ -546,7 +588,7 @@ commandf (char **stdoutput, char **stderror, int flags, const char *name, ...) va_end (args); - r = commandvf (stdoutput, stderror, flags, (char **) argv); + r = commandvf (stdoutput, stderror, flags, (const char * const*) argv); /* NB: Mustn't free the strings which are on the stack. */ free (argv); @@ -603,7 +645,8 @@ commandrf (char **stdoutput, char **stderror, int flags, const char *name, ...) /* Same as 'command', but passing an argv. */ int -commandvf (char **stdoutput, char **stderror, int flags, char *const *argv) +commandvf (char **stdoutput, char **stderror, int flags, + char const *const *argv) { int r; @@ -638,7 +681,7 @@ commandvf (char **stdoutput, char **stderror, int flags, char *const *argv) */ int commandrvf (char **stdoutput, char **stderror, int flags, - char const* const *argv) + char const* const *argv) { int so_size = 0, se_size = 0; int so_fd[2], se_fd[2]; @@ -742,15 +785,20 @@ commandrvf (char **stdoutput, char **stderror, int flags, } if (r == 0) { FD_CLR (se_fd[0], &rset); quit++; } - if (r > 0 && stderror) { - se_size += r; - p = realloc (*stderror, se_size); - if (p == NULL) { - perror ("realloc"); - goto quit; + if (r > 0) { + if (verbose) + ignore_value (write (2, buf, r)); + + if (stderror) { + se_size += r; + p = realloc (*stderror, se_size); + if (p == NULL) { + perror ("realloc"); + goto quit; + } + *stderror = p; + memcpy (*stderror + se_size - r, buf, r); } - *stderror = p; - memcpy (*stderror + se_size - r, buf, r); } } } @@ -823,7 +871,7 @@ split_lines (char *str) int size = 0, alloc = 0; char *p, *pend; - if (strcmp (str, "") == 0) + if (STREQ (str, "")) goto empty_list; p = str; @@ -937,7 +985,7 @@ device_name_translation (char *device, const char *func) } /* If the name begins with "/dev/sd" then try the alternatives. */ - if (strncmp (device, "/dev/sd", 7) != 0) + if (STRNEQLEN (device, "/dev/sd", 7)) goto error; device[5] = 'h'; /* /dev/hd (old IDE driver) */ @@ -968,5 +1016,25 @@ device_name_translation (char *device, const char *func) void udev_settle (void) { - command (NULL, NULL, "/sbin/udevadm", "settle", NULL); + static int which_prog = 0; + + if (which_prog == 0) { + if (access ("/sbin/udevsettle", X_OK) == 0) + which_prog = 2; + else if (access ("/sbin/udevadm", X_OK) == 0) + which_prog = 1; + else + which_prog = 3; + } + + switch (which_prog) { + case 1: + command (NULL, NULL, "/sbin/udevadm", "settle", NULL); + break; + case 2: + command (NULL, NULL, "/sbin/udevsettle", NULL); + break; + default: + ; + } }