Pino Toscano
2015-Jun-17 16:09 UTC
[Libguestfs] [PATCH 1/4] daemon: introduce free_stringsbuf
Simple shortcut to easily cleanup a stringsbuf. --- daemon/daemon.h | 1 + daemon/guestfsd.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/daemon/daemon.h b/daemon/daemon.h index 53cb797..bed4dbc 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -92,6 +92,7 @@ extern int add_string (struct stringsbuf *sb, const char *str); extern int add_sprintf (struct stringsbuf *sb, const char *fs, ...) __attribute__((format (printf,2,3))); extern int end_stringsbuf (struct stringsbuf *sb); +extern void free_stringsbuf (struct stringsbuf *sb); extern size_t count_strings (char *const *argv); extern void sort_strings (char **argv, size_t len); diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index c912ee3..453dee1 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -587,6 +587,13 @@ end_stringsbuf (struct stringsbuf *sb) return add_string_nodup (sb, NULL); } +void +free_stringsbuf (struct stringsbuf *sb) +{ + if (sb->argv != NULL) + free_stringslen (sb->argv, sb->size); +} + size_t count_strings (char *const *argv) { -- 2.1.0
Pino Toscano
2015-Jun-17 16:09 UTC
[Libguestfs] [PATCH 2/4] daemon: add CLEANUP_FREE_STRINGSBUF
--- daemon/daemon.h | 3 +++ daemon/guestfsd.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/daemon/daemon.h b/daemon/daemon.h index bed4dbc..d3ba148 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -178,6 +178,7 @@ extern void cleanup_free_string_list (void *ptr); extern void cleanup_unlink_free (void *ptr); extern void cleanup_close (void *ptr); extern void cleanup_aug_close (void *ptr); +extern void cleanup_free_stringsbuf (void *ptr); /*-- in names.c (auto-generated) --*/ extern const char *function_names[]; @@ -458,12 +459,14 @@ is_zero (const char *buffer, size_t size) #define CLEANUP_UNLINK_FREE __attribute__((cleanup(cleanup_unlink_free))) #define CLEANUP_CLOSE __attribute__((cleanup(cleanup_close))) #define CLEANUP_AUG_CLOSE __attribute__((cleanup(cleanup_aug_close))) +#define CLEANUP_FREE_STRINGSBUF __attribute__((cleanup(cleanup_free_stringsbuf))) #else #define CLEANUP_FREE #define CLEANUP_FREE_STRING_LIST #define CLEANUP_UNLINK_FREE #define CLEANUP_CLOSE #define CLEANUP_AUG_CLOSE +#define CLEANUP_FREE_STRINGSBUF #endif #endif /* GUESTFSD_DAEMON_H */ diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 453dee1..a571aad 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -1539,3 +1539,9 @@ cleanup_aug_close (void *ptr) if (aug != NULL) aug_close (aug); } + +void +cleanup_free_stringsbuf (void *ptr) +{ + free_stringsbuf ((struct stringsbuf *) ptr); +} -- 2.1.0
--- daemon/daemon.h | 1 + daemon/guestfsd.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/daemon/daemon.h b/daemon/daemon.h index d3ba148..f2244b0 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -92,6 +92,7 @@ extern int add_string (struct stringsbuf *sb, const char *str); extern int add_sprintf (struct stringsbuf *sb, const char *fs, ...) __attribute__((format (printf,2,3))); extern int end_stringsbuf (struct stringsbuf *sb); +extern char **take_stringsbuf (struct stringsbuf *sb); extern void free_stringsbuf (struct stringsbuf *sb); extern size_t count_strings (char *const *argv); diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index a571aad..198b2b2 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -594,6 +594,18 @@ free_stringsbuf (struct stringsbuf *sb) free_stringslen (sb->argv, sb->size); } +/* Take the ownership of the strings of the strings buffer, + * resetting it to a null buffer. + */ +char ** +take_stringsbuf (struct stringsbuf *sb) +{ + DECLARE_STRINGSBUF (null); + char **ret = sb->argv; + *sb = null; + return ret; +} + size_t count_strings (char *const *argv) { -- 2.1.0
Mold split_lines_sb from split_lines, so it returns the strings buffer with the result of the split. This way, we can have the number of lines in the array, with no need to count them again later. split_lines is rewritten to take the ownership of the result of split_lines_sb. --- daemon/daemon.h | 1 + daemon/guestfsd.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/daemon/daemon.h b/daemon/daemon.h index f2244b0..136e9a9 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -110,6 +110,7 @@ extern int compare_device_names (const char *a, const char *b); extern char *concat_strings (char *const *argv); extern char *join_strings (const char *separator, char *const *argv); +extern struct stringsbuf split_lines_sb (char *str); extern char **split_lines (char *str); extern char **empty_list (void); diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 198b2b2..21b3600 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -1115,7 +1115,8 @@ commandrvf (char **stdoutput, char **stderror, int flags, return -1; } -/* Split an output string into a NULL-terminated list of lines. +/* Split an output string into a NULL-terminated list of lines, + * wrapped into a stringsbuf. * Typically this is used where we have run an external command * which has printed out a list of things, and we want to return * an actual list. @@ -1132,15 +1133,23 @@ commandrvf (char **stdoutput, char **stderror, int flags, * function (which is usually OK because it's the 'out' string * from command()). You can free the original string, because * add_string() strdups the strings. + * + * argv in the stringsbuf will be NULL in case of errors. */ -char ** -split_lines (char *str) +struct stringsbuf +split_lines_sb (char *str) { DECLARE_STRINGSBUF (lines); + DECLARE_STRINGSBUF (null); char *p, *pend; - if (STREQ (str, "")) - return empty_list (); + if (STREQ (str, "")) { + /* No need to check the return value, as the stringsbuf will be + * returned as it is anyway. + */ + end_stringsbuf (&lines); + return lines; + } p = str; while (p) { @@ -1155,16 +1164,26 @@ split_lines (char *str) } if (add_string (&lines, p) == -1) { - return NULL; + free_stringsbuf (&lines); + return null; } p = pend; } - if (end_stringsbuf (&lines) == -1) - return NULL; + if (end_stringsbuf (&lines) == -1) { + free_stringsbuf (&lines); + return null; + } + + return lines; +} - return lines.argv; +char ** +split_lines (char *str) +{ + struct stringsbuf sb = split_lines_sb (str); + return take_stringsbuf (&sb); } char ** -- 2.1.0
Richard W.M. Jones
2015-Jun-17 18:50 UTC
Re: [Libguestfs] [PATCH 4/4] daemon: add split_lines_sb
ACK series. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Reasonably Related Threads
- [PATCH 1/4] daemon: introduce free_stringsbuf
- [PATCH v7 13/13] daemon: Link guestfsd with libutils.
- [PATCH libguestfs 2/3] daemon: Add filter_list utility function.
- [PATCH libguestfs v2 2/3] daemon: Add filter_list utility function.
- [PATCH 05/27] daemon: Reimplement several devsparts APIs in OCaml.