Fix pg_current_logfile() to not emit a carriage return on Windows.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 9 Jul 2020 20:02:23 +0000 (16:02 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 9 Jul 2020 20:02:23 +0000 (16:02 -0400)
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

index ee340fb0f021bee659374ef589320b09601ceaac..37c23c9155afbb3ad9b31ed4d3280d7920e2168d 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <sys/file.h>
 #include <dirent.h>
+#include <fcntl.h>
 #include <math.h>
 #include <unistd.h>
 
@@ -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)
        {