commit: abb8d4dd35eeeddb691ebd7d97ced8b76679026e
parent: 4d2eb6d93ada819a0a86284d76e85fe370ebb81b
author: Tim Sedlmeyer <tim@sedlmeyer.org>
date: Sun, 3 Jun 2018 08:54:12 -0400
Add check for asprintf and portable implementation
4 files changed, 133 insertions(+), 7 deletions(-)
diff --git a/asprintf.c b/asprintf.c
@@ -0,0 +1,98 @@
+/*
+ * 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 "pconfig.h"
+
+#ifndef HAVE_ASPRINTF
+
+#include <errno.h>
+#include <limits.h> /* for INT_MAX */
+#include <stdarg.h>
+#include <stdio.h> /* for vsnprintf */
+#include <stdlib.h>
+
+#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;
+ va_list ap2;
+ char *string, *newstr;
+ size_t len;
+
+ if ((string = malloc(INIT_SZ)) == NULL)
+ goto fail;
+
+ VA_COPY(ap2, ap);
+ ret = vsnprintf(string, INIT_SZ, fmt, ap2);
+ va_end(ap2);
+ if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
+ *str = string;
+ } else if (ret == INT_MAX || ret < 0) { /* Bad length */
+ free(string);
+ 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;
+ }
+ VA_COPY(ap2, ap);
+ ret = vsnprintf(newstr, len, fmt, ap2);
+ va_end(ap2);
+ if (ret < 0 || (size_t)ret >= len) { /* failed with realloc'ed string */
+ free(newstr);
+ goto fail;
+ }
+ *str = newstr;
+ }
+ return (ret);
+
+fail:
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+}
+
+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
diff --git a/configure b/configure
@@ -3,6 +3,21 @@
# This configure script written by Brian Callahan <bcallah@openbsd.org>
# and released into the Public Domain.
+asprintfcheck() {
+ cat << EOF > conftest.c
+#include <stdio.h>
+int main(void){asprintf(NULL,NULL);return 0;}
+EOF
+ $cc $tflags -o conftest conftest.c > /dev/null 2>&1
+ if [ $? -eq 0 ] ; then
+ rm -f conftest conftest.c
+ return 0
+ else
+ rm -f conftest conftest.c
+ return 1
+ fi
+}
+
cccheck() {
if [ ! -z "$CC" ] ; then
cat << EOF > conftest.c
@@ -436,6 +451,15 @@ else
fi
fi
+printf "checking for asprintf... "
+asprintfcheck
+if [ $? -eq 0 ] ; then
+ echo "#define HAVE_ASPRINTF" >> pconfig.h
+ echo "yes"
+else
+ echo "no"
+fi
+
printf "checking for confstr... "
confstrcheck
if [ $? -eq 0 ] ; then
@@ -572,11 +596,11 @@ PREFIX = $prefix
MANDIR = $mandir
PROG = $instprog
-OBJS = alloc.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o \\
- exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o \\
- path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o \\
- confstr.o reallocarray.o siglist.o signame.o strlcat.o strlcpy.o \\
- strtonum.o unvis.o vis.o
+OBJS = alloc.o asprintf.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o \\
+ emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o \\
+ main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o \\
+ version.o vi.o confstr.o reallocarray.o siglist.o signame.o \\
+ strlcat.o strlcpy.o strtonum.o unvis.o vis.o
ETS = \`grep -w \${PREFIX}/bin/\${PROG} /etc/shells > /dev/null; \\
[ \$\$? -ne 0 ] && echo "\${PREFIX}/bin/\${PROG}" >> /etc/shells\`
diff --git a/portable.h b/portable.h
@@ -127,6 +127,10 @@
* Prototypes
*/
+#ifndef HAVE_ASPRINTF
+int asprintf(char **str, const char *fmt, ...);
+#endif /* !HAVE_ASPRINTF */
+
#ifndef HAVE_CONFSTR
size_t confstr(int, char *, size_t);
#endif /* !HAVE_CONFSTR */
diff --git a/rescue.sh b/rescue.sh
@@ -117,5 +117,5 @@ cc -DEMACS -DVI -o unvis.o -c unvis.c
echo cc -DEMACS -DVI -o vis.o -c vis.c
cc -DEMACS -DVI -o vis.o -c vis.c
-echo cc -o oksh alloc.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o confstr.o reallocarray.o strtonum.o siglist.o signame.o strlcat.o strlcpy.o unvis.o vis.o -lc
-cc -o oksh alloc.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o confstr.o reallocarray.o strtonum.o siglist.o signame.o strlcat.o strlcpy.o unvis.o vis.o -lc
+echo cc -o oksh alloc.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o asprintf.o confstr.o reallocarray.o strtonum.o siglist.o signame.o strlcat.o strlcpy.o unvis.o vis.o -lc
+cc -o oksh alloc.o asprintf.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o version.o vi.o asprintf.o confstr.o reallocarray.o strtonum.o siglist.o signame.o strlcat.o strlcpy.o unvis.o vis.o -lc