[libvirt] [PATCH v1 00/21] use GCC's cleanup attribute in src/util

This series of patches introduces a new set of macros which help in using GCC's __attribute__((cleanup)) in the code. Then the patches modify a few files in src/util to use VIR_AUTOFREE and VIR_AUTOPTR for automatic freeing of memory and get rid of some VIR_FREE macro invocations and *Free function calls. Sukrit Bhatnagar (21): add macros for implementing automatic cleanup functionality util: arptable: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: iohelper: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: audit: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: fcp: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: eventpoll: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: filecache: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: authconfig: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC util: authconfig: remove redundant include directive util: authconfig: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: auth: remove redundant include directive util: auth: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: auth: use VIR_AUTOPTR for aggregate types util: json: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC util: json: remove redundant include directive util: json: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: json: use VIR_AUTOPTR for aggregate types util: identity: use VIR_AUTOFREE instead of VIR_FREE for scalar types util: bitmap: define cleanup function using VIR_DEFINE_AUTOPTR_FUNC util: bitmap: remove redundant include directive util: bitmap: use VIR_AUTOPTR for aggregate types src/util/iohelper.c | 4 +-- src/util/viralloc.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ src/util/virarptable.c | 14 +++------- src/util/viraudit.c | 3 +-- src/util/virauth.c | 61 +++++++++++++------------------------------ src/util/virauthconfig.c | 35 +++++++++---------------- src/util/virauthconfig.h | 3 +++ src/util/virbitmap.c | 8 ++---- src/util/virbitmap.h | 3 +++ src/util/vireventpoll.c | 7 ++--- src/util/virfcp.c | 20 +++++--------- src/util/virfilecache.c | 35 ++++++++----------------- src/util/viridentity.c | 54 ++++++++++++++++---------------------- src/util/virjson.c | 45 +++++++++----------------------- src/util/virjson.h | 3 +++ 15 files changed, 168 insertions(+), 195 deletions(-) -- 1.8.3.1

