Non-daemon actions indirect through generated code.
[libguestfs.git] / src / guestfs.c
index ad3980f..571205f 100644 (file)
@@ -19,7 +19,6 @@
 #include <config.h>
 
 #define _BSD_SOURCE /* for mkdtemp, usleep */
-#define _GNU_SOURCE /* for vasprintf, GNU strerror_r, strchrnul */
 
 #include <stdio.h>
 #include <stdlib.h>
 #endif
 
 #include "guestfs.h"
+#include "guestfs-internal-actions.h"
 #include "guestfs_protocol.h"
+#include "ignore-value.h"
 
 #ifdef HAVE_GETTEXT
 #include "gettext.h"
 #define _(str) dgettext(PACKAGE, (str))
-#define N_(str) dgettext(PACKAGE, (str))
+//#define N_(str) dgettext(PACKAGE, (str))
 #else
 #define _(str) str
-#define N_(str) str
+//#define N_(str) str
 #endif
 
 #define error guestfs_error
@@ -74,7 +75,7 @@
 #define safe_malloc guestfs_safe_malloc
 #define safe_realloc guestfs_safe_realloc
 #define safe_strdup guestfs_safe_strdup
-#define safe_memdup guestfs_safe_memdup
+//#define safe_memdup guestfs_safe_memdup
 
 static void default_error_cb (guestfs_h *g, void *data, const char *msg);
 static void stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int watch, int fd, int events);
@@ -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;
 };
@@ -347,6 +348,10 @@ guestfs_close (guestfs_h *g)
   g->fd[1] = -1;
   g->sock = -1;
 
+  /* Wait for subprocess(es) to exit. */
+  waitpid (g->pid, NULL, 0);
+  if (g->recoverypid > 0) waitpid (g->recoverypid, NULL, 0);
+
   /* Remove tmpfiles. */
   if (g->tmpdir) {
     snprintf (filename, sizeof filename, "%s/sock", g->tmpdir);
@@ -539,8 +544,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 +562,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) {
@@ -602,33 +609,33 @@ guestfs_get_error_handler (guestfs_h *g, void **data_rtn)
 }
 
 int
-guestfs_set_verbose (guestfs_h *g, int v)
+guestfs__set_verbose (guestfs_h *g, int v)
 {
   g->verbose = !!v;
   return 0;
 }
 
 int
-guestfs_get_verbose (guestfs_h *g)
+guestfs__get_verbose (guestfs_h *g)
 {
   return g->verbose;
 }
 
 int
-guestfs_set_autosync (guestfs_h *g, int a)
+guestfs__set_autosync (guestfs_h *g, int a)
 {
   g->autosync = !!a;
   return 0;
 }
 
 int
-guestfs_get_autosync (guestfs_h *g)
+guestfs__get_autosync (guestfs_h *g)
 {
   return g->autosync;
 }
 
 int
-guestfs_set_path (guestfs_h *g, const char *path)
+guestfs__set_path (guestfs_h *g, const char *path)
 {
   free (g->path);
   g->path = NULL;
@@ -640,13 +647,13 @@ guestfs_set_path (guestfs_h *g, const char *path)
 }
 
 const char *
-guestfs_get_path (guestfs_h *g)
+guestfs__get_path (guestfs_h *g)
 {
   return g->path;
 }
 
 int
-guestfs_set_qemu (guestfs_h *g, const char *qemu)
+guestfs__set_qemu (guestfs_h *g, const char *qemu)
 {
   free (g->qemu);
   g->qemu = NULL;
@@ -656,13 +663,13 @@ guestfs_set_qemu (guestfs_h *g, const char *qemu)
 }
 
 const char *
-guestfs_get_qemu (guestfs_h *g)
+guestfs__get_qemu (guestfs_h *g)
 {
   return g->qemu;
 }
 
 int
-guestfs_set_append (guestfs_h *g, const char *append)
+guestfs__set_append (guestfs_h *g, const char *append)
 {
   free (g->append);
   g->append = NULL;
@@ -672,39 +679,39 @@ guestfs_set_append (guestfs_h *g, const char *append)
 }
 
 const char *
-guestfs_get_append (guestfs_h *g)
+guestfs__get_append (guestfs_h *g)
 {
   return g->append;
 }
 
 int
-guestfs_set_memsize (guestfs_h *g, int memsize)
+guestfs__set_memsize (guestfs_h *g, int memsize)
 {
   g->memsize = memsize;
   return 0;
 }
 
 int
-guestfs_get_memsize (guestfs_h *g)
+guestfs__get_memsize (guestfs_h *g)
 {
   return g->memsize;
 }
 
 int
-guestfs_set_selinux (guestfs_h *g, int selinux)
+guestfs__set_selinux (guestfs_h *g, int selinux)
 {
   g->selinux = selinux;
   return 0;
 }
 
 int
-guestfs_get_selinux (guestfs_h *g)
+guestfs__get_selinux (guestfs_h *g)
 {
   return g->selinux;
 }
 
 int
-guestfs_get_pid (guestfs_h *g)
+guestfs__get_pid (guestfs_h *g)
 {
   if (g->pid > 0)
     return g->pid;
@@ -715,7 +722,7 @@ guestfs_get_pid (guestfs_h *g)
 }
 
 struct guestfs_version *
