suppress warnings from -Wmissing-noreturn
[libguestfs.git] / src / guestfs.c
index 37869e8..0d54d65 100644 (file)
@@ -59,6 +59,7 @@
 
 #include "guestfs.h"
 #include "guestfs_protocol.h"
+#include "ignore-value.h"
 
 #ifdef HAVE_GETTEXT
 #include "gettext.h"
@@ -201,9 +202,9 @@ struct guestfs_h
 
   /* Messages sent and received from the daemon. */
   char *msg_in;
-  int msg_in_size, msg_in_allocated;
+  unsigned int msg_in_size, msg_in_allocated;
   char *msg_out;
-  int msg_out_size, msg_out_pos;
+  unsigned int msg_out_size, msg_out_pos;
 
   int msg_next_serial;
 };
@@ -539,8 +540,9 @@ guestfs_safe_memdup (guestfs_h *g, void *ptr, size_t size)
 }
 
 static int
-xwrite (int fd, const void *buf, size_t len)
+xwrite (int fd, const void *v_buf, size_t len)
 {
+  const char *buf = v_buf;
   int r;
 
   while (len > 0) {
@@ -556,8 +558,9 @@ xwrite (int fd, const void *buf, size_t len)
 }
 
 static int
-xread (int fd, void *buf, size_t len)
+xread (int fd, void *v_buf, size_t len)
 {
+  char *buf = v_buf;
   int r;
 
   while (len > 0) {
@@ -799,14 +802,31 @@ guestfs_add_drive (guestfs_h *g, const char *filename)
     return -1;
   }
 
-  if (access (filename, F_OK) == -1) {
-    perrorf (g, "%s", filename);
-    return -1;
+  /* cache=off improves reliability in the event of a host crash.
+   *
+   * However this option causes qemu to try to open the file with
+   * O_DIRECT.  This fails on some filesystem types (notably tmpfs).
+   * So we check if we can open the file with or without O_DIRECT,
+   * and use cache=off (or not) accordingly.
+   *
+   * This test also checks for the presence of the file, which
+   * is a documented semantic of this interface.
+   */
+  int fd = open (filename, O_RDONLY|O_DIRECT);
+  if (fd >= 0) {
+    close (fd);
+    snprintf (buf, len, "file=%s,cache=off,if=" DRIVE_IF, filename);
+  } else {
+    fd = open (filename, O_RDONLY);
+    if (fd >= 0) {
+      close (fd);
+      snprintf (buf, len, "file=%s,if=" DRIVE_IF, filename);
+    } else {
+      perrorf (g, "%s", filename);
+      return -1;
+    }
   }
 
-  /* cache=off improves reliability in the event of a host crash. */
-  snprintf (buf, len, "file=%s,cache=off,if=%s", filename, DRIVE_IF);
-
   return guestfs_config (g, "-drive", buf);
 }
 
@@ -1144,11 +1164,18 @@ guestfs_launch (guestfs_h *g)
     close (1);
     close (wfd[1]);
     close (rfd[0]);
-    dup (wfd[0]);
-    dup (rfd[1]);
+
+    int fail = 0;
+    fail |= dup (wfd[0]);
+    fail |= dup (rfd[1]);
     close (wfd[0]);
     close (rfd[1]);
 
+    if (fail) {
+      perror ("dup failed");
+      _exit (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).
@@ -1601,8 +1628,10 @@ guestfs_end_busy (guestfs_h *g)
     case CONFIG:
     case READY:
       break;
+
     case LAUNCHING:
     case NO_HANDLE:
+    default:
       error (g, _("guestfs_end_busy: called when in state %d"), g->state);
       return -1;
     }
@@ -1680,7 +1709,7 @@ stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data,
 
   /* In verbose mode, copy all log messages to stderr. */
   if (g->verbose)
-    write (2, buf, n);
+    ignore_value (write (STDERR_FILENO, buf, n));
 
   /* It's an actual log message, send it upwards if anyone is listening. */
   if (g->log_message_cb)
@@ -2490,7 +2519,7 @@ receive_file_data_sync (guestfs_h *g, void **buf, size_t *len_r)
 
     if (buf) {
       *buf = safe_realloc (g, *buf, len + ctx.chunks[i].data.data_len);
-      memcpy (*buf+len, ctx.chunks[i].data.data_val,
+      memcpy (((char *)*buf)+len, ctx.chunks[i].data.data_val,
               ctx.chunks[i].data.data_len);
     }
     len += ctx.chunks[i].data.data_len;
@@ -2596,6 +2625,7 @@ select_remove_handle (guestfs_main_loop *mlv, guestfs_h *g, int fd)
 }
 
 static int
+__attribute__((noreturn))
 select_add_timeout (guestfs_main_loop *mlv, guestfs_h *g, int interval,
                     guestfs_handle_timeout_cb cb, void *data)
 {
@@ -2605,6 +2635,7 @@ select_add_timeout (guestfs_main_loop *mlv, guestfs_h *g, int interval,
 }
 
 static int
+__attribute__((noreturn))
 select_remove_timeout (guestfs_main_loop *mlv, guestfs_h *g, int timer)
 {
   //struct select_main_loop *ml = (struct select_main_loop *) mlv;