summaryrefslogtreecommitdiff
path: root/openbsd-compat/bsd-asprintf.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-11-24 19:58:19 +1100
committerDamien Miller <djm@mindrot.org>2005-11-24 19:58:19 +1100
commit57f3915b5513495b11e7052df0260c7896b7b612 (patch)
tree88e15971a1f626cb8ef3ff18d8e9697fef8c2cef /openbsd-compat/bsd-asprintf.c
parentefc17470e0548dae4b6ffc34370ad15562d83239 (diff)
downloadopenssh-git-57f3915b5513495b11e7052df0260c7896b7b612.tar.gz
- (djm) [configure.ac openbsd-compat/Makefile.in openbsd-compat/bsd-asprintf.c
openbsd-compat/bsd-snprintf.c openbsd-compat/openbsd-compat.h] Add an asprintf() implementation, after syncing our {v,}snprintf() implementation with some extra fixes from Samba's version. With help and debugging from dtucker and tim; ok dtucker@
Diffstat (limited to 'openbsd-compat/bsd-asprintf.c')
-rw-r--r--openbsd-compat/bsd-asprintf.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/openbsd-compat/bsd-asprintf.c b/openbsd-compat/bsd-asprintf.c
new file mode 100644
index 00000000..5ca01f80
--- /dev/null
+++ b/openbsd-compat/bsd-asprintf.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2004 Darren Tucker.
+ *
+ * Based originally on asprintf.c from OpenBSD:
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifndef HAVE_VASPRINTF
+
+#ifndef VA_COPY
+# ifdef HAVE_VA_COPY
+# define VA_COPY(dest, src) va_copy(dest, src)
+# else
+# ifdef HAVE___VA_COPY
+# define VA_COPY(dest, src) __va_copy(dest, src)
+# else
+# define VA_COPY(dest, src) (dest) = (src)
+# endif
+# endif
+#endif
+
+#define INIT_SZ 128
+
+int vasprintf(char **str, const char *fmt, va_list ap)
+{
+ int ret = -1;
+ va_list ap2;
+ char *string, *newstr;
+ size_t len;
+
+ VA_COPY(ap2, ap);
+ if ((string = malloc(INIT_SZ)) == NULL)
+ goto fail;
+
+ ret = vsnprintf(string, INIT_SZ, fmt, ap2);
+ if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
+ *str = string;
+ } else if (ret == INT_MAX) { /* shouldn't happen */
+ goto fail;
+ } else { /* bigger than initial, realloc allowing for nul */
+ len = (size_t)ret + 1;
+ if ((newstr = realloc(string, len)) == NULL) {
+ free(string);
+ goto fail;
+ } else {
+ va_end(ap2);
+ VA_COPY(ap2, ap);
+ ret = vsnprintf(newstr, len, fmt, ap2);
+ if (ret >= 0 && (size_t)ret < len) {
+ *str = newstr;
+ } else { /* failed with realloc'ed string, give up */
+ free(newstr);
+ goto fail;
+ }
+ }
+ }
+ va_end(ap2);
+ return (ret);
+
+fail:
+ *str = NULL;
+ errno = ENOMEM;
+ va_end(ap2);
+ return (-1);
+}
+#endif
+
+#ifndef HAVE_ASPRINTF
+int asprintf(char **str, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ *str = NULL;
+ va_start(ap, fmt);
+ ret = vasprintf(str, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+#endif