From 601d419b2b5def62a1867169e67c7ef876f0b886 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 9 Jul 2020 16:02:23 -0400 Subject: [PATCH] Fix pg_current_logfile() to not emit a carriage return on Windows. Due to not having our signals straight about CRLF vs. LF line termination, the output of pg_current_logfile() included a trailing \r on Windows. To fix, force the file descriptor it uses into text mode. While here, move a couple of local variable declarations to make the function's logic clearer. In v12 and v13, also back-patch the test added by 1c4e88e2f so that this function has some test coverage. However, the 004_logrotate.pl test script doesn't exist before v12, and it didn't seem worth adding to older branches just for this. Per report from Thomas Kellerer. Back-patch to v10 where this function was added. Discussion: https://postgr.es/m/412ae8da-76bb-640f-039a-f3513499e53d@gmx.net --- src/backend/utils/adt/misc.c | 19 ++++++++++++------- src/bin/pg_ctl/t/004_logrotate.pl | 6 +++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index ee340fb0f0..37c23c9155 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -738,9 +739,6 @@ pg_current_logfile(PG_FUNCTION_ARGS) FILE *fd; char lbuffer[MAXPGPATH]; char *logfmt; - char *log_filepath; - char *log_format = lbuffer; - char *nlpos; /* The log format parameter is optional */ if (PG_NARGS() == 0 || PG_ARGISNULL(0)) @@ -767,16 +765,23 @@ pg_current_logfile(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } +#ifdef WIN32 + /* syslogger.c writes CRLF line endings on Windows */ + _setmode(_fileno(fd), _O_TEXT); +#endif + /* * Read the file to gather current log filename(s) registered by the * syslogger. */ while (fgets(lbuffer, sizeof(lbuffer), fd) != NULL) { - /* - * Extract log format and log file path from the line; lbuffer == - * log_format, they share storage. - */ + char *log_format; + char *log_filepath; + char *nlpos; + + /* Extract log format and log file path from the line. */ + log_format = lbuffer; log_filepath = strchr(lbuffer, ' '); if (log_filepath == NULL) { diff --git a/src/bin/pg_ctl/t/004_logrotate.pl b/src/bin/pg_ctl/t/004_logrotate.pl index 71dbfd2030..acaade8d81 100644 --- a/src/bin/pg_ctl/t/004_logrotate.pl +++ b/src/bin/pg_ctl/t/004_logrotate.pl @@ -3,7 +3,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 4; +use Test::More tests => 5; use Time::HiRes qw(usleep); # Set up node with logging collector @@ -47,6 +47,10 @@ for (my $attempts = 0; $attempts < $max_attempts; $attempts++) like($first_logfile, qr/division by zero/, 'found expected log file content'); +# While we're at it, test pg_current_logfile() function +is($node->safe_psql('postgres', "SELECT pg_current_logfile('stderr')"), + $lfname, 'pg_current_logfile() gives correct answer'); + # Sleep 2 seconds and ask for log rotation; this should result in # output into a different log file name. sleep(2);