diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index f1f9effae77085b7ec2c23aa25e0d570e3a350ac..f187393e4366e33e8a3f7d442a14386ae2b0d1c8 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.535 2007/07/24 04:54:09 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.536 2007/08/02 23:15:26 adunstan Exp $
  *
  * NOTES
  *
@@ -3385,6 +3385,15 @@ SubPostmasterMain(int argc, char *argv[])
 
 	MyProcPid = getpid();		/* reset MyProcPid */
 
+	/* make sure stderr is in binary mode before anything can
+	 * possibly be written to it, in case it's actually the syslogger pipe,
+	 * so the pipe chunking protocol isn't disturbed. Non-logpipe data
+	 * gets translated on redirection (e.g. via pg_ctl -l) anyway.
+	 */
+#ifdef WIN32
+	_setmode(fileno(stderr),_O_BINARY);
+#endif
+
 	/* Lose the postmaster's on-exit routines (really a no-op) */
 	on_exit_reset();
 
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c
index d07a6818e43ac83bbced30ad8ae50ff95cd35405..8dc7353a67172cb9964824f9b344ae7d95a4c0ca 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -18,7 +18,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.33 2007/07/19 19:13:43 adunstan Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.34 2007/08/02 23:15:27 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -194,6 +194,15 @@ SysLoggerMain(int argc, char *argv[])
 		close(fd);
 	}
 
+	/* Syslogger's own stderr can't be the syslogPipe, so set it back to
+	 * text mode if we didn't just close it. 
+	 * (It was set to binary in SubPostmasterMain).
+	 */
+#ifdef WIN32
+	else
+		_setmode(_fileno(stderr),_O_TEXT);
+#endif
+
 	/*
 	 * Also close our copy of the write end of the pipe.  This is needed to
 	 * ensure we can detect pipe EOF correctly.  (But note that in the restart
@@ -531,14 +540,20 @@ SysLogger_Start(void)
 #else
 				int			fd;
 
+				/*
+				 * open the pipe in binary mode and make sure
+				 * stderr is binary after it's been dup'ed into, to avoid
+				 * disturbing the pipe chunking protocol.
+				 */
 				fflush(stderr);
 				fd = _open_osfhandle((long) syslogPipe[1],
-									 _O_APPEND | _O_TEXT);
+									 _O_APPEND | _O_BINARY);
 				if (dup2(fd, _fileno(stderr)) < 0)
 					ereport(FATAL,
 							(errcode_for_file_access(),
 							 errmsg("could not redirect stderr: %m")));
 				close(fd);
+				_setmode(_fileno(stderr),_O_BINARY);
 				/* Now we are done with the write end of the pipe. */
 				CloseHandle(syslogPipe[1]);
 				syslogPipe[1] = 0;
@@ -626,7 +641,7 @@ syslogger_parseArgs(int argc, char *argv[])
 	fd = atoi(*argv++);
 	if (fd != 0)
 	{
-		fd = _open_osfhandle(fd, _O_APPEND);
+		fd = _open_osfhandle(fd, _O_APPEND | _O_TEXT);
 		if (fd > 0)
 		{
 			syslogFile = fdopen(fd, "a");
@@ -988,6 +1003,10 @@ logfile_rotate(bool time_based_rotation)
 
 	setvbuf(fh, NULL, LBF_MODE, 0);
 
+#ifdef WIN32
+	_setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */
+#endif
+
 	/* On Windows, need to interlock against data-transfer thread */
 #ifdef WIN32
 	EnterCriticalSection(&sysfileSection);