Only use the pipe chunking protocol if we know the syslogger should
authorAndrew Dunstan <andrew@dunslane.net>
Thu, 19 Jul 2007 19:13:43 +0000 (19:13 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Thu, 19 Jul 2007 19:13:43 +0000 (19:13 +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 f730e27c5f48920143282b825ec15db524380028..240f150d62a74e256e0eb921c7587d8e4c3aa39a 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.532 2007/07/11 08:27:33 mha Exp $
+ *   $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.533 2007/07/19 19:13:43 adunstan Exp $
  *
  * NOTES
  *
@@ -203,8 +203,8 @@ static pid_t StartupPID = 0,
            BgWriterPID = 0,
            AutoVacPID = 0,
            PgArchPID = 0,
-           PgStatPID = 0;
-pid_t          SysLoggerPID = 0; /* Needs to be accessed from elog.c */
+           PgStatPID = 0,
+           SysLoggerPID = 0;
 
 /* Startup/shutdown state */
 #define            NoShutdown      0
@@ -218,6 +218,8 @@ static bool FatalError = false; /* T if recovering from backend crash */
 bool       ClientAuthInProgress = false;       /* T during new-client
                                                 * authentication */
 
+bool redirection_done = false; 
+
 /* received START_AUTOVAC_LAUNCHER signal */
 static bool start_autovac_launcher = false;
 
@@ -332,6 +334,7 @@ typedef struct
    InheritableSocket pgStatSock;
    pid_t       PostmasterPid;
    TimestampTz PgStartTime;
+   bool        redirection_done;
 #ifdef WIN32
    HANDLE      PostmasterHandle;
    HANDLE      initial_signal_pipe;
@@ -3953,6 +3956,8 @@ save_backend_variables(BackendParameters * param, Port *port,
    param->PostmasterPid = PostmasterPid;
    param->PgStartTime = PgStartTime;
 
+   param->redirection_done = redirection_done;
+
 #ifdef WIN32
    param->PostmasterHandle = PostmasterHandle;
    write_duplicated_handle(&param->initial_signal_pipe,
@@ -4156,6 +4161,8 @@ restore_backend_variables(BackendParameters * param, Port *port)
    PostmasterPid = param->PostmasterPid;
    PgStartTime = param->PgStartTime;
 
+   redirection_done = param->redirection_done;
+
 #ifdef WIN32
    PostmasterHandle = param->PostmasterHandle;
    pgwin32_initial_signal_pipe = param->initial_signal_pipe;
index 0862b81dd7b4764f1f1af57a665fd1006241e2bf..d07a6818e43ac83bbced30ad8ae50ff95cd35405 100644 (file)
@@ -18,7 +18,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.32 2007/06/14 01:48:51 adunstan Exp $
+ *   $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.33 2007/07/19 19:13:43 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,11 +79,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;
@@ -582,14 +583,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 */
@@ -623,7 +622,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)
@@ -635,7 +633,6 @@ syslogger_parseArgs(int argc, char *argv[])
            setvbuf(syslogFile, NULL, LBF_MODE, 0);
        }
    }
-   redirection_done = (bool) atoi(*argv++);
 #endif   /* WIN32 */
 }
 #endif   /* EXEC_BACKEND */
index c762475d65a4a41c2008f6300b7ed3f02b890b2b..88d9182f297b19cc0f7a08be8f65e734900554a8 100644 (file)
@@ -42,7 +42,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.187 2007/06/14 01:48:51 adunstan Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.188 2007/07/19 19:13:43 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -76,7 +76,7 @@ ErrorContextCallback *error_context_stack = NULL;
 
 sigjmp_buf *PG_exception_stack = NULL;
 
-extern pid_t SysLoggerPID;
+extern bool redirection_done;
 
 /* GUC parameters */
 PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
@@ -1780,11 +1780,15 @@ send_message_to_server_log(ErrorData *edata)
         * that's really a pipe to the syslogger process. Unless we're in the
         * postmaster, and the syslogger process isn't started yet.
         */
-       if ((!Redirect_stderr || am_syslogger || (!IsUnderPostmaster && SysLoggerPID==0)) && pgwin32_is_service())
+       if (pgwin32_is_service() && (!redirection_done || am_syslogger) )
            write_eventlog(edata->elevel, buf.data);
        else
 #endif
-           if (Redirect_stderr)
+           /* only use the chunking protocol if we know the syslogger should
+            * be catching stderr output, and we are not ourselves the
+            * syslogger. Otherwise, go directly to stderr.
+            */
+           if (redirection_done && !am_syslogger)
                write_pipe_chunks(fileno(stderr), buf.data, buf.len);
            else
                write(fileno(stderr), buf.data, buf.len);