X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=daemon%2Fproto.c;h=4106d92187f31fab4b2d3d30a369ccdf1b58009d;hb=25081d62684eea9e704ecc0a0a15d2421b203356;hp=62871b5d3285780ce6d0dfcd2d8b91feb074635a;hpb=a7b73d4a1e09f12b2002083618056f0c823c1dcf;p=libguestfs.git diff --git a/daemon/proto.c b/daemon/proto.c index 62871b5..4106d92 100644 --- a/daemon/proto.c +++ b/daemon/proto.c @@ -24,11 +24,14 @@ #include #include #include -#include #include /* defines MIN */ +#include #include #include +#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,24 +56,24 @@ 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); if (len > GUESTFS_MESSAGE_MAX) { fprintf (stderr, "guestfsd: incoming message is too long (%u bytes)\n", - len); - exit (1); + len); + exit (EXIT_FAILURE); } buf = malloc (len); @@ -79,27 +82,28 @@ 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); - 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])) - printf ("%c", buf[j]); - else - printf ("."); - for (; j < i+16; ++j) - printf (" "); - printf ("|\n"); + 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 (c_isprint (buf[j])) + printf ("%c", buf[j]); + else + printf ("."); + for (; j < i+16; ++j) + printf (" "); + printf ("|\n"); } } #endif @@ -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. */ @@ -147,11 +151,11 @@ main_loop (int _sock) end_us = (int64_t) end_t.tv_sec * 1000000 + end_t.tv_usec; elapsed_us = end_us - start_us; fprintf (stderr, "proc %d (%s) took %d.%02d seconds\n", - proc_nr, - proc_nr >= 0 && proc_nr < GUESTFS_PROC_NR_PROCS - ? function_names[proc_nr] : "UNKNOWN PROCEDURE", - (int) (elapsed_us / 1000000), - (int) ((elapsed_us / 10000) % 100)); + proc_nr, + proc_nr >= 0 && proc_nr < GUESTFS_PROC_NR_PROCS + ? function_names[proc_nr] : "UNKNOWN PROCEDURE", + (int) (elapsed_us / 1000000), + (int) ((elapsed_us / 10000) % 100)); } cont: @@ -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,13 +266,18 @@ 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) { + /* This can fail if the reply body is too large, for example + * if it exceeds the maximum message size. In that case + * we want to return an error message instead. (RHBZ#509597). + */ if (!(*xdrp) (&xdr, ret)) { - fprintf (stderr, "guestfsd: failed to encode reply body\n"); - exit (1); + reply_with_perror ("guestfsd: failed to encode reply body\n"); + xdr_destroy (&xdr); + return; } } @@ -281,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); } } @@ -302,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); @@ -312,8 +323,8 @@ 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); + len); + exit (EXIT_FAILURE); } buf = malloc (len); @@ -322,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); @@ -336,7 +348,7 @@ receive_file (receive_cb cb, void *opaque) if (verbose) printf ("receive_file: got chunk: cancel = %d, len = %d, buf = %p\n", - chunk.cancel, chunk.data.data_len, chunk.data.data_val); + chunk.cancel, chunk.data.data_len, chunk.data.data_val); if (chunk.cancel) { fprintf (stderr, "receive_file: received cancellation from library\n"); @@ -392,7 +404,7 @@ send_file_write (const void *buf, int len) if (len > GUESTFS_MAX_CHUNK_SIZE) { fprintf (stderr, "send_file_write: len (%d) > GUESTFS_MAX_CHUNK_SIZE (%d)\n", - len, GUESTFS_MAX_CHUNK_SIZE); + len, GUESTFS_MAX_CHUNK_SIZE); return -1; } @@ -439,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); @@ -450,14 +460,14 @@ check_for_library_cancellation (void) if (flag != GUESTFS_CANCEL_FLAG) { fprintf (stderr, "check_for_library_cancellation: read 0x%x from library, expected 0x%x\n", - flag, GUESTFS_CANCEL_FLAG); + flag, GUESTFS_CANCEL_FLAG); return 0; } return 1; } -void +int send_file_end (int cancel) { guestfs_chunk chunk; @@ -465,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 @@ -490,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; }