daemon/Win32: Use gnulib modules for first porting to Win32.
[libguestfs.git] / daemon / proto.c
index 709f978..4106d92 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
-#include <ctype.h>
 #include <sys/param.h>         /* defines MIN */
+#include <sys/select.h>
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 
+#include "c-ctype.h"
+#include "ignore-value.h"
+
 #include "daemon.h"
 #include "../src/guestfs_protocol.h"
 
@@ -45,7 +48,7 @@ main_loop (int _sock)
   XDR xdr;
   char *buf;
   char lenbuf[4];
-  unsigned len;
+  uint32_t len;
   struct guestfs_message_header hdr;
   struct timeval start_t, end_t;
   int64_t start_us, end_us, elapsed_us;
@@ -53,16 +56,16 @@ main_loop (int _sock)
   sock = _sock;
 
   for (;;) {
-#if 0
     /* Most common errors are leaked memory and leaked file descriptors,
      * so run this between each command:
      */
-    if (verbose)
-      system ("ls -l /proc/self/fd");
-#endif
+    if (verbose && 0)
+      ignore_value (system ("ls -l /proc/self/fd"));
 
     /* Read the length word. */
-    xread (sock, lenbuf, 4);
+    if (xread (sock, lenbuf, 4) == -1)
+      exit (EXIT_FAILURE);
+
     xdrmem_create (&xdr, lenbuf, 4, XDR_DECODE);
     xdr_uint32_t (&xdr, &len);
     xdr_destroy (&xdr);
@@ -70,7 +73,7 @@ main_loop (int _sock)
     if (len > GUESTFS_MESSAGE_MAX) {
       fprintf (stderr, "guestfsd: incoming message is too long (%u bytes)\n",
                len);
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 
     buf = malloc (len);
@@ -79,21 +82,22 @@ main_loop (int _sock)
       continue;
     }
 
-    xread (sock, buf, len);
+    if (xread (sock, buf, len) == -1)
+      exit (EXIT_FAILURE);
 
-#if 0
+#ifdef ENABLE_PACKET_DUMP
     if (verbose) {
-      int i, j;
+      size_t i, j;
 
       for (i = 0; i < len; i += 16) {
-        printf ("%04x: ", i);
+        printf ("%04zx: ", i);
         for (j = i; j < MIN (i+16, len); ++j)
           printf ("%02x ", (unsigned char) buf[j]);
         for (; j < i+16; ++j)
           printf ("   ");
         printf ("|");
         for (j = i; j < MIN (i+16, len); ++j)
-          if (isprint (buf[j]))
+          if (c_isprint (buf[j]))
             printf ("%c", buf[j]);
           else
             printf (".");
@@ -112,7 +116,7 @@ main_loop (int _sock)
     xdrmem_create (&xdr, buf, len, XDR_DECODE);
     if (!xdr_guestfs_message_header (&xdr, &hdr)) {
       fprintf (stderr, "guestfsd: could not decode message header\n");
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 
     /* Check the version etc. */
@@ -215,14 +219,14 @@ send_error (const char *msg)
 
   if (!xdr_guestfs_message_header (&xdr, &hdr)) {
     fprintf (stderr, "guestfsd: failed to encode error message header\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
 
   err.error_message = (char *) msg;
 
   if (!xdr_guestfs_message_error (&xdr, &err)) {
     fprintf (stderr, "guestfsd: failed to encode error message body\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
 
   len = xdr_getpos (&xdr);
@@ -234,11 +238,11 @@ send_error (const char *msg)
 
   if (xwrite (sock, lenbuf, 4) == -1) {
     fprintf (stderr, "xwrite failed\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
   if (xwrite (sock, buf, len) == -1) {
     fprintf (stderr, "xwrite failed\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
 }
 
@@ -262,7 +266,7 @@ reply (xdrproc_t xdrp, char *ret)
 
   if (!xdr_guestfs_message_header (&xdr, &hdr)) {
     fprintf (stderr, "guestfsd: failed to encode reply header\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
 
   if (xdrp) {
@@ -286,11 +290,11 @@ reply (xdrproc_t xdrp, char *ret)
 
   if (xwrite (sock, lenbuf, 4) == -1) {
     fprintf (stderr, "xwrite failed\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
-  if (xwrite (sock, buf, len) == len) {
+  if (xwrite (sock, buf, len) == -1) {
     fprintf (stderr, "xwrite failed\n");
-    exit (1);
+    exit (EXIT_FAILURE);
   }
 }
 
@@ -307,7 +311,9 @@ receive_file (receive_cb cb, void *opaque)
 
   for (;;) {
     /* Read the length word. */
-    xread (sock, lenbuf, 4);
+    if (xread (sock, lenbuf, 4) == -1)
+      exit (EXIT_FAILURE);
+
     xdrmem_create (&xdr, lenbuf, 4, XDR_DECODE);
     xdr_uint32_t (&xdr, &len);
     xdr_destroy (&xdr);
@@ -318,7 +324,7 @@ receive_file (receive_cb cb, void *opaque)
     if (len > GUESTFS_MESSAGE_MAX) {
       fprintf (stderr, "guestfsd: incoming message is too long (%u bytes)\n",
                len);
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 
     buf = malloc (len);
@@ -327,7 +333,8 @@ receive_file (receive_cb cb, void *opaque)
       return -1;
     }
 
-    xread (sock, buf, len);
+    if (xread (sock, buf, len) == -1)
+      exit (EXIT_FAILURE);
 
     xdrmem_create (&xdr, buf, len, XDR_DECODE);
     memset (&chunk, 0, sizeof chunk);
@@ -444,10 +451,8 @@ check_for_library_cancellation (void)
 
   /* Read the message from the daemon. */
   r = xread (sock, buf, sizeof buf);
-  if (r == -1) {
-    perror ("read");
+  if (r == -1)
     return 0;
-  }
 
   xdrmem_create (&xdr, buf, sizeof buf, XDR_DECODE);
   xdr_uint32_t (&xdr, &flag);
@@ -462,7 +467,7 @@ check_for_library_cancellation (void)
   return 1;
 }
 
-void
+int
 send_file_end (int cancel)
 {
   guestfs_chunk chunk;
@@ -470,7 +475,7 @@ send_file_end (int cancel)
   chunk.cancel = cancel;
   chunk.data.data_len = 0;
   chunk.data.data_val = NULL;
-  send_chunk (&chunk);
+  return send_chunk (&chunk);
 }
 
 static int
@@ -495,8 +500,12 @@ send_chunk (const guestfs_chunk *chunk)
   xdr_uint32_t (&xdr, &len);
   xdr_destroy (&xdr);
 
-  (void) xwrite (sock, lenbuf, 4);
-  (void) xwrite (sock, buf, len);
+  int err = (xwrite (sock, lenbuf, 4) == 0
+             && xwrite (sock, buf, len) == 0 ? 0 : -1);
+  if (err) {
+    fprintf (stderr, "send_chunk: write failed\n");
+    exit (EXIT_FAILURE);
+  }
 
-  return 0;
+  return err;
 }