New macros are added to src/util/viralloc.h which help in adding GCC's cleanup attribute to variable declarations. --- src/util/viralloc.h | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/util/viralloc.h b/src/util/viralloc.h index 69d0f90..5804ca9 100644 --- a/src/util/viralloc.h +++ b/src/util/viralloc.h @@ -596,4 +596,72 @@ void virAllocTestInit(void); int virAllocTestCount(void); void virAllocTestOOM(int n, int m); void virAllocTestHook(void (*func)(int, void*), void *data); + +# define VIR_AUTOPTR_FUNC_NAME(type) virAutoPtr##type +# define VIR_AUTOCLEAR_FUNC_NAME(type) virAutoClear##type + +/** + * VIR_DEFINE_AUTOPTR_FUNC: + * @type: type of the variable to be freed automatically + * @func: cleanup function to be automatically called + * + * This macro defines a function for automatic freeing of + * resources allocated to a variable of type @type. This newly + * defined function works as a necessary wrapper around @func. + */ +# define VIR_DEFINE_AUTOPTR_FUNC(type, func) \ + static inline void VIR_AUTOPTR_FUNC_NAME(type)(type *_ptr) \ + { \ + (func)(*_ptr); \ + } \ + +/** + * VIR_DEFINE_AUTOCLEAR_FUNC: + * @type: type of the variable to be freed automatically + * @func: cleanup function to be automatically called + * + * This macro defines a function for automatic clearing of + * a variable of type @type. This newly defined function + * works as a necessary wrapper around @func. + */ +# define VIR_DEFINE_AUTOCLEAR_FUNC(type, func) \ + static inline void VIR_AUTOCLEAR_FUNC_NAME(type)(type *_ptr) \ + { \ + (func)(_ptr); \ + } \ + +/** + * VIR_AUTOFREE: + * @type: type of the variable to be freed automatically + * + * Macro to automatically free the memory allocated to + * the variable declared with it by calling virFree + * when the variable goes out of scope. + */ +# define VIR_AUTOFREE(type) __attribute__((cleanup(virFree))) type + +/** + * VIR_AUTOPTR: + * @type: type of the variable to be freed automatically + * + * Macro to automatically free the memory allocated to + * the variable declared with it by calling the function + * defined by VIR_DEFINE_AUTOPTR_FUNC when the variable + * goes out of scope. + */ +# define VIR_AUTOPTR(type) \ + __attribute__((cleanup(VIR_AUTOPTR_FUNC_NAME(type)))) type + +/** + * VIR_AUTOCLEAR: + * @type: type of the variable to be freed automatically + * + * Macro to automatically clear the variable declared + * with it by calling the function defined by + * VIR_DEFINE_AUTOCLEAR_FUNC when the variable goes out + * of scope. + */ +# define VIR_AUTOCLEAR(type) \ + __attribute__((cleanup(VIR_AUTOCLEAR_FUNC_NAME(type)))) type + #endif /* __VIR_MEMORY_H_ */ -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virarptable.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/util/virarptable.c b/src/util/virarptable.c index c0e90dc..bf40267 100644 --- a/src/util/virarptable.c +++ b/src/util/virarptable.c @@ -71,9 +71,8 @@ virArpTableGet(void) { int num = 0; int msglen; - void *nlData = NULL; + VIR_AUTOFREE(void *) nlData = NULL; virArpTablePtr table = NULL; - char *ipstr = NULL; struct nlmsghdr* nh; struct rtattr * tb[NDA_MAX+1]; @@ -89,6 +88,7 @@ virArpTableGet(void) VIR_WARNINGS_NO_CAST_ALIGN for (; NLMSG_OK(nh, msglen); nh = NLMSG_NEXT(nh, msglen)) { VIR_WARNINGS_RESET + VIR_AUTOFREE(char *) ipstr = NULL; struct ndmsg *r = NLMSG_DATA(nh); int len = nh->nlmsg_len; void *addr; @@ -108,7 +108,7 @@ virArpTableGet(void) continue; if (nh->nlmsg_type == NLMSG_DONE) - goto end_of_netlink_messages; + return table; VIR_WARNINGS_NO_CAST_ALIGN parse_rtattr(tb, NDA_MAX, NDA_RTA(r), @@ -134,8 +134,6 @@ virArpTableGet(void) if (VIR_STRDUP(table->t[num].ipaddr, ipstr) < 0) goto cleanup; - - VIR_FREE(ipstr); } if (tb[NDA_LLADDR]) { @@ -154,14 +152,8 @@ virArpTableGet(void) } } - end_of_netlink_messages: - VIR_FREE(nlData); - return table; - cleanup: virArpTableFree(table); - VIR_FREE(ipstr); - VIR_FREE(nlData); return NULL; } -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/iohelper.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/util/iohelper.c b/src/util/iohelper.c index bb8a8dd..f7794dc 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -46,7 +46,7 @@ static int runIO(const char *path, int fd, int oflags) { - void *base = NULL; /* Location to be freed */ + VIR_AUTOFREE(void *) base = NULL; /* Location to be freed */ char *buf = NULL; /* Aligned location within base */ size_t buflen = 1024*1024; intptr_t alignMask = 64*1024 - 1; @@ -174,8 +174,6 @@ runIO(const char *path, int fd, int oflags) virReportSystemError(errno, _("Unable to close %s"), path); ret = -1; } - - VIR_FREE(base); return ret; } -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/viraudit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util/viraudit.c b/src/util/viraudit.c index 0085dc3..a49d458 100644 --- a/src/util/viraudit.c +++ b/src/util/viraudit.c @@ -97,7 +97,7 @@ void virAuditSend(virLogSourcePtr source, virAuditRecordType type ATTRIBUTE_UNUSED, bool success, const char *fmt, ...) { - char *str = NULL; + VIR_AUTOFREE(char *) str = NULL; va_list args; /* Duplicate later checks, to short circuit & avoid printf overhead @@ -144,7 +144,6 @@ void virAuditSend(virLogSourcePtr source, } } #endif - VIR_FREE(str); } void virAuditClose(void) -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virfcp.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/util/virfcp.c b/src/util/virfcp.c index 7660ba7..b703744 100644 --- a/src/util/virfcp.c +++ b/src/util/virfcp.c @@ -40,16 +40,12 @@ bool virFCIsCapableRport(const char *rport) { - bool ret = false; - char *path = NULL; + VIR_AUTOFREE(char *) path = NULL; if (virBuildPath(&path, SYSFS_FC_RPORT_PATH, rport) < 0) return false; - ret = virFileExists(path); - VIR_FREE(path); - - return ret; + return virFileExists(path); } int @@ -57,8 +53,8 @@ virFCReadRportValue(const char *rport, const char *entry, char **result) { - int ret = -1; - char *buf = NULL, *p = NULL; + VIR_AUTOFREE(char *) buf = NULL; + char *p = NULL; if (virFileReadValueString(&buf, "%s/%s/%s", SYSFS_FC_RPORT_PATH, rport, entry) < 0) { @@ -69,13 +65,9 @@ virFCReadRportValue(const char *rport, *p = '\0'; if (VIR_STRDUP(*result, buf) < 0) - goto cleanup; - - ret = 0; + return -1; - cleanup: - VIR_FREE(buf); - return ret; + return 0; } #else -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/vireventpoll.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/util/vireventpoll.c b/src/util/vireventpoll.c index 81ecab4..13d278d 100644 --- a/src/util/vireventpoll.c +++ b/src/util/vireventpoll.c @@ -618,7 +618,7 @@ static void virEventPollCleanupHandles(void) */ int virEventPollRunOnce(void) { - struct pollfd *fds = NULL; + VIR_AUTOFREE(struct pollfd *) fds = NULL; int ret, timeout, nfds; virMutexLock(&eventLoop.lock); @@ -645,7 +645,7 @@ int virEventPollRunOnce(void) goto retry; virReportSystemError(errno, "%s", _("Unable to poll on file handles")); - goto error_unlocked; + return -1; } EVENT_DEBUG("Poll got %d event(s)", ret); @@ -662,13 +662,10 @@ int virEventPollRunOnce(void) eventLoop.running = 0; virMutexUnlock(&eventLoop.lock); - VIR_FREE(fds); return 0; error: virMutexUnlock(&eventLoop.lock); - error_unlocked: - VIR_FREE(fds); return -1; } -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virfilecache.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/src/util/virfilecache.c b/src/util/virfilecache.c index 96ae96d..2927c68 100644 --- a/src/util/virfilecache.c +++ b/src/util/virfilecache.c @@ -100,18 +100,17 @@ static char * virFileCacheGetFileName(virFileCachePtr cache, const char *name) { - char *file = NULL; - char *namehash = NULL; + VIR_AUTOFREE(char *) namehash = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; if (virCryptoHashString(VIR_CRYPTO_HASH_SHA256, name, &namehash) < 0) - goto cleanup; + return NULL; if (virFileMakePath(cache->dir) < 0) { virReportSystemError(errno, _("Unable to create directory '%s'"), cache->dir); - goto cleanup; + return NULL; } virBufferAsprintf(&buf, "%s/%s", cache->dir, namehash); @@ -120,13 +119,9 @@ virFileCacheGetFileName(virFileCachePtr cache, virBufferAsprintf(&buf, ".%s", cache->suffix); if (virBufferCheckError(&buf) < 0) - goto cleanup; - - file = virBufferContentAndReset(&buf); + return NULL; - cleanup: - VIR_FREE(namehash); - return file; + return virBufferContentAndReset(&buf); } @@ -135,7 +130,7 @@ virFileCacheLoad(virFileCachePtr cache, const char *name, void **data) { - char *file = NULL; + VIR_AUTOFREE(char *) file = NULL; int ret = -1; void *loadData = NULL; @@ -178,7 +173,6 @@ virFileCacheLoad(virFileCachePtr cache, cleanup: virObjectUnref(loadData); - VIR_FREE(file); return ret; } @@ -188,20 +182,15 @@ virFileCacheSave(virFileCachePtr cache, const char *name, void *data) { - char *file = NULL; - int ret = -1; + VIR_AUTOFREE(char *) file = NULL; if (!(file = virFileCacheGetFileName(cache, name))) - return ret; + return -1; if (cache->handlers.saveFile(data, file, cache->priv) < 0) - goto cleanup; - - ret = 0; + return -1; - cleanup: - VIR_FREE(file); - return ret; + return 0; } @@ -346,7 +335,7 @@ virFileCacheLookupByFunc(virFileCachePtr cache, const void *iterData) { void *data = NULL; - char *name = NULL; + VIR_AUTOFREE(char *) name = NULL; virObjectLock(cache); @@ -356,8 +345,6 @@ virFileCacheLookupByFunc(virFileCachePtr cache, virObjectRef(data); virObjectUnlock(cache); - VIR_FREE(name); - return data; } -- 1.8.3.1

