Hi Alvaro,
Am Montag, den 05.03.2018, 12:48 -0300 schrieb Alvaro Herrera:
> Please make ctx->discard a bool, not an int.
Ok, done so now. I forgot to mention that in the earlier resubmission,
but I had a look at the other pg_backup_*.c files and isSpecialScript
and hasSeek were ints as well, so I opted for that.
> You can initialize it like this:
> ctx->discard = strcmp(ctx->directory, DEVNULL) == 0;
Thanks, changed it thusly.
> Why do you change the mode to create directory to 0711 from 0700?
Oh wow, that was either a mistype in vim or a very old test hack, thanks
for spotting it.
> You have a cuddled "else" in the last hunk. Please uncuddle.
Done so now, hopefully.
Thanks again for the review, a new version is attached.
Michael
--
Michael Banck
Projektleiter / Senior Berater
Tel.: +49 2166 9901-171
Fax: +49 2166 9901-100
Email: michael.ba...@credativ.de
credativ GmbH, HRB Mönchengladbach 12080
USt-ID-Nummer: DE204566209
Trompeterallee 108, 41189 Mönchengladbach
Geschäftsführung: Dr. Michael Meskes, Jörg Folz, Sascha Heuer
diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c
index a96da15dc1..0953290069 100644
--- a/src/bin/pg_dump/compress_io.c
+++ b/src/bin/pg_dump/compress_io.c
@@ -512,7 +512,10 @@ cfopen_write(const char *path, const char *mode, int compression)
#ifdef HAVE_LIBZ
char *fname;
- fname = psprintf("%s.gz", path);
+ if (strcmp(path, DEVNULL) != 0)
+ fname = psprintf("%s.gz", path);
+ else
+ fname = pg_strdup(path);
fp = cfopen(fname, mode, compression);
free_keep_errno(fname);
#else
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
index 4aabb40f59..3b77023d77 100644
--- a/src/bin/pg_dump/pg_backup_directory.c
+++ b/src/bin/pg_dump/pg_backup_directory.c
@@ -54,6 +54,7 @@ typedef struct
cfp *blobsTocFH; /* file handle for blobs.toc */
ParallelState *pstate; /* for parallel backup / restore */
+ bool discard; /* target is DEVNULL */
} lclContext;
typedef struct
@@ -158,6 +159,8 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
ctx->directory = AH->fSpec;
+ ctx->discard = strcmp(ctx->directory, DEVNULL) == 0;
+
if (AH->mode == archModeWrite)
{
struct stat st;
@@ -192,9 +195,15 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
}
}
- if (!is_empty && mkdir(ctx->directory, 0700) < 0)
- exit_horribly(modulename, "could not create directory \"%s\": %s\n",
- ctx->directory, strerror(errno));
+ /*
+ * Create the output directory, unless it exists already and is empty.
+ * If we are discarding output to the null device, we must not
+ * create it.
+ */
+ if (!is_empty && !ctx->discard)
+ if (mkdir(ctx->directory, 0700) < 0)
+ exit_horribly(modulename, "could not create directory \"%s\": %s\n",
+ ctx->directory, strerror(errno));
}
else
{ /* Read Mode */
@@ -602,8 +611,10 @@ _CloseArchive(ArchiveHandle *AH)
/*
* In directory mode, there is no need to sync all the entries
* individually. Just recurse once through all the files generated.
+ * If we are discarding output to the null device, it does not
+ * need syncing and would emit a warning if we did.
*/
- if (AH->dosync)
+ if (AH->dosync && !ctx->discard)
fsync_dir_recurse(ctx->directory, progname);
}
AH->FH = NULL;
@@ -659,7 +670,14 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
lclContext *ctx = (lclContext *) AH->formatData;
char fname[MAXPGPATH];
- snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
+ /*
+ * If we are discarding output to the null device, just use that as
+ * fname.
+ */
+ if (ctx->discard)
+ snprintf(fname, MAXPGPATH, DEVNULL);
+ else
+ snprintf(fname, MAXPGPATH, "%s/blob_%u.dat", ctx->directory, oid);
ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression);
@@ -721,9 +739,18 @@ setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename)
if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH)
exit_horribly(modulename, "file name too long: \"%s\"\n", dname);
- strcpy(buf, dname);
- strcat(buf, "/");
- strcat(buf, relativeFilename);
+ /*
+ * If we are discarding output to the null device, we cannot set a file
+ * path and just set the buffer to the null device.
+ */
+ if (ctx->discard)
+ strcpy(buf, DEVNULL);
+ else
+ {
+ strcpy(buf, dname);
+ strcat(buf, "/");
+ strcat(buf, relativeFilename);
+ }
}
/*