commit: 4616f8f809ee8566904ca37f2b8bf0409a487475
Author: William Hubbs <w.d.hubbs <AT> gmail <DOT> com>
AuthorDate: Fri Feb 9 22:27:12 2018 +0000
Commit: William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Fri Feb 9 22:27:12 2018 +0000
URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=4616f8f8
helpers.h: add xasprintf function
This is our own version of asprintf(). This original code was written by
Mike Frysinger, and I was able to modify it to use our memory helper
functions.
We need a version of this code because it is not available on glibc at
least without defining _GNU_SOURCE, and I would rather not do that.
This is the first step in improving string handling in OpenRC for #207.
src/includes/helpers.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/src/includes/helpers.h b/src/includes/helpers.h
index 8d8b16e8..3657ee74 100644
--- a/src/includes/helpers.h
+++ b/src/includes/helpers.h
@@ -53,6 +53,7 @@
} while (/* CONSTCOND */ 0)
#endif
+#include <stdarg.h>
#include <stdbool.h>
#include <sys/stat.h>
@@ -123,4 +124,52 @@ _unused static bool existss(const char *pathname)
return (stat(pathname, &buf) == 0 && buf.st_size != 0);
}
+/*
+ * This is an OpenRC specific version of the asprintf() function.
+ * We do this to avoid defining the _GNU_SOURCE feature test macro on
+ * glibc systems and to insure that we have a consistent function across
+ * platforms. This also allows us to call our xmalloc and xrealloc
+ * functions to handle memory allocation.
+ * this function was originally written by Mike Frysinger.
+ */
+_unused static int xasprintf(char **strp, const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+ int memlen;
+ char *ret;
+
+ /*
+ * Start with a buffer size that should cover the vast majority of uses
+ * (path construction).
+ */
+ memlen = 4096;
+ ret = xmalloc(memlen);
+
+ va_start(ap, fmt);
+ len = vsnprintf(ret, memlen, fmt, ap);
+ va_end(ap);
+ if (len >= memlen) {
+ /*
+ * Output was truncated, so increase buffer to exactly what we
need.
+ */
+ memlen = len + 1;
+ ret = xrealloc(ret, memlen);
+ va_start(ap, fmt);
+ len = vsnprintf(ret, len + 1, fmt, ap);
+ va_end(ap);
+ if (len >= memlen) {
+ /* Give up! */
+ free(ret);
+ return -1;
+ }
+ }
+ if (len < 0) {
+ free(ret);
+ return -1;
+ }
+ *strp = ret;
+ return len;
+}
+
#endif