aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/pg_backup_tar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_dump/pg_backup_tar.c')
-rw-r--r--src/bin/pg_dump/pg_backup_tar.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 2358b9d160c..06005ae8682 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -996,33 +996,33 @@ _EndBlobs(ArchiveHandle *AH, TocEntry *te)
static int
tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...)
{
- char *p = NULL;
- va_list ap;
- size_t bSize = strlen(fmt) + 256; /* Should be enough */
- int cnt = -1;
-
- /*
- * This is paranoid: deal with the possibility that vsnprintf is willing
- * to ignore trailing null
- */
+ char *p;
+ size_t len = 128; /* initial assumption about buffer size */
+ size_t cnt;
- /*
- * or returns > 0 even if string does not fit. It may be the case that it
- * returns cnt = bufsize
- */
- while (cnt < 0 || cnt >= (bSize - 1))
+ for (;;)
{
- if (p != NULL)
- free(p);
- bSize *= 2;
- p = (char *) pg_malloc(bSize);
- va_start(ap, fmt);
- cnt = vsnprintf(p, bSize, fmt, ap);
- va_end(ap);
+ va_list args;
+
+ /* Allocate work buffer. */
+ p = (char *) pg_malloc(len);
+
+ /* Try to format the data. */
+ va_start(args, fmt);
+ cnt = pvsnprintf(p, len, fmt, args);
+ va_end(args);
+
+ if (cnt < len)
+ break; /* success */
+
+ /* Release buffer and loop around to try again with larger len. */
+ free(p);
+ len = cnt;
}
+
cnt = tarWrite(p, cnt, th);
free(p);
- return cnt;
+ return (int) cnt;
}
bool