daemon/Win32: Use gnulib pread module.
[libguestfs.git] / daemon / guestfsd.c
index bf06c73..eab8529 100644 (file)
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 #include <getopt.h>
-#include <netdb.h>
 #include <sys/param.h>
-#include <sys/select.h>
 #include <sys/types.h>
-#include <sys/wait.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <netdb.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_PRINTF_H
 #include <printf.h>
+#endif
 
 #include "c-ctype.h"
+#include "ignore-value.h"
+
 #include "daemon.h"
 
 static char *read_cmdline (void);
@@ -119,17 +124,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 ();
@@ -188,7 +193,7 @@ main (int argc, char *argv[])
       vmchannel = strndup (p + 18, len);
       if (!vmchannel) {
         perror ("strndup");
-        exit (1);
+        exit (EXIT_FAILURE);
       }
     }
 
@@ -202,7 +207,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 +219,7 @@ main (int argc, char *argv[])
     vmchannel = strdup ("tcp:" GUESTFWD_ADDR ":" GUESTFWD_PORT);
     if (!vmchannel) {
       perror ("strdup");
-      exit (1);
+      exit (EXIT_FAILURE);
     }
   }
 
@@ -224,7 +229,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 +244,7 @@ main (int argc, char *argv[])
     } else {
       fprintf (stderr, "vmchannel: expecting \"tcp:<ip>:<port>\": %s\n",
                vmchannel);
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 
     memset (&hints, 0, sizeof hints);
@@ -249,7 +254,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 +275,7 @@ main (int argc, char *argv[])
              "unknown vmchannel connection type: %s\n"
              "expecting \"tcp:<ip>:<port>\"\n",
              vmchannel);
-    exit (1);
+    exit (EXIT_FAILURE);
   }
 
   if (sock == -1) {
@@ -289,7 +294,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
@@ -302,7 +307,7 @@ main (int argc, char *argv[])
   xdr_uint32_t (&xdr, &len);
 
   if (xwrite (sock, lenbuf, sizeof lenbuf) == -1)
-    exit (1);
+    exit (EXIT_FAILURE);
 
   xdr_destroy (&xdr);
 
@@ -310,14 +315,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 +551,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 +608,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 +644,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 +748,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 +834,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 +948,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 +979,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:
+    ;
+  }
 }