42
42
*
43
43
*
44
44
* IDENTIFICATION
45
- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.217 2009/07/03 19:14:25 petere Exp $
45
+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.218 2009/10/17 00:24:50 mha Exp $
46
46
*
47
47
*-------------------------------------------------------------------------
48
48
*/
@@ -111,8 +111,10 @@ static int syslog_facility = LOG_LOCAL0;
111
111
static void write_syslog (int level , const char * line );
112
112
#endif
113
113
114
+ static void write_console (const char * line , int len );
115
+
114
116
#ifdef WIN32
115
- static void write_eventlog (int level , const char * line );
117
+ static void write_eventlog (int level , const char * line , int len );
116
118
#endif
117
119
118
120
/* We provide a small stack of ErrorData records for re-entrant cases */
@@ -1567,10 +1569,11 @@ write_syslog(int level, const char *line)
1567
1569
* Write a message line to the windows event log
1568
1570
*/
1569
1571
static void
1570
- write_eventlog (int level , const char * line )
1572
+ write_eventlog (int level , const char * line , int len )
1571
1573
{
1572
- int eventlevel = EVENTLOG_ERROR_TYPE ;
1573
- static HANDLE evtHandle = INVALID_HANDLE_VALUE ;
1574
+ WCHAR * utf16 ;
1575
+ int eventlevel = EVENTLOG_ERROR_TYPE ;
1576
+ static HANDLE evtHandle = INVALID_HANDLE_VALUE ;
1574
1577
1575
1578
if (evtHandle == INVALID_HANDLE_VALUE )
1576
1579
{
@@ -1606,8 +1609,34 @@ write_eventlog(int level, const char *line)
1606
1609
break ;
1607
1610
}
1608
1611
1609
-
1610
- ReportEvent (evtHandle ,
1612
+ /*
1613
+ * Convert message to UTF16 text and write it with ReportEventW,
1614
+ * but fall-back into ReportEventA if conversion failed.
1615
+ *
1616
+ * Also verify that we are not on our way into error recursion trouble
1617
+ * due to error messages thrown deep inside pgwin32_toUTF16().
1618
+ */
1619
+ if (GetDatabaseEncoding () != GetPlatformEncoding () &&
1620
+ !in_error_recursion_trouble ())
1621
+ {
1622
+ utf16 = pgwin32_toUTF16 (line , len , NULL );
1623
+ if (utf16 )
1624
+ {
1625
+ ReportEventW (evtHandle ,
1626
+ eventlevel ,
1627
+ 0 ,
1628
+ 0 , /* All events are Id 0 */
1629
+ NULL ,
1630
+ 1 ,
1631
+ 0 ,
1632
+ (LPCWSTR * ) & utf16 ,
1633
+ NULL );
1634
+
1635
+ pfree (utf16 );
1636
+ return ;
1637
+ }
1638
+ }
1639
+ ReportEventA (evtHandle ,
1611
1640
eventlevel ,
1612
1641
0 ,
1613
1642
0 , /* All events are Id 0 */
@@ -1619,6 +1648,52 @@ write_eventlog(int level, const char *line)
1619
1648
}
1620
1649
#endif /* WIN32 */
1621
1650
1651
+ static void
1652
+ write_console (const char * line , int len )
1653
+ {
1654
+ #ifdef WIN32
1655
+ /*
1656
+ * WriteConsoleW() will fail of stdout is redirected, so just fall through
1657
+ * to writing unconverted to the logfile in this case.
1658
+ */
1659
+ if (GetDatabaseEncoding () != GetPlatformEncoding () &&
1660
+ !in_error_recursion_trouble () &&
1661
+ !redirection_done )
1662
+ {
1663
+ WCHAR * utf16 ;
1664
+ int utf16len ;
1665
+
1666
+ utf16 = pgwin32_toUTF16 (line , len , & utf16len );
1667
+ if (utf16 != NULL )
1668
+ {
1669
+ HANDLE stdHandle ;
1670
+ DWORD written ;
1671
+
1672
+ stdHandle = GetStdHandle (STD_ERROR_HANDLE );
1673
+ if (WriteConsoleW (stdHandle , utf16 , utf16len , & written , NULL ))
1674
+ {
1675
+ pfree (utf16 );
1676
+ return ;
1677
+ }
1678
+
1679
+ /*
1680
+ * In case WriteConsoleW() failed, fall back to writing the message
1681
+ * unconverted.
1682
+ */
1683
+ pfree (utf16 );
1684
+ }
1685
+ }
1686
+ #else
1687
+ /*
1688
+ * Conversion on non-win32 platform is not implemented yet.
1689
+ * It requires non-throw version of pg_do_encoding_conversion(),
1690
+ * that converts unconvertable characters to '?' without errors.
1691
+ */
1692
+ #endif
1693
+
1694
+ write (fileno (stderr ), line , len );
1695
+ }
1696
+
1622
1697
/*
1623
1698
* setup formatted_log_time, for consistent times between CSV and regular logs
1624
1699
*/
@@ -2206,7 +2281,7 @@ send_message_to_server_log(ErrorData *edata)
2206
2281
/* Write to eventlog, if enabled */
2207
2282
if (Log_destination & LOG_DESTINATION_EVENTLOG )
2208
2283
{
2209
- write_eventlog (edata -> elevel , buf .data );
2284
+ write_eventlog (edata -> elevel , buf .data , buf . len );
2210
2285
}
2211
2286
#endif /* WIN32 */
2212
2287
@@ -2230,10 +2305,10 @@ send_message_to_server_log(ErrorData *edata)
2230
2305
* because that's really a pipe to the syslogger process.
2231
2306
*/
2232
2307
else if (pgwin32_is_service ())
2233
- write_eventlog (edata - > elevel , buf .data );
2308
+ write_eventlog (edata - > elevel , buf .data , buf . len );
2234
2309
#endif
2235
2310
else
2236
- write ( fileno ( stderr ), buf .data , buf .len );
2311
+ write_console ( buf .data , buf .len );
2237
2312
}
2238
2313
2239
2314
/* If in the syslogger process, try to write messages direct to file */
@@ -2256,12 +2331,12 @@ send_message_to_server_log(ErrorData *edata)
2256
2331
{
2257
2332
const char * msg = _ ("Not safe to send CSV data\n" );
2258
2333
2259
- write ( fileno ( stderr ), msg , strlen (msg ));
2334
+ write_console ( msg , strlen (msg ));
2260
2335
if (!(Log_destination & LOG_DESTINATION_STDERR ) &&
2261
2336
whereToSendOutput != DestDebug )
2262
2337
{
2263
2338
/* write message to stderr unless we just sent it above */
2264
- write ( fileno ( stderr ), buf .data , buf .len );
2339
+ write_console ( buf .data , buf .len );
2265
2340
}
2266
2341
pfree (buf .data );
2267
2342
}
@@ -2642,6 +2717,9 @@ void
2642
2717
write_stderr (const char * fmt ,...)
2643
2718
{
2644
2719
va_list ap ;
2720
+ #ifdef WIN32
2721
+ char errbuf [2048 ]; /* Arbitrary size? */
2722
+ #endif
2645
2723
2646
2724
fmt = _ (fmt );
2647
2725
@@ -2651,23 +2729,20 @@ write_stderr(const char *fmt,...)
2651
2729
vfprintf (stderr , fmt , ap );
2652
2730
fflush (stderr );
2653
2731
#else
2732
+ vsnprintf (errbuf , sizeof (errbuf ), fmt , ap );
2654
2733
2655
2734
/*
2656
2735
* On Win32, we print to stderr if running on a console, or write to
2657
2736
* eventlog if running as a service
2658
2737
*/
2659
2738
if (pgwin32_is_service ()) /* Running as a service */
2660
2739
{
2661
- char errbuf [2048 ]; /* Arbitrary size? */
2662
-
2663
- vsnprintf (errbuf , sizeof (errbuf ), fmt , ap );
2664
-
2665
- write_eventlog (ERROR , errbuf );
2740
+ write_eventlog (ERROR , errbuf , strlen (errbuf ));
2666
2741
}
2667
2742
else
2668
2743
{
2669
2744
/* Not running as service, write to stderr */
2670
- vfprintf ( stderr , fmt , ap );
2745
+ write_console ( errbuf , strlen ( errbuf ) );
2671
2746
fflush (stderr );
2672
2747
}
2673
2748
#endif
0 commit comments