From: "Richard W.M. Jones" <rjo...@redhat.com> This is modelled on similar code in the daemon that we have used successfully for a long time.
(cherry picked from commit 35278e4c186badb9e243628771da4cbd068ffaa0) --- po/POTFILES | 1 + src/Makefile.am | 1 + src/guestfs-internal.h | 24 ++++++++++++++ src/stringsbuf.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+) create mode 100644 src/stringsbuf.c diff --git a/po/POTFILES b/po/POTFILES index 92b9a18..bc4be6f 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -284,6 +284,7 @@ src/match.c src/osinfo.c src/private-data.c src/proto.c +src/stringsbuf.c src/tmpdirs.c src/utils.c test-tool/test-tool.c diff --git a/src/Makefile.am b/src/Makefile.am index 57cdf34..3facf16 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,6 +116,7 @@ libguestfs_la_SOURCES = \ osinfo.c \ private-data.c \ proto.c \ + stringsbuf.c \ tmpdirs.c \ libguestfs.syms diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 1d08375..8fd6388 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -597,6 +597,30 @@ extern int guestfs___match6 (guestfs_h *g, const char *str, const pcre *re, char #define match3 guestfs___match3 #define match6 guestfs___match6 +/* stringsbuf.c */ +struct stringsbuf { + char **argv; + size_t size; + size_t alloc; +}; +#define DECLARE_STRINGSBUF(v) \ + struct stringsbuf (v) = { .argv = NULL, .size = 0, .alloc = 0 } + +extern void guestfs___add_string_nodup (guestfs_h *g, struct stringsbuf *sb, char *str); +extern void guestfs___add_string (guestfs_h *g, struct stringsbuf *sb, const char *str); +extern void guestfs___add_sprintf (guestfs_h *g, struct stringsbuf *sb, const char *fs, ...) + __attribute__((format (printf,3,4))); +extern void guestfs___end_stringsbuf (guestfs_h *g, struct stringsbuf *sb); + +extern void guestfs___free_stringsbuf (struct stringsbuf *sb); + +#ifdef HAVE_ATTRIBUTE_CLEANUP +#define CLEANUP_FREE_STRINGSBUF __attribute__((cleanup(guestfs___cleanup_free_stringsbuf))) +#else +#define CLEANUP_FREE_STRINGSBUF +#endif +extern void guestfs___cleanup_free_stringsbuf (struct stringsbuf *sb); + /* proto.c */ extern int guestfs___send (guestfs_h *g, int proc_nr, uint64_t progress_hint, uint64_t optargs_bitmask, xdrproc_t xdrp, char *args); extern int guestfs___recv (guestfs_h *g, const char *fn, struct guestfs_message_header *hdr, struct guestfs_message_error *err, xdrproc_t xdrp, char *ret); diff --git a/src/stringsbuf.c b/src/stringsbuf.c new file mode 100644 index 0000000..df1dfd6 --- /dev/null +++ b/src/stringsbuf.c @@ -0,0 +1,88 @@ +/* libguestfs + * Copyright (C) 2013 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Note: Don't confuse this with stringsbuf in the daemon. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +#include "guestfs.h" +#include "guestfs-internal.h" + +void +guestfs___add_string_nodup (guestfs_h *g, struct stringsbuf *sb, char *str) +{ + if (sb->size >= sb->alloc) { + sb->alloc += 64; + sb->argv = safe_realloc (g, sb->argv, sb->alloc * sizeof (char *)); + } + + sb->argv[sb->size] = str; + sb->size++; +} + +void +guestfs___add_string (guestfs_h *g, struct stringsbuf *sb, const char *str) +{ + guestfs___add_string_nodup (g, sb, safe_strdup (g, str)); +} + +void +guestfs___add_sprintf (guestfs_h *g, struct stringsbuf *sb, + const char *fs, ...) +{ + va_list args; + char *str; + int r; + + va_start (args, fs); + r = vasprintf (&str, fs, args); + va_end (args); + if (r == -1) + g->abort_cb (); + + guestfs___add_string_nodup (g, sb, str); +} + +void +guestfs___end_stringsbuf (guestfs_h *g, struct stringsbuf *sb) +{ + guestfs___add_string_nodup (g, sb, NULL); +} + +void +guestfs___free_stringsbuf (struct stringsbuf *sb) +{ + size_t i; + + if (sb->argv) { + for (i = 0; i < sb->size; ++i) + free (sb->argv[i]); + } + free (sb->argv); +} + +void +guestfs___cleanup_free_stringsbuf (struct stringsbuf *sb) +{ + guestfs___free_stringsbuf (sb); +} -- 1.8.3.1 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs