Only use the pipe chunking protocol if we know the syslogger should
authorAndrew Dunstan <andrew@dunslane.net>
Thu, 19 Jul 2007 19:15:25 +0000 (19:15 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Thu, 19 Jul 2007 19:15:25 +0000 (19:15 +0000)
be catching stderr output, and we are not ourselves the
syslogger. Otherwise, go directly to stderr.
Bug noticed by Tom Lane.
Backpatch as far as 8.0.

src/backend/postmaster/postmaster.c
src/backend/postmaster/syslogger.c
src/backend/utils/error/elog.c

index ab45db3a64ae6175168f446b3a1ae74170485ebf..4fca006beca6d8bf7ebc6184688ab351ef96fa8e 100644 (file)
@@ -221,6 +221,7 @@ static bool FatalError = false; /* T if recovering from backend crash */
 
 bool           ClientAuthInProgress = false;           /* T during new-client
                                                                                                 * authentication */
+bool redirection_done = false; 
 
 /*
  * State for assigning random salts and cancel keys.
@@ -330,6 +331,7 @@ typedef struct
        InheritableSocket pgStatPipe0;
        InheritableSocket pgStatPipe1;
        pid_t PostmasterPid;
+       bool redirection_done;
 #ifdef WIN32
        HANDLE PostmasterHandle;
        HANDLE initial_signal_pipe;
@@ -3718,6 +3720,8 @@ save_backend_variables(BackendParameters *param, Port *port,
 
        param->PostmasterPid = PostmasterPid;
 
+       param->redirection_done = redirection_done;
+
 #ifdef WIN32
        param->PostmasterHandle = PostmasterHandle;
        write_duplicated_handle(&param->initial_signal_pipe,
@@ -3920,6 +3924,8 @@ restore_backend_variables(BackendParameters *param, Port *port)
 
        PostmasterPid = param->PostmasterPid;
 
+       redirection_done = param->redirection_done;
+
 #ifdef WIN32
        PostmasterHandle = param->PostmasterHandle;
        pgwin32_initial_signal_pipe = param->initial_signal_pipe;
index 909718a461d41be3eb2bf6e0f047bb2964a9e52a..c2404ab5a543aac6b7e7e0a5ba700f9d68f0b763 100644 (file)
@@ -78,11 +78,12 @@ bool                Log_truncate_on_rotation = false;
  */
 bool           am_syslogger = false;
 
+extern bool redirection_done;
+
 /*
  * Private state
  */
 static pg_time_t next_rotation_time;
-static bool redirection_done = false;
 static bool pipe_eof_seen = false;
 static FILE *syslogFile = NULL;
 static char *last_file_name = NULL;
@@ -600,14 +601,12 @@ syslogger_forkexec(void)
                snprintf(numbuf[bufc++], 32, "%d", fileno(syslogFile));
        else
                strcpy(numbuf[bufc++], "-1");
-       snprintf(numbuf[bufc++], 32, "%d", (int) redirection_done);
 #else                                                  /* WIN32 */
        if (syslogFile != NULL)
                snprintf(numbuf[bufc++], 32, "%ld",
                                 _get_osfhandle(_fileno(syslogFile)));
        else
                strcpy(numbuf[bufc++], "0");
-       snprintf(numbuf[bufc++], 32, "%d", (int) redirection_done);
 #endif   /* WIN32 */
 
        /* Add to the arg list */
@@ -641,7 +640,6 @@ syslogger_parseArgs(int argc, char *argv[])
                syslogFile = fdopen(fd, "a");
                setvbuf(syslogFile, NULL, LBF_MODE, 0);
        }
-       redirection_done = (bool) atoi(*argv++);
 #else                                                  /* WIN32 */
        fd = atoi(*argv++);
        if (fd != 0)
@@ -653,7 +651,6 @@ syslogger_parseArgs(int argc, char *argv[])
                        setvbuf(syslogFile, NULL, LBF_MODE, 0);
                }
        }
-       redirection_done = (bool) atoi(*argv++);
 #endif   /* WIN32 */
 }
 #endif   /* EXEC_BACKEND */
index 85cafbd094cb18440628af2102741674ccc260c0..2240a5bddf1a604ed058594ff661ff16f3662e24 100644 (file)
@@ -75,6 +75,8 @@ ErrorContextCallback *error_context_stack = NULL;
 
 sigjmp_buf *PG_exception_stack = NULL;
 
+extern bool redirection_done;
+
 /* GUC parameters */
 PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
 char      *Log_line_prefix = NULL;             /* format for extra log line info */
@@ -1670,11 +1672,11 @@ send_message_to_server_log(ErrorData *edata)
                 * If stderr redirection is active, it's ok to write to stderr
                 * because that's really a pipe to the syslogger process.
                 */
-               if ((!Redirect_stderr || am_syslogger) && pgwin32_is_service())
+               if (pgwin32_is_service() && (!redirection_done || am_syslogger) )
                        write_eventlog(edata->elevel, buf.data);
                else
 #endif
-                       if (Redirect_stderr)
+                       if (redirection_done && !am_syslogger)
                                write_pipe_chunks(fileno(stderr), buf.data, buf.len);
                        else
                                write(fileno(stderr), buf.data, buf.len);