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

Reply via email to