krb5 commit: Bump bundled libverto for 0.3.0 release
Greg Hudson
ghudson at mit.edu
Mon Sep 4 11:58:03 EDT 2017
https://github.com/krb5/krb5/commit/e690f1b5691edf87b6c8a92eab95db5cfaee01d3
commit e690f1b5691edf87b6c8a92eab95db5cfaee01d3
Author: Robbie Harwood <rharwood at redhat.com>
Date: Thu Aug 31 16:49:17 2017 -0400
Bump bundled libverto for 0.3.0 release
Local changes:
- Update upstream URL for fedorahosted deprecation.
- Add verto_cleanup() to exports.
Upstream changes:
- Strict c89 compliance.
- Remove local asprintf() implementation.
- Fix memleak when memory allocator is realloc().
- Fix leaks of filenames during load.
- Fix many unused variable warnings.
- Factor out mutability check.
- Properly handle _GNU_SOURCE checking.
ticket: 8612 (new)
src/util/verto/README | 2 +-
src/util/verto/libverto.exports | 1 +
src/util/verto/verto-k5ev.c | 5 ++
src/util/verto/verto-libev.c | 5 ++
src/util/verto/verto.c | 131 ++++++++++++++++++++++++++++-----------
src/util/verto/verto.h | 20 +++++-
6 files changed, 125 insertions(+), 39 deletions(-)
diff --git a/src/util/verto/README b/src/util/verto/README
index 6de645f..a3dab83 100644
--- a/src/util/verto/README
+++ b/src/util/verto/README
@@ -36,5 +36,5 @@ BUILTIN_MODULE define.
The libverto and libev upstream project pages are at:
- https://fedorahosted.org/libverto/
+ https://github.com/latchset/libverto/
http://software.schmorp.de/pkg/libev.html
diff --git a/src/util/verto/libverto.exports b/src/util/verto/libverto.exports
index ecba76a..3745d50 100644
--- a/src/util/verto/libverto.exports
+++ b/src/util/verto/libverto.exports
@@ -4,6 +4,7 @@ verto_add_io
verto_add_signal
verto_add_timeout
verto_break
+verto_cleanup
verto_convert_module
verto_default
verto_del
diff --git a/src/util/verto/verto-k5ev.c b/src/util/verto/verto-k5ev.c
index 3f08275..a390af7 100644
--- a/src/util/verto/verto-k5ev.c
+++ b/src/util/verto/verto-k5ev.c
@@ -114,6 +114,11 @@ libev_callback(EV_P_ ev_watcher *w, int revents)
{
verto_ev_flag state = VERTO_EV_FLAG_NONE;
+#if EV_MULTIPLICITY
+ /* Match the check in ev.h, which doesn't mark this unused */
+ (void) EV_A;
+#endif
+
if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
diff --git a/src/util/verto/verto-libev.c b/src/util/verto/verto-libev.c
index 9c7c324..99256a2 100644
--- a/src/util/verto/verto-libev.c
+++ b/src/util/verto/verto-libev.c
@@ -80,6 +80,11 @@ libev_callback(EV_P_ ev_watcher *w, int revents)
{
verto_ev_flag state = VERTO_EV_FLAG_NONE;
+#if EV_MULTIPLICITY
+ /* Match the check in ev.h, which doesn't mark this unused */
+ (void) EV_A;
+#endif
+
if (verto_get_type(w->data)== VERTO_EV_TYPE_CHILD)
verto_set_proc_status(w->data, ((ev_child*) w)->rstatus);
diff --git a/src/util/verto/verto.c b/src/util/verto/verto.c
index 44ea437..71eaffa 100644
--- a/src/util/verto/verto.c
+++ b/src/util/verto/verto.c
@@ -22,8 +22,6 @@
* SOFTWARE.
*/
-#define _GNU_SOURCE /* For asprintf() */
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -45,6 +43,8 @@
#define _str(s) # s
#define __str(s) _str(s)
+#define MUTABLE(flags) (flags & _VERTO_EV_FLAG_MUTABLE_MASK)
+
/* Remove flags we can emulate */
#define make_actual(flags) ((flags) & ~(VERTO_EV_FLAG_PERSIST|VERTO_EV_FLAG_IO_CLOSE_FD))
@@ -103,7 +103,7 @@ struct module_record {
/*
* This symbol can be used when embedding verto.c in a library along with a
* built-in private module, to preload the module instead of dynamically
- * linking it in later. Define to verto_module_table_<modulename>.
+ * linking it in later. Define to <modulename>.
*/
extern verto_module MODTABLE(BUILTIN_MODULE);
static module_record builtin_record = {
@@ -119,12 +119,43 @@ static int resize_cb_hierarchical;
#ifdef HAVE_PTHREAD
static pthread_mutex_t loaded_modules_mutex = PTHREAD_MUTEX_INITIALIZER;
-#define mutex_lock(x) pthread_mutex_lock(x)
-#define mutex_unlock(x) pthread_mutex_unlock(x)
-#else
+
+#ifndef NDEBUG
+#define mutex_lock(x) { \
+ int c = pthread_mutex_lock(x); \
+ if (c != 0) { \
+ fprintf(stderr, "pthread_mutex_lock returned %d (%s) in %s", \
+ c, strerror(c), __FUNCTION__); \
+ } \
+ assert(c == 0); \
+ }
+#define mutex_unlock(x) { \
+ int c = pthread_mutex_unlock(x); \
+ if (c != 0) { \
+ fprintf(stderr, "pthread_mutex_unlock returned %d (%s) in %s", \
+ c, strerror(c), __FUNCTION__); \
+ } \
+ assert(c == 0); \
+ }
+#define mutex_destroy(x) { \
+ int c = pthread_mutex_destroy(x); \
+ if (c != 0) { \
+ fprintf(stderr, "pthread_mutex_destroy returned %d (%s) in %s", \
+ c, strerror(c), __FUNCTION__); \
+ } \
+ assert(c == 0); \
+ }
+#else /* NDEBUG */
+#define mutex_lock pthread_mutex_lock
+#define mutex_unlock pthread_mutex_unlock
+#define mutex_destroy pthread_mutex_destroy
+#endif /* NDEBUG */
+
+#else /* HAVE_PTHREAD */
#define mutex_lock(x)
#define mutex_unlock(x)
-#endif
+#define mutex_destroy(x)
+#endif /* HAVE_PTHREAD */
#define vfree(mem) vresize(mem, 0)
static void *
@@ -132,34 +163,35 @@ vresize(void *mem, size_t size)
{
if (!resize_cb)
resize_cb = &realloc;
+ if (size == 0 && resize_cb == &realloc) {
+ /* Avoid memleak as realloc(X, 0) can return a free-able pointer. */
+ free(mem);
+ return NULL;
+ }
return (*resize_cb)(mem, size);
}
#ifndef BUILTIN_MODULE
-static int
-int_vasprintf(char **strp, const char *fmt, va_list ap) {
- va_list apc;
- int size = 0;
-
- va_copy(apc, ap);
- size = vsnprintf(NULL, 0, fmt, apc);
- va_end(apc);
+static char *
+string_aconcat(const char *first, const char *second, const char *third) {
+ char *ret;
+ size_t len;
- if (size <= 0 || !(*strp = malloc(size + 1)))
- return -1;
+ len = strlen(first) + strlen(second);
+ if (third)
+ len += strlen(third);
- return vsnprintf(*strp, size + 1, fmt, ap);
-}
+ ret = malloc(len + 1);
+ if (!ret)
+ return NULL;
-static int
-int_asprintf(char **strp, const char *fmt, ...) {
- va_list ap;
- int size = 0;
+ strncpy(ret, first, strlen(first));
+ strncpy(ret + strlen(first), second, strlen(second));
+ if (third)
+ strncpy(ret + strlen(first) + strlen(second), third, strlen(third));
- va_start(ap, fmt);
- size = int_vasprintf(strp, fmt, ap);
- va_end(ap);
- return size;
+ ret[len] = '\0';
+ return ret;
}
static char *
@@ -185,8 +217,7 @@ int_get_table_name_from_filename(const char *filename)
if (tmp) {
if (strchr(tmp+1, '.')) {
*strchr(tmp+1, '.') = '\0';
- if (int_asprintf(&tmp, "%s%s", __str(VERTO_MODULE_TABLE()), tmp + 1) < 0)
- tmp = NULL;
+ tmp = string_aconcat(__str(VERTO_MODULE_TABLE()), tmp + 1, NULL);
} else
tmp = NULL;
}
@@ -217,7 +248,7 @@ shouldload(void *symb, void *misc, char **err)
if (table->symb && data->reqsym
&& !module_symbol_is_present(NULL, table->symb)) {
if (err)
- int_asprintf(err, "Symbol not found: %s!", table->symb);
+ *err = string_aconcat("Symbol not found: ", table->symb, "!");
return 0;
}
@@ -265,6 +296,7 @@ do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes,
tblname = int_get_table_name_from_filename(filename);
if (!tblname) {
free(tblname);
+ free(tmp->filename);
vfree(tmp);
return 0;
}
@@ -278,6 +310,7 @@ do_load_file(const char *filename, int reqsym, verto_ev_type reqtypes,
free(error);
module_close(tmp->dll);
free(tblname);
+ free(tmp->filename);
vfree(tmp);
return 0;
}
@@ -324,7 +357,8 @@ do_load_dir(const char *dirname, const char *prefix, const char *suffix,
if (flen < slen || strcmp(ent->d_name + flen - slen, suffix))
continue;
- if (int_asprintf(&tmp, "%s/%s", dirname, ent->d_name) < 0)
+ tmp = string_aconcat(dirname, "/", ent->d_name);
+ if (!tmp)
continue;
success = do_load_file(tmp, reqsym, reqtypes, record);
@@ -401,8 +435,8 @@ load_module(const char *impl, verto_ev_type reqtypes, module_record **record)
success = do_load_file(impl, 0, reqtypes, record);
if (!success) {
/* Try to do a load by the name */
- tmp = NULL;
- if (int_asprintf(&tmp, "%s%s%s", prefix, impl, suffix) > 0) {
+ tmp = string_aconcat(prefix, impl, suffix);
+ if (tmp) {
success = do_load_file(tmp, 0, reqtypes, record);
free(tmp);
}
@@ -494,6 +528,8 @@ remove_ev(verto_ev **origin, verto_ev *item)
static void
signal_ignore(verto_ctx *ctx, verto_ev *ev)
{
+ (void) ctx;
+ (void) ev;
}
verto_ctx *
@@ -566,6 +602,25 @@ verto_free(verto_ctx *ctx)
}
void
+verto_cleanup(void)
+{
+ module_record *record;
+
+ mutex_lock(&loaded_modules_mutex);
+
+ for (record = loaded_modules; record; record = record->next) {
+ module_close(record->dll);
+ free(record->filename);
+ }
+
+ vfree(loaded_modules);
+ loaded_modules = NULL;
+
+ mutex_unlock(&loaded_modules_mutex);
+ mutex_destroy(&loaded_modules_mutex);
+}
+
+void
verto_run(verto_ctx *ctx)
{
if (!ctx)
@@ -752,8 +807,12 @@ verto_set_flags(verto_ev *ev, verto_ev_flag flags)
if (!ev)
return;
+ /* No modification is needed, so do nothing. */
+ if (MUTABLE(ev->flags) == MUTABLE(flags))
+ return;
+
ev->flags &= ~_VERTO_EV_FLAG_MUTABLE_MASK;
- ev->flags |= flags & _VERTO_EV_FLAG_MUTABLE_MASK;
+ ev->flags |= MUTABLE(flags);
/* If setting flags isn't supported, just rebuild the event */
if (!ev->ctx->module->funcs->ctx_set_flags) {
@@ -765,7 +824,7 @@ verto_set_flags(verto_ev *ev, verto_ev_flag flags)
}
ev->actual &= ~_VERTO_EV_FLAG_MUTABLE_MASK;
- ev->actual |= flags & _VERTO_EV_FLAG_MUTABLE_MASK;
+ ev->actual |= MUTABLE(flags);
ev->ctx->module->funcs->ctx_set_flags(ev->ctx->ctx, ev, ev->ev);
}
@@ -861,7 +920,7 @@ verto_convert_module(const verto_module *module, int deflt, verto_mod_ctx *mctx)
module_record *mr;
if (!module)
- goto error;
+ return NULL;
if (deflt) {
mutex_lock(&loaded_modules_mutex);
diff --git a/src/util/verto/verto.h b/src/util/verto/verto.h
index 5540367..55c5836 100644
--- a/src/util/verto/verto.h
+++ b/src/util/verto/verto.h
@@ -33,6 +33,7 @@
typedef HANDLE verto_proc;
typedef DWORD verto_proc_status;
#else
+#include <sys/types.h>
typedef pid_t verto_proc;
typedef int verto_proc_status;
#endif
@@ -195,7 +196,8 @@ verto_set_default(const char *impl, verto_ev_type reqtypes);
* @see verto_add_idle()
* @see verto_add_signal()
* @see verto_add_child()
- * @param resize The allocator to use (behaves like realloc())
+ * @param resize The allocator to use (behaves like realloc();
+ * resize(ptr, 0) must free memory at ptr.)
* @param hierarchical Zero if the allocator is not hierarchical
*/
int
@@ -216,6 +218,19 @@ void
verto_free(verto_ctx *ctx);
/**
+ * Frees global state.
+ *
+ * Remove and free all allocated global state. Call only when no further
+ * contexts exist and all threads have exited.
+ *
+ * @see verto_new()
+ * @see verto_free()
+ * @see verto_default()
+ */
+void
+verto_cleanup(void);
+
+/**
* Run the verto_ctx forever, or at least until verto_break() is called.
*
* @see verto_break()
@@ -444,7 +459,8 @@ verto_get_flags(const verto_ev *ev);
* Sets the flags associated with the given verto_ev.
*
* See _VERTO_EV_FLAG_MUTABLE_MASK for the flags that can be changed
- * with this function. All others will be ignored.
+ * with this function. All others will be ignored. If the flags specified
+ * are the same as the flags the event already has, this function is a no-op.
*
* @see verto_add_io()
* @see verto_add_timeout()
More information about the cvs-krb5
mailing list