aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWilliam Hubbs <w.d.hubbs@gmail.com>2018-02-09 16:27:12 -0600
committerWilliam Hubbs <w.d.hubbs@gmail.com>2018-02-09 16:27:12 -0600
commit4616f8f809ee8566904ca37f2b8bf0409a487475 (patch)
tree77fccbcaf254f3ad840ecfea2f1f4a5b43a33078 /src
parent287d71bd2591ddec73efe356db081020e65cd922 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/includes/helpers.h49
1 files changed, 49 insertions, 0 deletions
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