-guestfs_version (guestfs_h *g)
+guestfs__version (guestfs_h *g)
 {
   struct guestfs_version *r;
 
@@ -757,8 +764,8 @@ add_cmdline (guestfs_h *g, const char *str)
 }
 
 int
-guestfs_config (guestfs_h *g,
-                const char *qemu_param, const char *qemu_value)
+guestfs__config (guestfs_h *g,
+                 const char *qemu_param, const char *qemu_value)
 {
   if (qemu_param[0] != '-') {
     error (g, _("guestfs_config: parameter must begin with '-' character"));
@@ -789,7 +796,7 @@ guestfs_config (guestfs_h *g,
 }
 
 int
-guestfs_add_drive (guestfs_h *g, const char *filename)
+guestfs__add_drive (guestfs_h *g, const char *filename)
 {
   size_t len = strlen (filename) + 64;
   char buf[len];
@@ -828,7 +835,7 @@ guestfs_add_drive (guestfs_h *g, const char *filename)
 }
 
 int
-guestfs_add_drive_ro (guestfs_h *g, const char *filename)
+guestfs__add_drive_ro (guestfs_h *g, const char *filename)
 {
   size_t len = strlen (filename) + 64;
   char buf[len];
@@ -849,7 +856,7 @@ guestfs_add_drive_ro (guestfs_h *g, const char *filename)
 }
 
 int
-guestfs_add_cdrom (guestfs_h *g, const char *filename)
+guestfs__add_cdrom (guestfs_h *g, const char *filename)
 {
   if (strchr (filename, ',') != NULL) {
     error (g, _("filename cannot contain ',' (comma) character"));
@@ -908,7 +915,7 @@ static const char *supermin_hostfiles_name =
   "initramfs." REPO "." host_cpu ".supermin.hostfiles";
 
 int
-guestfs_launch (guestfs_h *g)
+guestfs__launch (guestfs_h *g)
 {
   const char *tmpdir;
   char dir_template[PATH_MAX];
@@ -1161,8 +1168,15 @@ guestfs_launch (guestfs_h *g)
     close (1);
     close (wfd[1]);
     close (rfd[0]);
-    dup (wfd[0]);
-    dup (rfd[1]);
+
+    if (dup (wfd[0]) == -1) {
+    dup_failed:
+      perror ("dup failed");
+      _exit (1);
+    }
+    if (dup (rfd[1]) == -1)
+      goto dup_failed;
+
     close (wfd[0]);
     close (rfd[1]);
 
@@ -1493,7 +1507,7 @@ finish_wait_ready (guestfs_h *g, void *vp)
 }
 
 int
-guestfs_wait_ready (guestfs_h *g)
+guestfs__wait_ready (guestfs_h *g)
 {
   int finished = 0, r;
 
@@ -1536,7 +1550,7 @@ guestfs_wait_ready (guestfs_h *g)
 }
 
 int
-guestfs_kill_subprocess (guestfs_h *g)
+guestfs__kill_subprocess (guestfs_h *g)
 {
   if (g->state == CONFIG) {
     error (g, _("no subprocess to kill"));
@@ -1554,37 +1568,37 @@ guestfs_kill_subprocess (guestfs_h *g)
 
 /* Access current state. */
 int
-guestfs_is_config (guestfs_h *g)
+guestfs__is_config (guestfs_h *g)
 {
   return g->state == CONFIG;
 }
 
 int
-guestfs_is_launching (guestfs_h *g)
+guestfs__is_launching (guestfs_h *g)
 {
   return g->state == LAUNCHING;
 }
 
 int
-guestfs_is_ready (guestfs_h *g)
+guestfs__is_ready (guestfs_h *g)
 {
   return g->state == READY;
 }
 
 int
-guestfs_is_busy (guestfs_h *g)
+guestfs__is_busy (guestfs_h *g)
 {
   return g->state == BUSY;
 }
 
 int
-guestfs_get_state (guestfs_h *g)
+guestfs__get_state (guestfs_h *g)
 {
   return g->state;
 }
 
 int
-guestfs_set_ready (guestfs_h *g)
+guestfs__set_ready (guestfs_h *g)
 {
   if (g->state != BUSY) {
     error (g, _("guestfs_set_ready: called when in state %d != BUSY"),
@@ -1596,7 +1610,7 @@ guestfs_set_ready (guestfs_h *g)
 }
 
 int
-guestfs_set_busy (guestfs_h *g)
+guestfs__set_busy (guestfs_h *g)
 {
   if (g->state != READY) {
     error (g, _("guestfs_set_busy: called when in state %d != READY"),
@@ -1608,7 +1622,7 @@ guestfs_set_busy (guestfs_h *g)
 }
 
 int
-guestfs_end_busy (guestfs_h *g)
+guestfs__end_busy (guestfs_h *g)
 {
   switch (g->state)
     {
@@ -1618,8 +1632,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;
     }
@@ -1697,7 +1713,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)
@@ -2398,7 +2414,7 @@ guestfs__receive_file_sync (guestfs_h *g, const char *filename)
     return -1;
   }
 
-  while ((r = receive_file_data_sync (g, NULL, NULL)) > 0)
+  while (receive_file_data_sync (g, NULL, NULL) > 0)
     ;                          /* just discard it */
 
   return -1;
@@ -2507,7 +2523,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;
@@ -2613,6 +2629,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)
 {
@@ -2622,6 +2639,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;