Skip to content

Commit 9601cb7

Browse files
committed
Fix unportable setvbuf() usage in initdb.
In yesterday's commit 2dc4f01, I tried to force buffering of stdout/stderr in initdb to be what it is by default when the program is run interactively on Unix (since that's how most manual testing is done). This tripped over the fact that Windows doesn't support _IOLBF mode. We dealt with that a long time ago in syslogger.c by falling back to unbuffered mode on Windows. Export that solution in port.h and use it in initdb. Back-patch to 8.4, like the previous commit.
1 parent 479a36f commit 9601cb7

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

src/backend/postmaster/syslogger.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,6 @@
4646
#include "utils/ps_status.h"
4747
#include "utils/timestamp.h"
4848

49-
/*
50-
* We really want line-buffered mode for logfile output, but Windows does
51-
* not have it, and interprets _IOLBF as _IOFBF (bozos). So use _IONBF
52-
* instead on Windows.
53-
*/
54-
#ifdef WIN32
55-
#define LBF_MODE _IONBF
56-
#else
57-
#define LBF_MODE _IOLBF
58-
#endif
59-
6049
/*
6150
* We read() into a temp buffer twice as big as a chunk, so that any fragment
6251
* left after processing can be moved down to the front and we'll still have
@@ -744,7 +733,7 @@ syslogger_parseArgs(int argc, char *argv[])
744733
if (fd != -1)
745734
{
746735
syslogFile = fdopen(fd, "a");
747-
setvbuf(syslogFile, NULL, LBF_MODE, 0);
736+
setvbuf(syslogFile, NULL, PG_IOLBF, 0);
748737
}
749738
#else /* WIN32 */
750739
fd = atoi(*argv++);
@@ -754,7 +743,7 @@ syslogger_parseArgs(int argc, char *argv[])
754743
if (fd > 0)
755744
{
756745
syslogFile = fdopen(fd, "a");
757-
setvbuf(syslogFile, NULL, LBF_MODE, 0);
746+
setvbuf(syslogFile, NULL, PG_IOLBF, 0);
758747
}
759748
}
760749
#endif /* WIN32 */
@@ -1133,7 +1122,7 @@ logfile_open(const char *filename, const char *mode, bool allow_errors)
11331122

11341123
if (fh)
11351124
{
1136-
setvbuf(fh, NULL, LBF_MODE, 0);
1125+
setvbuf(fh, NULL, PG_IOLBF, 0);
11371126

11381127
#ifdef WIN32
11391128
/* use CRLF line endings on Windows */

src/bin/initdb/initdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2675,7 +2675,7 @@ main(int argc, char *argv[])
26752675
* unexpected output ordering when, eg, output is redirected to a file.
26762676
* POSIX says we must do this before any other usage of these files.
26772677
*/
2678-
setvbuf(stdout, NULL, _IOLBF, 0);
2678+
setvbuf(stdout, NULL, PG_IOLBF, 0);
26792679
setvbuf(stderr, NULL, _IONBF, 0);
26802680

26812681
progname = get_progname(argv[0]);

src/include/port.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,20 @@ extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
352352
#define closesocket close
353353
#endif /* WIN32 */
354354

355+
/*
356+
* On Windows, setvbuf() does not support _IOLBF mode, and interprets that
357+
* as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0)
358+
* crashes outright if "parameter validation" is enabled. Therefore, in
359+
* places where we'd like to select line-buffered mode, we fall back to
360+
* unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF
361+
* directly in order to implement this behavior.
362+
*/
363+
#ifndef WIN32
364+
#define PG_IOLBF _IOLBF
365+
#else
366+
#define PG_IOLBF _IONBF
367+
#endif
368+
355369
/*
356370
* Default "extern" declarations or macro substitutes for library routines.
357371
* When necessary, these routines are provided by files in src/port/.

0 commit comments

Comments
 (0)