diff options
author | Andres Freund <andres@anarazel.de> | 2015-07-07 12:47:44 +0200 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2015-07-07 13:07:50 +0200 |
commit | 1790b35baf52fff7f670f7cc1159a1b40b36e701 (patch) | |
tree | 94b106e36abc8b7a091faf6d1a81dd53cca0f0cc | |
parent | 0471894a6f01007752abd37ca493ed371a720bdd (diff) | |
download | postgresql-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.c | 17 |
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, ©buf, 1); |