Using the VIR_DEFINE_AUTOPTR_FUNC macro defined in src/util/viralloc.h, define a new wrapper around an existing cleanup function which will be called when a variable declared with VIR_AUTOPTR macro goes out of scope. --- src/util/virauthconfig.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/virauthconfig.h b/src/util/virauthconfig.h index ac0ceeb..375ccad 100644 --- a/src/util/virauthconfig.h +++ b/src/util/virauthconfig.h @@ -24,6 +24,7 @@ # define __VIR_AUTHCONFIG_H__ # include "internal.h" +# include "viralloc.h" typedef struct _virAuthConfig virAuthConfig; typedef virAuthConfig *virAuthConfigPtr; @@ -42,4 +43,6 @@ int virAuthConfigLookup(virAuthConfigPtr auth, const char *credname, const char **value); +VIR_DEFINE_AUTOPTR_FUNC(virAuthConfigPtr, virAuthConfigFree) + #endif /* __VIR_AUTHCONFIG_H__ */ -- 1.8.3.1

The include directive for viralloc.h is added in virauthconfig.h in the previous patch. --- src/util/virauthconfig.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util/virauthconfig.c b/src/util/virauthconfig.c index 91c9c0c..3487cc2 100644 --- a/src/util/virauthconfig.c +++ b/src/util/virauthconfig.c @@ -25,7 +25,6 @@ #include "virauthconfig.h" #include "virkeyfile.h" -#include "viralloc.h" #include "virlog.h" #include "virerror.h" #include "virstring.h" -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virauthconfig.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/util/virauthconfig.c b/src/util/virauthconfig.c index 3487cc2..9977e71 100644 --- a/src/util/virauthconfig.c +++ b/src/util/virauthconfig.c @@ -105,10 +105,9 @@ int virAuthConfigLookup(virAuthConfigPtr auth, const char *credname, const char **value) { - char *authgroup = NULL; - char *credgroup = NULL; + VIR_AUTOFREE(char *) authgroup = NULL; + VIR_AUTOFREE(char *) credgroup = NULL; const char *authcred; - int ret = -1; *value = NULL; @@ -118,47 +117,38 @@ int virAuthConfigLookup(virAuthConfigPtr auth, hostname = "localhost"; if (virAsprintf(&authgroup, "auth-%s-%s", service, hostname) < 0) - goto cleanup; + return -1; if (!virKeyFileHasGroup(auth->keyfile, authgroup)) { VIR_FREE(authgroup); if (virAsprintf(&authgroup, "auth-%s-%s", service, "default") < 0) - goto cleanup; + return -1; } - if (!virKeyFileHasGroup(auth->keyfile, authgroup)) { - ret = 0; - goto cleanup; - } + if (!virKeyFileHasGroup(auth->keyfile, authgroup)) + return 0; if (!(authcred = virKeyFileGetValueString(auth->keyfile, authgroup, "credentials"))) { virReportError(VIR_ERR_CONF_SYNTAX, _("Missing item 'credentials' in group '%s' in '%s'"), authgroup, auth->path); - goto cleanup; + return -1; } if (virAsprintf(&credgroup, "credentials-%s", authcred) < 0) - goto cleanup; + return -1; if (!virKeyFileHasGroup(auth->keyfile, credgroup)) { virReportError(VIR_ERR_CONF_SYNTAX, _("Missing group 'credentials-%s' referenced from group '%s' in '%s'"), authcred, authgroup, auth->path); - goto cleanup; + return -1; } - if (!virKeyFileHasValue(auth->keyfile, credgroup, credname)) { - ret = 0; - goto cleanup; - } + if (!virKeyFileHasValue(auth->keyfile, credgroup, credname)) + return 0; *value = virKeyFileGetValueString(auth->keyfile, credgroup, credname); - ret = 0; - - cleanup: - VIR_FREE(authgroup); - VIR_FREE(credgroup); - return ret; + return 0; } -- 1.8.3.1

