Обсуждение: Unportability of setvbuf()
From the department of punishing good deeds ... in commit 2dc4f011fd I added setvbuf() calls to initdb to ensure that output to stdout and stderr would appear in a consistent order regardless of whether the output was going to a terminal or a file. The buildfarm shows that on several (but not all) Windows machines, initdb is now failing without printing anything. After a bit of research, I believe what is happening is: (1) On Windows, setvbuf interprets _IOLBF as _IOFBF. (2) If _IOFBF is specified and size is zero, it reports EINVAL. (3) If "parameter validation" is enabled, EINVAL turns into abort(). Thanks Microsoft for your careful attention to compliance with POSIX. I see that syslogger.c encountered this problem long ago and solved it by the expedient of using _IONBF not _IOLBF for the log output file. That's probably what we must do for stdout in initdb as well. It seems likely that we may need the same in other client programs someday. What I'm not totally sure about is how to wrap this up nicely. I'm inclined first of all to move syslogger.c's LBF_MODE symbol to port.h and rename it to, say, PG_IOLBF. It might also be reasonable to create a wrapper macro along the line of "PG_STD_IO_BUFFERING()" that would encapsulate the whole sequencesetvbuf(stdout, NULL, _IOLBF, 0);setvbuf(stderr, NULL, _IONBF,0); Or maybe we should have separate macros for those two calls. Or maybe this is just a useless layer of abstraction and PG_IOLBF is enough to make the calls portable. Thoughts? regards, tom lane
Tom Lane wrote: > It might also be reasonable to create a wrapper macro along the line of > "PG_STD_IO_BUFFERING()" that would encapsulate the whole sequence > setvbuf(stdout, NULL, _IOLBF, 0); > setvbuf(stderr, NULL, _IONBF, 0); > Or maybe we should have separate macros for those two calls. Or maybe > this is just a useless layer of abstraction and PG_IOLBF is enough > to make the calls portable. > > Thoughts? I don't really know all that much about this stuff, but see commits 6eda3e9c27781dec369542a9b20cba7c3d832a5e and its parent about isolationtester. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
Alvaro Herrera <alvherre@2ndquadrant.com> writes: > Tom Lane wrote: >> It might also be reasonable to create a wrapper macro along the line of >> "PG_STD_IO_BUFFERING()" that would encapsulate the whole sequence >> setvbuf(stdout, NULL, _IOLBF, 0); >> setvbuf(stderr, NULL, _IONBF, 0); >> Or maybe we should have separate macros for those two calls. Or maybe >> this is just a useless layer of abstraction and PG_IOLBF is enough >> to make the calls portable. >> >> Thoughts? > I don't really know all that much about this stuff, but see commits > 6eda3e9c27781dec369542a9b20cba7c3d832a5e and its parent about > isolationtester. Yeah, making them both unbuffered is another scenario that has its use-cases, so maybe it's inappropriate to create a macro that presumes to define the One True Way. For the moment I'll just arrange for initdb to share the logic with syslogger. regards, tom lane