diff options
Diffstat (limited to 'src/bin/pg_dump/pg_backup_tar.c')
-rw-r--r-- | src/bin/pg_dump/pg_backup_tar.c | 44 |
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 |