The include directive for viralloc.h is added in virauthconfig.h in a previous patch. --- src/util/virauth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util/virauth.c b/src/util/virauth.c index adb093e..c6a2ce7 100644 --- a/src/util/virauth.c +++ b/src/util/virauth.c @@ -26,7 +26,6 @@ #include "virauth.h" #include "virutil.h" -#include "viralloc.h" #include "virlog.h" #include "datatypes.h" #include "virerror.h" -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virauth.c | 45 +++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/src/util/virauth.c b/src/util/virauth.c index c6a2ce7..d3a5cc7 100644 --- a/src/util/virauth.c +++ b/src/util/virauth.c @@ -41,10 +41,9 @@ int virAuthGetConfigFilePathURI(virURIPtr uri, char **path) { - int ret = -1; size_t i; const char *authenv = virGetEnvBlockSUID("LIBVIRT_AUTH_FILE"); - char *userdir = NULL; + VIR_AUTOFREE(char *) userdir = NULL; *path = NULL; @@ -53,7 +52,7 @@ virAuthGetConfigFilePathURI(virURIPtr uri, if (authenv) { VIR_DEBUG("Using path from env '%s'", authenv); if (VIR_STRDUP(*path, authenv) < 0) - goto cleanup; + return -1; return 0; } @@ -63,17 +62,17 @@ virAuthGetConfigFilePathURI(virURIPtr uri, uri->params[i].value) { VIR_DEBUG("Using path from URI '%s'", uri->params[i].value); if (VIR_STRDUP(*path, uri->params[i].value) < 0) - goto cleanup; + return -1; return 0; } } } if (!(userdir = virGetUserConfigDirectory())) - goto cleanup; + return -1; if (virAsprintf(path, "%s/auth.conf", userdir) < 0) - goto cleanup; + return -1; VIR_DEBUG("Checking for readability of '%s'", *path); if (access(*path, R_OK) == 0) @@ -82,7 +81,7 @@ virAuthGetConfigFilePathURI(virURIPtr uri, VIR_FREE(*path); if (VIR_STRDUP(*path, SYSCONFDIR "/libvirt/auth.conf") < 0) - goto cleanup; + return -1; VIR_DEBUG("Checking for readability of '%s'", *path); if (access(*path, R_OK) == 0) @@ -91,13 +90,9 @@ virAuthGetConfigFilePathURI(virURIPtr uri, VIR_FREE(*path); done: - ret = 0; - VIR_DEBUG("Using auth file '%s'", NULLSTR(*path)); - cleanup: - VIR_FREE(userdir); - return ret; + return 0; } @@ -155,7 +150,7 @@ virAuthGetUsernamePath(const char *path, { unsigned int ncred; virConnectCredential cred; - char *prompt; + VIR_AUTOFREE(char *) prompt = NULL; char *ret = NULL; if (virAuthGetCredential(servicename, hostname, "username", path, &ret) < 0) @@ -192,8 +187,6 @@ virAuthGetUsernamePath(const char *path, break; } - VIR_FREE(prompt); - return cred.result; } @@ -205,18 +198,13 @@ virAuthGetUsername(virConnectPtr conn, const char *defaultUsername, const char *hostname) { - char *ret; - char *path; + VIR_AUTOFREE(char *) path = NULL; if (virAuthGetConfigFilePath(conn, &path) < 0) return NULL; - ret = virAuthGetUsernamePath(path, auth, servicename, + return virAuthGetUsernamePath(path, auth, servicename, defaultUsername, hostname); - - VIR_FREE(path); - - return ret; } @@ -229,7 +217,7 @@ virAuthGetPasswordPath(const char *path, { unsigned int ncred; virConnectCredential cred; - char *prompt; + VIR_AUTOFREE(char *) prompt = NULL; char *ret = NULL; if (virAuthGetCredential(servicename, hostname, "password", path, &ret) < 0) @@ -263,8 +251,6 @@ virAuthGetPasswordPath(const char *path, break; } - VIR_FREE(prompt); - return cred.result; } @@ -276,15 +262,10 @@ virAuthGetPassword(virConnectPtr conn, const char *username, const char *hostname) { - char *ret; - char *path; + VIR_AUTOFREE(char *) path = NULL; if (virAuthGetConfigFilePath(conn, &path) < 0) return NULL; - ret = virAuthGetPasswordPath(path, auth, servicename, username, hostname); - - VIR_FREE(path); - - return ret; + return virAuthGetPasswordPath(path, auth, servicename, username, hostname); } -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOPTR macro, majority of the calls to *Free functions can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virauth.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/util/virauth.c b/src/util/virauth.c index d3a5cc7..f000d45 100644 --- a/src/util/virauth.c +++ b/src/util/virauth.c @@ -111,8 +111,7 @@ virAuthGetCredential(const char *servicename, const char *path, char **value) { - int ret = -1; - virAuthConfigPtr config = NULL; + VIR_AUTOPTR(virAuthConfigPtr) config = NULL; const char *tmp; *value = NULL; @@ -121,23 +120,19 @@ virAuthGetCredential(const char *servicename, return 0; if (!(config = virAuthConfigNew(path))) - goto cleanup; + return -1; if (virAuthConfigLookup(config, servicename, hostname, credname, &tmp) < 0) - goto cleanup; + return -1; if (VIR_STRDUP(*value, tmp) < 0) - goto cleanup; - - ret = 0; + return -1; - cleanup: - virAuthConfigFree(config); - return ret; + return 0; } -- 1.8.3.1

