[Libguestfs] [PATCH 55/67] lib: Use stringsbuf at various places in the library to simplify the code.

Richard W.M. Jones rjones at redhat.com
Sat Aug 24 11:04:55 UTC 2013


From: "Richard W.M. Jones" <rjones at redhat.com>

This is just code refactoring.

(cherry picked from commit d2ae632d3bc0a4fcdbf4150a33406d7646f8cdf9)
---
 src/command.c      | 38 ++++++++-------------------
 src/drives.c       | 18 ++++---------
 src/inspect.c      | 59 +++++++++++------------------------------
 src/libvirt-auth.c | 14 +++++-----
 src/listfs.c       | 77 ++++++++++++++++++------------------------------------
 5 files changed, 63 insertions(+), 143 deletions(-)

diff --git a/src/command.c b/src/command.c
index 7c0da6e..02e5801 100644
--- a/src/command.c
+++ b/src/command.c
@@ -108,10 +108,7 @@ struct command
   enum command_style style;
   union {
     /* COMMAND_STYLE_EXECV */
-    struct {
-      char **args;
-      size_t len, alloc;
-    } argv;
+    struct stringsbuf argv;
     /* COMMAND_STYLE_SYSTEM */
     struct {
       char *str;
@@ -161,16 +158,7 @@ add_arg_no_strdup (struct command *cmd, char *arg)
   assert (cmd->style != COMMAND_STYLE_SYSTEM);
   cmd->style = COMMAND_STYLE_EXECV;
 
-  if (cmd->argv.len >= cmd->argv.alloc) {
-    if (cmd->argv.alloc == 0)
-      cmd->argv.alloc = 16;
-    else
-      cmd->argv.alloc *= 2;
-    cmd->argv.args = safe_realloc (cmd->g, cmd->argv.args,
-                                   cmd->argv.alloc * sizeof (char *));
-  }
-  cmd->argv.args[cmd->argv.len] = arg;
-  cmd->argv.len++;
+  guestfs___add_string_nodup (cmd->g, &cmd->argv, arg);
 }
 
 static void
@@ -328,7 +316,7 @@ finish_command (struct command *cmd)
 {
   switch (cmd->style) {
   case COMMAND_STYLE_EXECV:
-    add_arg_no_strdup (cmd, NULL);
+    guestfs___end_stringsbuf (cmd->g, &cmd->argv);
     break;
 
   case COMMAND_STYLE_SYSTEM:
@@ -347,17 +335,17 @@ debug_command (struct command *cmd)
 
   switch (cmd->style) {
   case COMMAND_STYLE_EXECV:
-    debug (cmd->g, "command: run: %s", cmd->argv.args[0]);
-    last = cmd->argv.len-1;     /* omit final NULL pointer */
+    debug (cmd->g, "command: run: %s", cmd->argv.argv[0]);
+    last = cmd->argv.size-1;     /* omit final NULL pointer */
     for (i = 1; i < last; ++i) {
       if (i < last-1 &&
-          cmd->argv.args[i][0] == '-' && cmd->argv.args[i+1][0] != '-') {
+          cmd->argv.argv[i][0] == '-' && cmd->argv.argv[i+1][0] != '-') {
         debug (cmd->g, "command: run: \\ %s %s",
-               cmd->argv.args[i], cmd->argv.args[i+1]);
+               cmd->argv.argv[i], cmd->argv.argv[i+1]);
         i++;
       }
       else
-        debug (cmd->g, "command: run: \\ %s", cmd->argv.args[i]);
+        debug (cmd->g, "command: run: \\ %s", cmd->argv.argv[i]);
     }
     break;
 
@@ -472,8 +460,8 @@ run_command (struct command *cmd)
   /* Run the command. */
   switch (cmd->style) {
   case COMMAND_STYLE_EXECV:
-    execvp (cmd->argv.args[0], cmd->argv.args);
-    perror (cmd->argv.args[0]);
+    execvp (cmd->argv.argv[0], cmd->argv.argv);
+    perror (cmd->argv.argv[0]);
     _exit (EXIT_FAILURE);
 
   case COMMAND_STYLE_SYSTEM:
@@ -638,8 +626,6 @@ guestfs___cmd_run (struct command *cmd)
 void
 guestfs___cmd_close (struct command *cmd)
 {
-  size_t i;
-
   if (!cmd)
     return;
 
@@ -649,9 +635,7 @@ guestfs___cmd_close (struct command *cmd)
     break;
 
   case COMMAND_STYLE_EXECV:
-    for (i = 0; i < cmd->argv.len; ++i)
-      free (cmd->argv.args[i]);
-    free (cmd->argv.args);
+    guestfs___free_stringsbuf (&cmd->argv);
     break;
 
   case COMMAND_STYLE_SYSTEM:
diff --git a/src/drives.c b/src/drives.c
index cb2360a..df6f7e0 100644
--- a/src/drives.c
+++ b/src/drives.c
@@ -1167,25 +1167,17 @@ guestfs___rollback_drives (guestfs_h *g, size_t old_i)
 char **
 guestfs__debug_drives (guestfs_h *g)
 {
-  size_t i, count;
-  char **ret;
+  size_t i;
+  DECLARE_STRINGSBUF (ret);
   struct drive *drv;
 
-  count = 0;
   ITER_DRIVES (g, i, drv) {
-    count++;
+    guestfs___add_string_nodup (g, &ret, drive_to_string (g, drv));
   }
 
-  ret = safe_malloc (g, sizeof (char *) * (count + 1));
+  guestfs___end_stringsbuf (g, &ret);
 
-  count = 0;
-  ITER_DRIVES (g, i, drv) {
-    ret[count++] = drive_to_string (g, drv);
-  }
-
-  ret[count] = NULL;
-
-  return ret;                   /* caller frees */
+  return ret.argv;              /* caller frees */
 }
 
 /* The drive_source struct is also used in the backends, so we
diff --git a/src/inspect.c b/src/inspect.c
index 6c8dcda..46bb4ab 100644
--- a/src/inspect.c
+++ b/src/inspect.c
@@ -84,34 +84,21 @@ compare_strings (const void *vp1, const void *vp2)
 char **
 guestfs__inspect_get_roots (guestfs_h *g)
 {
+  size_t i;
+  DECLARE_STRINGSBUF (ret);
+
   /* NB. Doesn't matter if g->nr_fses == 0.  We just return an empty
    * list in this case.
    */
-
-  size_t i;
-  size_t count = 0;
-  for (i = 0; i < g->nr_fses; ++i)
+  for (i = 0; i < g->nr_fses; ++i) {
     if (g->fses[i].is_root)
-      count++;
-
-  char **ret = calloc (count+1, sizeof (char *));
-  if (ret == NULL) {
-    perrorf (g, "calloc");
-    return NULL;
-  }
-
-  count = 0;
-  for (i = 0; i < g->nr_fses; ++i) {
-    if (g->fses[i].is_root) {
-      ret[count] = safe_strdup (g, g->fses[i].mountable);
-      count++;
-    }
+      guestfs___add_string (g, &ret, g->fses[i].mountable);
   }
-  ret[count] = NULL;
+  guestfs___end_stringsbuf (g, &ret);
 
-  qsort (ret, count, sizeof (char *), compare_strings);
+  qsort (ret.argv, ret.size-1, sizeof (char *), compare_strings);
 
-  return ret;
+  return ret.argv;
 }
 
 char *
@@ -392,37 +379,21 @@ guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
 char **
 guestfs__inspect_get_drive_mappings (guestfs_h *g, const char *root)
 {
-  char **ret;
-  size_t i, count;
+  DECLARE_STRINGSBUF (ret);
+  size_t i;
   struct inspect_fs *fs;
 
   fs = guestfs___search_for_root (g, root);
   if (!fs)
     return NULL;
 
-  /* If no drive mappings, return an empty hashtable. */
-  if (!fs->drive_mappings)
-    count = 0;
-  else {
-    for (count = 0; fs->drive_mappings[count] != NULL; count++)
-      ;
+  if (fs->drive_mappings) {
+    for (i = 0; fs->drive_mappings[i] != NULL; ++i)
+      guestfs___add_string (g, &ret, fs->drive_mappings[i]);
   }
 
-  ret = calloc (count+1, sizeof (char *));
-  if (ret == NULL) {
-    perrorf (g, "calloc");
-    return NULL;
-  }
-
-  /* We need to make a deep copy of the hashtable since the caller
-   * will free it.
-   */
-  for (i = 0; i < count; ++i)
-    ret[i] = safe_strdup (g, fs->drive_mappings[i]);
-
-  ret[count] = NULL;
-
-  return ret;
+  guestfs___end_stringsbuf (g, &ret);
+  return ret.argv;
 }
 
 char *
diff --git a/src/libvirt-auth.c b/src/libvirt-auth.c
index cd90378..fb18f8a 100644
--- a/src/libvirt-auth.c
+++ b/src/libvirt-auth.c
@@ -215,20 +215,18 @@ guestfs___open_libvirt_connection (guestfs_h *g, const char *uri,
 char **
 guestfs__get_libvirt_requested_credentials (guestfs_h *g)
 {
-  char **ret;
+  DECLARE_STRINGSBUF (ret);
   size_t i;
 
   CHECK_IN_EVENT_HANDLER (NULL);
 
   /* Convert the requested_credentials types to a list of strings. */
-  ret = safe_malloc (g, sizeof (char *) * (g->nr_requested_credentials+1));
-  for (i = 0; i < g->nr_requested_credentials; ++i) {
-    ret[i] = safe_strdup (g,
-      get_string_of_credtype (g->requested_credentials[i].type));
-  }
-  ret[i] = NULL;
+  for (i = 0; i < g->nr_requested_credentials; ++i)
+    guestfs___add_string (g, &ret,
+                          get_string_of_credtype (g->requested_credentials[i].type));
+  guestfs___end_stringsbuf (g, &ret);
 
-  return ret;                   /* caller frees */
+  return ret.argv;              /* caller frees */
 }
 
 char *
diff --git a/src/listfs.c b/src/listfs.c
index bd3ee71..9102c55 100644
--- a/src/listfs.c
+++ b/src/listfs.c
@@ -39,15 +39,14 @@
  */
 
 static void remove_from_list (char **list, const char *item);
-static void check_with_vfs_type (guestfs_h *g, const char *dev, char ***ret, size_t *ret_size);
+static void check_with_vfs_type (guestfs_h *g, const char *dev, struct stringsbuf *sb);
 static int is_mbr_partition_type_42 (guestfs_h *g, const char *partition);
 
 char **
 guestfs__list_filesystems (guestfs_h *g)
 {
   size_t i;
-  char **ret;
-  size_t ret_size = 0;
+  DECLARE_STRINGSBUF (ret);
   const char *lvm2[] = { "lvm2", NULL };
   const char *ldm[] = { "ldm", NULL };
 
@@ -58,13 +57,6 @@ guestfs__list_filesystems (guestfs_h *g)
   CLEANUP_FREE_STRING_LIST char **ldmvols = NULL;
   CLEANUP_FREE_STRING_LIST char **ldmparts = NULL;
 
-  /* We need to initialize this with an empty list so that if there
-   * are no filesystems at all, we return an empty list (not NULL).
-   * See also add_vfs function below.
-   */
-  ret = safe_malloc (g, sizeof (char *));
-  ret[0] = NULL;
-
   /* Look to see if any devices directly contain filesystems
    * (RHBZ#590167).  However vfs-type will fail to tell us anything
    * useful about devices which just contain partitions, so we also
@@ -86,17 +78,17 @@ guestfs__list_filesystems (guestfs_h *g)
 
   /* Use vfs-type to check for filesystems on devices. */
   for (i = 0; devices[i] != NULL; ++i)
-    check_with_vfs_type (g, devices[i], &ret, &ret_size);
+    check_with_vfs_type (g, devices[i], &ret);
 
   /* Use vfs-type to check for filesystems on partitions. */
   for (i = 0; partitions[i] != NULL; ++i) {
     if (! is_mbr_partition_type_42 (g, partitions[i]))
-      check_with_vfs_type (g, partitions[i], &ret, &ret_size);
+      check_with_vfs_type (g, partitions[i], &ret);
   }
 
   /* Use vfs-type to check for filesystems on md devices. */
   for (i = 0; mds[i] != NULL; ++i)
-    check_with_vfs_type (g, mds[i], &ret, &ret_size);
+    check_with_vfs_type (g, mds[i], &ret);
 
   if (guestfs_feature_available (g, (char **) lvm2)) {
     /* Use vfs-type to check for filesystems on LVs. */
@@ -104,7 +96,7 @@ guestfs__list_filesystems (guestfs_h *g)
     if (lvs == NULL) goto error;
 
     for (i = 0; lvs[i] != NULL; ++i)
-      check_with_vfs_type (g, lvs[i], &ret, &ret_size);
+      check_with_vfs_type (g, lvs[i], &ret);
   }
 
   if (guestfs_feature_available (g, (char **) ldm)) {
@@ -113,19 +105,21 @@ guestfs__list_filesystems (guestfs_h *g)
     if (ldmvols == NULL) goto error;
 
     for (i = 0; ldmvols[i] != NULL; ++i)
-      check_with_vfs_type (g, ldmvols[i], &ret, &ret_size);
+      check_with_vfs_type (g, ldmvols[i], &ret);
 
     ldmparts = guestfs_list_ldm_partitions (g);
     if (ldmparts == NULL) goto error;
 
     for (i = 0; ldmparts[i] != NULL; ++i)
-      check_with_vfs_type (g, ldmparts[i], &ret, &ret_size);
+      check_with_vfs_type (g, ldmparts[i], &ret);
   }
 
-  return ret;
+  /* Finish off the list and return it. */
+  guestfs___end_stringsbuf (g, &ret);
+  return ret.argv;
 
  error:
-  if (ret) guestfs___free_string_list (ret);
+  guestfs___free_stringsbuf (&ret);
   return NULL;
 }
 
@@ -145,50 +139,34 @@ remove_from_list (char **list, const char *item)
     }
 }
 
-static void
-add_vfs (guestfs_h *g, char *mountable, char *vfs_type,
-         char ***ret, size_t *ret_size)
-{
-  /* Extend the return array. */
-  size_t i = *ret_size;
-  *ret_size += 2;
-  *ret = safe_realloc (g, *ret, (*ret_size + 1) * sizeof (char *));
-
-  (*ret)[i] = mountable;
-  (*ret)[i+1] = vfs_type;
-  (*ret)[i+2] = NULL;
-}
-
 /* Use vfs-type to look for a filesystem of some sort on 'dev'.
  * Apart from some types which we ignore, add the result to the
  * 'ret' string list.
  */
 static void
-check_with_vfs_type (guestfs_h *g, const char *device,
-                     char ***ret, size_t *ret_size)
+check_with_vfs_type (guestfs_h *g, const char *device, struct stringsbuf *sb)
 {
-  char *v;
-  char *vfs_type;
+  const char *v;
+  CLEANUP_FREE char *vfs_type = NULL;
 
   guestfs_push_error_handler (g, NULL, NULL);
   vfs_type = guestfs_vfs_type (g, device);
   guestfs_pop_error_handler (g);
 
   if (!vfs_type)
-    v = safe_strdup (g, "unknown");
-  else if (STREQ (vfs_type, "")) {
-    v = safe_strdup (g, "unknown");
-    free (vfs_type);
-  }
+    v = "unknown";
+  else if (STREQ (vfs_type, ""))
+    v = "unknown";
   else if (STREQ (vfs_type, "btrfs")) {
     CLEANUP_FREE_BTRFSSUBVOLUME_LIST struct guestfs_btrfssubvolume_list *vols =
       guestfs_btrfs_subvolume_list (g, device);
 
     for (size_t i = 0; i < vols->len; i++) {
       struct guestfs_btrfssubvolume *this = &vols->val[i];
-      char *mountable = safe_asprintf (g, "btrfsvol:%s/%s",
-                                       device, this->btrfssubvolume_path);
-      add_vfs (g, mountable, safe_strdup (g, "btrfs"), ret, ret_size);
+      guestfs___add_sprintf (g, sb,
+                             "btrfsvol:%s/%s",
+                             device, this->btrfssubvolume_path);
+      guestfs___add_string (g, sb, "btrfs");
     }
 
     v = vfs_type;
@@ -199,21 +177,18 @@ check_with_vfs_type (guestfs_h *g, const char *device,
      * importantly "LVM2_member" which is a PV.
      */
     size_t n = strlen (vfs_type);
-    if (n >= 7 && STREQ (&vfs_type[n-7], "_member")) {
-      free (vfs_type);
+    if (n >= 7 && STREQ (&vfs_type[n-7], "_member"))
       return;
-    }
 
     /* Ignore LUKS-encrypted partitions.  These are also containers. */
-    if (STREQ (vfs_type, "crypto_LUKS")) {
-      free (vfs_type);
+    if (STREQ (vfs_type, "crypto_LUKS"))
       return;
-    }
 
     v = vfs_type;
   }
 
-  add_vfs (g, safe_strdup (g, device), v, ret, ret_size);
+  guestfs___add_string (g, sb, device);
+  guestfs___add_string (g, sb, v);
 }
 
 /* We should ignore partitions that have MBR type byte 0x42, because
-- 
1.8.3.1




More information about the Libguestfs mailing list