-
-for ac_func in asprintf crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy
+for ac_func in crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy
do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
fi
-AC_REPLACE_FUNCS([asprintf crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy])
+AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy])
case $host_os in
*/
if (getenv("KRB5_KTNAME") == NULL)
{
- char *kt_path;
+ size_t kt_len = strlen(pg_krb_server_keyfile) + 14;
+ char *kt_path = malloc(kt_len);
- if (asprintf(&kt_path, "KRB5_KTNAME=%s", pg_krb_server_keyfile) < 0)
+ if (!kt_path)
{
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return STATUS_ERROR;
}
+ snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", pg_krb_server_keyfile);
putenv(kt_path);
}
}
}
}
- if (asprintf(&new, "%s/%s", buf, path) < 0)
+ new = malloc(strlen(buf) + strlen(path) + 2);
+ if (!new)
ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
+ sprintf(new, "%s/%s", buf, path);
free(buf);
}
else
out[len] = '\0';
return out;
}
-
-/*
- * asprintf()-like functions around palloc, adapted from
- * http://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/pkgtools/libnbcompat/files/asprintf.c
- */
-
-char *
-psprintf(const char *format, ...)
-{
- va_list ap;
- char *retval;
-
- va_start(ap, format);
- retval = pvsprintf(format, ap);
- va_end(ap);
-
- return retval;
-}
-
-char *
-pvsprintf(const char *format, va_list ap)
-{
- char *buf, *new_buf;
- size_t len;
- int retval;
- va_list ap2;
-
- len = 128;
- buf = palloc(len);
-
- va_copy(ap2, ap);
- retval = vsnprintf(buf, len, format, ap);
- Assert(retval >= 0);
-
- if (retval < len)
- {
- new_buf = repalloc(buf, retval + 1);
- va_end(ap2);
- return new_buf;
- }
-
- len = (size_t)retval + 1;
- pfree(buf);
- buf = palloc(len);
- retval = vsnprintf(buf, len, format, ap2);
- va_end(ap2);
- Assert(retval == len - 1);
- return buf;
-}
char *cmdbuf;
char *bufptr;
size_t slen = strlen(comment_arg);
- int rv;
- rv = asprintf(&cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
- if (rv < 0)
+ cmdbuf = malloc(slen * 2 + 256);
+ if (!cmdbuf)
return fail_lo_xact("\\lo_import", own_transaction);
- bufptr = cmdbuf + rv;
+ sprintf(cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
+ bufptr = cmdbuf + strlen(cmdbuf);
bufptr += PQescapeStringConn(pset.db, bufptr, comment_arg, slen, NULL);
strcpy(bufptr, "'");
override CPPFLAGS := -DFRONTEND $(CPPFLAGS)
LIBS += $(PTHREAD_LIBS)
-OBJS_COMMON = exec.o pgfnames.o relpath.o rmtree.o wait_error.o
+OBJS_COMMON = exec.o pgfnames.o psprintf.o relpath.o rmtree.o wait_error.o
OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o
free(ptr);
}
-int
-pg_asprintf(char **ret, const char *format, ...)
-{
- va_list ap;
- int rc;
-
- va_start(ap, format);
- rc = vasprintf(ret, format, ap);
- va_end(ap);
-
- if (rc < 0)
- {
- fprintf(stderr, _("out of memory\n"));
- exit(EXIT_FAILURE);
- }
-
- return rc;
-}
-
/*
* Frontend emulation of backend memory management functions. Useful for
* programs that compile backend files.
{
return pg_realloc(pointer, size);
}
-
-char *
-psprintf(const char *format, ...)
-{
- va_list ap;
- int rc;
- char *ret;
-
- va_start(ap, format);
- rc = vasprintf(&ret, format, ap);
- va_end(ap);
-
- if (rc < 0)
- {
- fprintf(stderr, _("out of memory\n"));
- exit(EXIT_FAILURE);
- }
-
- return ret;
-}
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * psprintf.c
+ * sprintf into an allocated-on-demand buffer
+ *
+ *
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/common/psprintf.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "utils/memutils.h"
+
+
+static size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
+
+
+/*
+ * psprintf
+ *
+ * Format text data under the control of fmt (an sprintf-style format string)
+ * and return it in an allocated-on-demand buffer. The buffer is allocated
+ * with palloc in the backend, or malloc in frontend builds. Caller is
+ * responsible to free the buffer when no longer needed, if appropriate.
+ *
+ * Errors are not returned to the caller, but are reported via elog(ERROR)
+ * in the backend, or printf-to-stderr-and-exit() in frontend builds.
+ * One should therefore think twice about using this in libpq.
+ */
+char *
+psprintf(const char *fmt,...)
+{
+ size_t len = 128; /* initial assumption about buffer size */
+
+ for (;;)
+ {
+ char *result;
+ va_list args;
+
+ /*
+ * Allocate result buffer. Note that in frontend this maps to malloc
+ * with exit-on-error.
+ */
+ result = (char *) palloc(len);
+
+ /* Try to format the data. */
+ va_start(args, fmt);
+ len = pvsnprintf(result, len, fmt, args);
+ va_end(args);
+
+ if (len == 0)
+ return result; /* success */
+
+ /* Release buffer and loop around to try again with larger len. */
+ pfree(result);
+ }
+}
+
+/*
+ * pvsnprintf
+ *
+ * Attempt to format text data under the control of fmt (an sprintf-style
+ * format string) and insert it into buf (which has length len).
+ *
+ * If successful, return zero. If there's not enough space in buf, return
+ * an estimate of the buffer size needed to succeed (this *must* be more
+ * than "len", else psprintf might loop infinitely).
+ * Other error cases do not return.
+ *
+ * XXX This API is ugly, but there seems no alternative given the C spec's
+ * restrictions on what can portably be done with va_list arguments: you have
+ * to redo va_start before you can rescan the argument list, and we can't do
+ * that from here.
+ */
+static size_t
+pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
+{
+ int nprinted;
+
+ Assert(len > 0);
+
+ errno = 0;
+
+ /*
+ * Assert check here is to catch buggy vsnprintf that overruns the
+ * specified buffer length. Solaris 7 in 64-bit mode is an example of a
+ * platform with such a bug.
+ */
+#ifdef USE_ASSERT_CHECKING
+ buf[len - 1] = '\0';
+#endif
+
+ nprinted = vsnprintf(buf, len, fmt, args);
+
+ Assert(buf[len - 1] == '\0');
+
+ /*
+ * If vsnprintf reports an error other than ENOMEM, fail. The possible
+ * causes of this are not user-facing errors, so elog should be enough.
+ */
+ if (nprinted < 0 && errno != 0 && errno != ENOMEM)
+ {
+#ifndef FRONTEND
+ elog(ERROR, "vsnprintf failed: %m");
+#else
+ fprintf(stderr, "vsnprintf failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+#endif
+ }
+
+ /*
+ * Note: some versions of vsnprintf return the number of chars actually
+ * stored, not the total space needed as C99 specifies. And at least one
+ * returns -1 on failure. Be conservative about believing whether the
+ * print worked.
+ */
+ if (nprinted >= 0 && (size_t) nprinted < len - 1)
+ {
+ /* Success. Note nprinted does not include trailing null. */
+ return 0;
+ }
+
+ if (nprinted >= 0 && (size_t) nprinted > len)
+ {
+ /*
+ * This appears to be a C99-compliant vsnprintf, so believe its
+ * estimate of the required space. (If it's wrong, this code will
+ * still work, but may loop multiple times.) Note that the space
+ * needed should be only nprinted+1 bytes, but we'd better allocate
+ * one more than that so that the test above will succeed next time.
+ *
+ * In the corner case where the required space just barely overflows,
+ * fall through so that we'll error out below (possibly after looping).
+ */
+ if ((size_t) nprinted <= MaxAllocSize - 2)
+ return nprinted + 2;
+ }
+
+ /*
+ * Buffer overrun, and we don't know how much space is needed. Estimate
+ * twice the previous buffer size. If this would overflow, choke. We use
+ * a palloc-oriented overflow limit even when in frontend.
+ */
+ if (len > MaxAllocSize / 2)
+ {
+#ifndef FRONTEND
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+#else
+ fprintf(stderr, _("out of memory\n"));
+ exit(EXIT_FAILURE);
+#endif
+ }
+
+ return len * 2;
+}
+
+
+/*
+ * XXX this is going away shortly.
+ */
+#ifdef FRONTEND
+int
+pg_asprintf(char **ret, const char *fmt, ...)
+{
+ size_t len = 128; /* initial assumption about buffer size */
+
+ for (;;)
+ {
+ char *result;
+ va_list args;
+
+ /*
+ * Allocate result buffer. Note that in frontend this maps to malloc
+ * with exit-on-error.
+ */
+ result = (char *) palloc(len);
+
+ /* Try to format the data. */
+ va_start(args, fmt);
+ len = pvsnprintf(result, len, fmt, args);
+ va_end(args);
+
+ if (len == 0)
+ {
+ *ret = result;
+ return 0;
+ }
+
+ /* Release buffer and loop around to try again with larger len. */
+ pfree(result);
+ }
+}
+#endif
/* Define to 1 if you have the `append_history' function. */
#undef HAVE_APPEND_HISTORY
-/* Define to 1 if you have the `asprintf' function. */
-#undef HAVE_ASPRINTF
-
/* Define to 1 if you have the `cbrt' function. */
#undef HAVE_CBRT
extern int inet_aton(const char *cp, struct in_addr * addr);
#endif
-#ifndef HAVE_ASPRINTF
-extern int asprintf(char **ret, const char *fmt, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
-extern int vasprintf(char **ret, const char *fmt, va_list ap) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
-#endif
-
#if !HAVE_DECL_STRLCAT
extern size_t strlcat(char *dst, const char *src, size_t siz);
#endif
#endif
#endif
-/*
- * Supplement to <stdarg.h>
- */
-
-/* Visual Studios 2012 and earlier don't have va_copy() */
-#if defined(_MSC_VER) && _MSC_VER <= 1700
-#define va_copy(dest, src) ((dest) = (src))
-#endif
-
/*
* Supplement to <sys/types.h>.
*
extern char *pstrdup(const char *in);
extern char *pnstrdup(const char *in, Size len);
+
+/* sprintf into a palloc'd buffer */
+extern char *psprintf(const char *fmt,...)
+__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+
+/* basic memory allocation functions */
extern void *palloc(Size size);
extern void *palloc0(Size size);
extern void pfree(void *pointer);
extern void *repalloc(void *pointer, Size size);
-extern char *psprintf(const char *format, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
-extern char *pvsprintf(const char *format, va_list ap) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 0)));
#endif /* PALLOC_H */
{
for (j = 0; times[j]; j++)
{
- char* t;
- if (asprintf(&t, "%s %s", dates[i], times[j]) < 0)
- abort();
+ int length = strlen(dates[i])
+ + 1
+ + strlen(times[j])
+ + 1;
+ char* t = malloc(length);
+ sprintf(t, "%s %s", dates[i], times[j]);
ts1 = PGTYPEStimestamp_from_asc(t, NULL);
text = PGTYPEStimestamp_to_asc(ts1);
if (i != 19 || j != 3) /* timestamp as integer or double differ for this case */
{
for (j = 0; times[j]; j++)
{
- char* t;
- if (asprintf(&t, "%s %s", dates[i], times[j]) < 0)
- abort();
+ int length = strlen(dates[i])
+ + 1
+ + strlen(times[j])
+ + 1;
+ char* t = malloc(length);
+ sprintf(t, "%s %s", dates[i], times[j]);
ts1 = PGTYPEStimestamp_from_asc(t, NULL);
text = PGTYPEStimestamp_to_asc(ts1);
if (i != 19 || j != 3) /* timestamp as integer or double differ for this case */
{
OM_uint32 maj_stat,
min_stat;
+ int maxlen;
gss_buffer_desc temp_gbuf;
if (!(conn->pghost && conn->pghost[0] != '\0'))
* Import service principal name so the proper ticket can be acquired by
* the GSSAPI system.
*/
- if (asprintf((char **)&temp_gbuf.value, "%s@%s",
- conn->krbsrvname, conn->pghost) < 0)
+ maxlen = NI_MAXHOST + strlen(conn->krbsrvname) + 2;
+ temp_gbuf.value = (char *) malloc(maxlen);
+ if (!temp_gbuf.value)
{
printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory"));
+ libpq_gettext("out of memory\n"));
return STATUS_ERROR;
}
-
+ snprintf(temp_gbuf.value, maxlen, "%s@%s",
+ conn->krbsrvname, conn->pghost);
temp_gbuf.length = strlen(temp_gbuf.value);
maj_stat = gss_import_name(&min_stat, &temp_gbuf,
libpq_gettext("host name must be specified\n"));
return STATUS_ERROR;
}
- if (asprintf(&conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost) < 0)
+ conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
+ if (!conn->sspitarget)
{
printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
return STATUS_ERROR;
}
+ sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost);
/*
* Indicate that we're in SSPI authentication mode to make sure that
+++ /dev/null
-/* src/port/asprintf.c */
-
-/* $NetBSD: asprintf.c,v 1.3 2012/07/02 16:02:53 joerg Exp $ */
-
-/*-
- * Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "c.h"
-
-#define HAVE_VA_COPY 1
-
-int
-asprintf(char **ret, const char *fmt, ...)
-{
- va_list ap;
- int retval;
-
- va_start(ap, fmt);
- retval = vasprintf(ret, fmt, ap);
- va_end(ap);
-
- return retval;
-}
-
-int
-vasprintf(char **ret, const char *fmt, va_list ap)
-{
- char *buf, *new_buf;
- size_t len;
- int retval;
- va_list ap2;
-
- len = 128;
- buf = malloc(len);
- if (buf == NULL) {
- *ret = NULL;
- return -1;
- }
-
-#if defined(HAVE_VA_COPY)
- va_copy(ap2, ap);
-#define my_va_end(ap2) va_end(ap2)
-#elif defined(HAVE___BUILTIN_VA_COPY)
- __builtin_va_copy(ap2, ap);
-#define my_va_end(ap2) __builtin_va_end(ap2)
-#else
- ap2 = ap;
-#define my_va_end(ap2) do {} while (0)
-#endif
- retval = vsnprintf(buf, len, fmt, ap);
- if (retval < 0) {
- free(buf);
- *ret = NULL;
- va_end(ap2);
- return -1;
- }
-
- if (retval < len) {
- new_buf = realloc(buf, retval + 1);
- if (new_buf == NULL)
- *ret = buf;
- else
- *ret = new_buf;
- my_va_end(ap2);
- return retval;
- }
-
- len = (size_t)retval + 1;
- free(buf);
- buf = malloc(len);
- if (buf == NULL) {
- *ret = NULL;
- my_va_end(ap2);
- return -1;
- }
- retval = vsnprintf(buf, len, fmt, ap2);
- my_va_end(ap2);
- if (retval != len - 1) {
- free(buf);
- *ret = NULL;
- return -1;
- }
- *ret = buf;
- return retval;
-}
$solution = CreateSolution($vsVersion, $config);
our @pgportfiles = qw(
- asprintf.c chklocale.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c random.c
+ chklocale.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c random.c
srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
pgcheckdir.c pg_crc.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c
win32error.c win32setlocale.c);
our @pgcommonallfiles = qw(
- exec.c pgfnames.c relpath.c rmtree.c wait_error.c);
+ exec.c pgfnames.c psprintf.c relpath.c rmtree.c wait_error.c);
our @pgcommonfrontendfiles = (@pgcommonallfiles, qw(fe_memutils.c));