Using the VIR_DEFINE_AUTOPTR_FUNC macro defined in src/util/viralloc.h, define a new wrapper around an existing cleanup function which will be called when a variable declared with VIR_AUTOPTR macro goes out of scope. --- src/util/virjson.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/virjson.h b/src/util/virjson.h index e4a82bd..593dcb7 100644 --- a/src/util/virjson.h +++ b/src/util/virjson.h @@ -26,6 +26,7 @@ # include "internal.h" # include "virbitmap.h" +# include "viralloc.h" # include <stdarg.h> @@ -45,6 +46,8 @@ typedef virJSONValue *virJSONValuePtr; void virJSONValueFree(virJSONValuePtr value); void virJSONValueHashFree(void *opaque, const void *name); +VIR_DEFINE_AUTOPTR_FUNC(virJSONValuePtr, virJSONValueFree) + virJSONType virJSONValueGetType(const virJSONValue *value); int virJSONValueObjectCreate(virJSONValuePtr *obj, ...) -- 1.8.3.1

The include directive for viralloc.h is added in virjson.h in the previous patch. --- src/util/virjson.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util/virjson.c b/src/util/virjson.c index 0559d40..92f3994 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -24,7 +24,6 @@ #include <config.h> #include "virjson.h" -#include "viralloc.h" #include "virerror.h" #include "virlog.h" #include "virstring.h" -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virjson.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/util/virjson.c b/src/util/virjson.c index 92f3994..1391a3b 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -497,11 +497,10 @@ virJSONValuePtr virJSONValueNewNumberInt(int data) { virJSONValuePtr val = NULL; - char *str; + VIR_AUTOFREE(char *) str = NULL; if (virAsprintf(&str, "%i", data) < 0) return NULL; val = virJSONValueNewNumber(str); - VIR_FREE(str); return val; } @@ -510,11 +509,10 @@ virJSONValuePtr virJSONValueNewNumberUint(unsigned int data) { virJSONValuePtr val = NULL; - char *str; + VIR_AUTOFREE(char *) str = NULL; if (virAsprintf(&str, "%u", data) < 0) return NULL; val = virJSONValueNewNumber(str); - VIR_FREE(str); return val; } @@ -523,11 +521,10 @@ virJSONValuePtr virJSONValueNewNumberLong(long long data) { virJSONValuePtr val = NULL; - char *str; + VIR_AUTOFREE(char *) str = NULL; if (virAsprintf(&str, "%lld", data) < 0) return NULL; val = virJSONValueNewNumber(str); - VIR_FREE(str); return val; } @@ -536,11 +533,10 @@ virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data) { virJSONValuePtr val = NULL; - char *str; + VIR_AUTOFREE(char *) str = NULL; if (virAsprintf(&str, "%llu", data) < 0) return NULL; val = virJSONValueNewNumber(str); - VIR_FREE(str); return val; } @@ -549,11 +545,10 @@ virJSONValuePtr virJSONValueNewNumberDouble(double data) { virJSONValuePtr val = NULL; - char *str; + VIR_AUTOFREE(char *) str = NULL; if (virDoubleToStr(&str, data) < 0) return NULL; val = virJSONValueNewNumber(str); - VIR_FREE(str); return val; } @@ -1171,10 +1166,9 @@ int virJSONValueGetArrayAsBitmap(const virJSONValue *val, virBitmapPtr *bitmap) { - int ret = -1; virJSONValuePtr elem; size_t i; - unsigned long long *elems = NULL; + VIR_AUTOFREE(unsigned long long *) elems = NULL; unsigned long long maxelem = 0; *bitmap = NULL; @@ -1191,25 +1185,20 @@ virJSONValueGetArrayAsBitmap(const virJSONValue *val, if (elem->type != VIR_JSON_TYPE_NUMBER || virStrToLong_ullp(elem->data.number, NULL, 10, &elems[i]) < 0) - goto cleanup; + return -1; if (elems[i] > maxelem) maxelem = elems[i]; } if (!(*bitmap = virBitmapNewQuiet(maxelem + 1))) - goto cleanup; + return -1; /* second pass sets the correct bits in the map */ for (i = 0; i < val->data.array.nvalues; i++) ignore_value(virBitmapSetBit(*bitmap, elems[i])); - ret = 0; - - cleanup: - VIR_FREE(elems); - - return ret; + return 0; } -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOPTR macro, majority of the calls to *Free functions can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virjson.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/util/virjson.c b/src/util/virjson.c index 1391a3b..3b54d94 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -2033,16 +2033,12 @@ char * virJSONStringReformat(const char *jsonstr, bool pretty) { - virJSONValuePtr json; - char *ret; + VIR_AUTOPTR(virJSONValuePtr) json = NULL; if (!(json = virJSONValueFromString(jsonstr))) return NULL; - ret = virJSONValueToString(json, pretty); - - virJSONValueFree(json); - return ret; + return virJSONValueToString(json, pretty); } @@ -2131,7 +2127,7 @@ virJSONValueObjectDeflattenWorker(const char *key, virJSONValuePtr virJSONValueObjectDeflatten(virJSONValuePtr json) { - virJSONValuePtr deflattened; + VIR_AUTOPTR(virJSONValuePtr) deflattened = NULL; virJSONValuePtr ret = NULL; if (!(deflattened = virJSONValueNewObject())) @@ -2140,12 +2136,9 @@ virJSONValueObjectDeflatten(virJSONValuePtr json) if (virJSONValueObjectForeachKeyValue(json, virJSONValueObjectDeflattenWorker, deflattened) < 0) - goto cleanup; + return NULL; VIR_STEAL_PTR(ret, deflattened); - cleanup: - virJSONValueFree(deflattened); - return ret; } -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/viridentity.c | 54 ++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/util/viridentity.c b/src/util/viridentity.c index 2f4307b..2060dd7 100644 --- a/src/util/viridentity.c +++ b/src/util/viridentity.c @@ -133,8 +133,8 @@ int virIdentitySetCurrent(virIdentityPtr ident) */ virIdentityPtr virIdentityGetSystem(void) { - char *username = NULL; - char *groupname = NULL; + VIR_AUTOFREE(char *) username = NULL; + VIR_AUTOFREE(char *) groupname = NULL; unsigned long long startTime; virIdentityPtr ret = NULL; #if WITH_SELINUX @@ -154,14 +154,14 @@ virIdentityPtr virIdentityGetSystem(void) goto error; if (!(username = virGetUserName(geteuid()))) - goto cleanup; + return ret; if (virIdentitySetUNIXUserName(ret, username) < 0) goto error; if (virIdentitySetUNIXUserID(ret, getuid()) < 0) goto error; if (!(groupname = virGetGroupName(getegid()))) - goto cleanup; + return ret; if (virIdentitySetUNIXGroupName(ret, groupname) < 0) goto error; if (virIdentitySetUNIXGroupID(ret, getgid()) < 0) @@ -172,7 +172,7 @@ virIdentityPtr virIdentityGetSystem(void) if (getcon(&con) < 0) { virReportSystemError(errno, "%s", _("Unable to lookup SELinux process context")); - goto cleanup; + return ret; } if (virIdentitySetSELinuxContext(ret, con) < 0) { freecon(con); @@ -182,15 +182,9 @@ virIdentityPtr virIdentityGetSystem(void) } #endif - cleanup: - VIR_FREE(username); - VIR_FREE(groupname); - return ret; - error: virObjectUnref(ret); - ret = NULL; - goto cleanup; + return NULL; } @@ -461,15 +455,14 @@ int virIdentitySetUNIXUserName(virIdentityPtr ident, int virIdentitySetUNIXUserID(virIdentityPtr ident, uid_t uid) { - char *val; - int ret; + VIR_AUTOFREE(char *) val = NULL; + if (virAsprintf(&val, "%d", (int)uid) < 0) return -1; - ret = virIdentitySetAttr(ident, + + return virIdentitySetAttr(ident, VIR_IDENTITY_ATTR_UNIX_USER_ID, val); - VIR_FREE(val); - return ret; } @@ -485,45 +478,42 @@ int virIdentitySetUNIXGroupName(virIdentityPtr ident, int virIdentitySetUNIXGroupID(virIdentityPtr ident, gid_t gid) { - char *val; - int ret; + VIR_AUTOFREE(char *) val = NULL; + if (virAsprintf(&val, "%d", (int)gid) < 0) return -1; - ret = virIdentitySetAttr(ident, + + return virIdentitySetAttr(ident, VIR_IDENTITY_ATTR_UNIX_GROUP_ID, val); - VIR_FREE(val); - return ret; } int virIdentitySetUNIXProcessID(virIdentityPtr ident, pid_t pid) { - char *val; - int ret; + VIR_AUTOFREE(char *) val = NULL; + if (virAsprintf(&val, "%lld", (long long) pid) < 0) return -1; - ret = virIdentitySetAttr(ident, + + return virIdentitySetAttr(ident, VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, val); - VIR_FREE(val); - return ret; } int virIdentitySetUNIXProcessTime(virIdentityPtr ident, unsigned long long timestamp) { - char *val; - int ret; + VIR_AUTOFREE(char *) val = NULL; + if (virAsprintf(&val, "%llu", timestamp) < 0) return -1; - ret = virIdentitySetAttr(ident, + + return virIdentitySetAttr(ident, VIR_IDENTITY_ATTR_UNIX_PROCESS_TIME, val); - VIR_FREE(val); - return ret; } -- 1.8.3.1

