@@ -1747,10 +1747,12 @@ write_eventlog(int level, const char *line, int len)
17471747static void
17481748write_console (const char * line , int len )
17491749{
1750+ int rc ;
1751+
17501752#ifdef WIN32
17511753
17521754 /*
1753- * WriteConsoleW() will fail of stdout is redirected, so just fall through
1755+ * WriteConsoleW() will fail if stdout is redirected, so just fall through
17541756 * to writing unconverted to the logfile in this case.
17551757 *
17561758 * Since we palloc the structure required for conversion, also fall
@@ -1788,13 +1790,18 @@ write_console(const char *line, int len)
17881790#else
17891791
17901792 /*
1791- * Conversion on non-win32 platform is not implemented yet. It requires
1793+ * Conversion on non-win32 platforms is not implemented yet. It requires
17921794 * non-throw version of pg_do_encoding_conversion(), that converts
17931795 * unconvertable characters to '?' without errors.
17941796 */
17951797#endif
17961798
1797- write (fileno (stderr ), line , len );
1799+ /*
1800+ * We ignore any error from write() here. We have no useful way to report
1801+ * it ... certainly whining on stderr isn't likely to be productive.
1802+ */
1803+ rc = write (fileno (stderr ), line , len );
1804+ (void ) rc ;
17981805}
17991806
18001807/*
@@ -2457,13 +2464,30 @@ send_message_to_server_log(ErrorData *edata)
24572464
24582465/*
24592466 * Send data to the syslogger using the chunked protocol
2467+ *
2468+ * Note: when there are multiple backends writing into the syslogger pipe,
2469+ * it's critical that each write go into the pipe indivisibly, and not
2470+ * get interleaved with data from other processes. Fortunately, the POSIX
2471+ * spec requires that writes to pipes be atomic so long as they are not
2472+ * more than PIPE_BUF bytes long. So we divide long messages into chunks
2473+ * that are no more than that length, and send one chunk per write() call.
2474+ * The collector process knows how to reassemble the chunks.
2475+ *
2476+ * Because of the atomic write requirement, there are only two possible
2477+ * results from write() here: -1 for failure, or the requested number of
2478+ * bytes. There is not really anything we can do about a failure; retry would
2479+ * probably be an infinite loop, and we can't even report the error usefully.
2480+ * (There is noplace else we could send it!) So we might as well just ignore
2481+ * the result from write(). However, on some platforms you get a compiler
2482+ * warning from ignoring write()'s result, so do a little dance with casting
2483+ * rc to void to shut up the compiler.
24602484 */
24612485static void
24622486write_pipe_chunks (char * data , int len , int dest )
24632487{
24642488 PipeProtoChunk p ;
2465-
24662489 int fd = fileno (stderr );
2490+ int rc ;
24672491
24682492 Assert (len > 0 );
24692493
@@ -2476,7 +2500,8 @@ write_pipe_chunks(char *data, int len, int dest)
24762500 p .proto .is_last = (dest == LOG_DESTINATION_CSVLOG ? 'F' : 'f' );
24772501 p .proto .len = PIPE_MAX_PAYLOAD ;
24782502 memcpy (p .proto .data , data , PIPE_MAX_PAYLOAD );
2479- write (fd , & p , PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD );
2503+ rc = write (fd , & p , PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD );
2504+ (void ) rc ;
24802505 data += PIPE_MAX_PAYLOAD ;
24812506 len -= PIPE_MAX_PAYLOAD ;
24822507 }
@@ -2485,7 +2510,8 @@ write_pipe_chunks(char *data, int len, int dest)
24852510 p .proto .is_last = (dest == LOG_DESTINATION_CSVLOG ? 'T' : 't' );
24862511 p .proto .len = len ;
24872512 memcpy (p .proto .data , data , len );
2488- write (fd , & p , PIPE_HEADER_SIZE + len );
2513+ rc = write (fd , & p , PIPE_HEADER_SIZE + len );
2514+ (void ) rc ;
24892515}
24902516
24912517
0 commit comments