aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2015-07-07 12:47:44 +0200
committerAndres Freund <andres@anarazel.de>2015-07-07 13:07:50 +0200
commit1790b35baf52fff7f670f7cc1159a1b40b36e701 (patch)
tree94b106e36abc8b7a091faf6d1a81dd53cca0f0cc
parent0471894a6f01007752abd37ca493ed371a720bdd (diff)
downloadpostgresql-1790b35baf52fff7f670f7cc1159a1b40b36e701.tar.gz
postgresql-1790b35baf52fff7f670f7cc1159a1b40b36e701.zip
Fix pg_recvlogical not to fsync output when it's a tty or pipe.
The previous coding tried to handle possible failures when fsyncing a tty or pipe fd by accepting EINVAL - but apparently some platforms (windows, OSX) don't reliably return that. So instead check whether the output fd refers to a pipe or a tty when opening it. Reported-By: Olivier Gosseaume, Marko Tiikkaja Discussion: 559AF98B.3050901@joh.to Backpatch to 9.4, where pg_recvlogical was added.
-rw-r--r--src/bin/pg_basebackup/pg_recvlogical.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
index 2a73ff64135..14714b139ac 100644
--- a/src/bin/pg_basebackup/pg_recvlogical.c
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -50,6 +50,7 @@ static const char *plugin = "test_decoding";
static int outfd = -1;
static volatile sig_atomic_t time_to_abort = false;
static volatile sig_atomic_t output_reopen = false;
+static bool output_isfile;
static int64 output_last_fsync = -1;
static bool output_needs_fsync = false;
static XLogRecPtr output_written_lsn = InvalidXLogRecPtr;
@@ -177,8 +178,11 @@ OutputFsync(int64 now)
output_needs_fsync = false;
- /* Accept EINVAL, in case output is writing to a pipe or similar. */
- if (fsync(outfd) != 0 && errno != EINVAL)
+ /* can only fsync if it's a regular file */
+ if (!output_isfile)
+ return true;
+
+ if (fsync(outfd) != 0)
{
fprintf(stderr,
_("%s: could not fsync log file \"%s\": %s\n"),
@@ -317,6 +321,8 @@ StreamLogicalLog(void)
/* open the output file, if not open yet */
if (outfd == -1)
{
+ struct stat statbuf;
+
if (strcmp(outfile, "-") == 0)
outfd = fileno(stdout);
else
@@ -329,6 +335,13 @@ StreamLogicalLog(void)
progname, outfile, strerror(errno));
goto error;
}
+
+ if (fstat(outfd, &statbuf) != 0)
+ fprintf(stderr,
+ _("%s: could not stat file \"%s\": %s\n"),
+ progname, outfile, strerror(errno));
+
+ output_isfile = S_ISREG(statbuf.st_mode) && !isatty(outfd);
}
r = PQgetCopyData(conn, &copybuf, 1);