On Fri, Jun 08, 2018 at 01:04:40AM +0530, Sukrit Bhatnagar wrote:
By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOFREE macro, majority of the VIR_FREE calls can be dropped, which in turn leads to getting rid of most of our cleanup sections.
You're missing the SoB line here. Make sure to add that to comply with the Developer Certificate of Origin, for more info, see https://libvirt.org/governance.html#contributors
--- src/util/viridentity.c | 54 ++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 32 deletions(-)
diff --git a/src/util/viridentity.c b/src/util/viridentity.c index 2f4307b..2060dd7 100644 --- a/src/util/viridentity.c +++ b/src/util/viridentity.c @@ -133,8 +133,8 @@ int virIdentitySetCurrent(virIdentityPtr ident) */ virIdentityPtr virIdentityGetSystem(void) { - char *username = NULL; - char *groupname = NULL; + VIR_AUTOFREE(char *) username = NULL; + VIR_AUTOFREE(char *) groupname = NULL; unsigned long long startTime; virIdentityPtr ret = NULL; #if WITH_SELINUX @@ -154,14 +154,14 @@ virIdentityPtr virIdentityGetSystem(void) goto error;
if (!(username = virGetUserName(geteuid()))) - goto cleanup; + return ret; if (virIdentitySetUNIXUserName(ret, username) < 0) goto error; if (virIdentitySetUNIXUserID(ret, getuid()) < 0) goto error;
if (!(groupname = virGetGroupName(getegid()))) - goto cleanup; + return ret; if (virIdentitySetUNIXGroupName(ret, groupname) < 0) goto error; if (virIdentitySetUNIXGroupID(ret, getgid()) < 0) @@ -172,7 +172,7 @@ virIdentityPtr virIdentityGetSystem(void) if (getcon(&con) < 0) { virReportSystemError(errno, "%s", _("Unable to lookup SELinux process context")); - goto cleanup; + return ret; } if (virIdentitySetSELinuxContext(ret, con) < 0) { freecon(con); @@ -182,15 +182,9 @@ virIdentityPtr virIdentityGetSystem(void) } #endif
- cleanup: - VIR_FREE(username); - VIR_FREE(groupname); - return ret; - error: virObjectUnref(ret); - ret = NULL; - goto cleanup; + return NULL;
you're returning NULL on success too, which causes the test suite to fail, make sure that you run make check -j X && make syntax-check -j X after every patch in the series. X - number of logical CPUs + 1 I briefly went through the other VIR_AUTOFREE patches and didn't spot any problems, I'll have a better look once you post another version of this series due to the points I raised. Regards, Erik

Using the VIR_DEFINE_AUTOPTR_FUNC macro defined in src/util/viralloc.h, define a new wrapper around an existing cleanup function which will be called when a variable declared with VIR_AUTOPTR macro goes out of scope. --- src/util/virbitmap.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h index 2464814..86bb84e 100644 --- a/src/util/virbitmap.h +++ b/src/util/virbitmap.h @@ -25,6 +25,7 @@ # define __BITMAP_H__ # include "internal.h" +# include "viralloc.h" # include <sys/types.h> @@ -44,6 +45,8 @@ virBitmapPtr virBitmapNewEmpty(void) ATTRIBUTE_RETURN_CHECK; */ void virBitmapFree(virBitmapPtr bitmap); +VIR_DEFINE_AUTOPTR_FUNC(virBitmapPtr, virBitmapFree) + /* * Copy all bits from @src to @dst. The bitmap sizes * must be the same -- 1.8.3.1

The include directive for viralloc.h is added in virbitmap.h in the previous patch. --- src/util/virbitmap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index 0cc5292..ef18dad 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -31,7 +31,6 @@ #include <sys/types.h> #include "virbitmap.h" -#include "viralloc.h" #include "virbuffer.h" #include "c-ctype.h" #include "count-one-bits.h" -- 1.8.3.1

By making use of the GCC's __attribute__((cleanup)) handled by VIR_AUTOPTR macro, majority of the calls to *Free functions can be dropped, which in turn leads to getting rid of most of our cleanup sections. --- src/util/virbitmap.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index ef18dad..37e5c0e 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -1202,15 +1202,12 @@ char * virBitmapDataFormat(const void *data, int len) { - virBitmapPtr map = NULL; - char *ret = NULL; + VIR_AUTOPTR(virBitmapPtr) map = NULL; if (!(map = virBitmapNewData(data, len))) return NULL; - ret = virBitmapFormat(map); - virBitmapFree(map); - return ret; + return virBitmapFormat(map); } -- 1.8.3.1
participants (2)
-
Erik Skultety
-
Sukrit Bhatnagar