Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7487713

Browse files
committed
Write to the Windows eventlog in UTF16, converting the message encoding
as necessary. Itagaki Takahiro with some changes from me
1 parent 76c09db commit 7487713

File tree

4 files changed

+215
-147
lines changed

4 files changed

+215
-147
lines changed

src/backend/utils/error/elog.c

Lines changed: 93 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
*
4343
*
4444
* 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 $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -111,8 +111,10 @@ static int syslog_facility = LOG_LOCAL0;
111111
static void write_syslog(int level, const char *line);
112112
#endif
113113

114+
static void write_console(const char *line, int len);
115+
114116
#ifdef WIN32
115-
static void write_eventlog(int level, const char *line);
117+
static void write_eventlog(int level, const char *line, int len);
116118
#endif
117119

118120
/* We provide a small stack of ErrorData records for re-entrant cases */
@@ -1567,10 +1569,11 @@ write_syslog(int level, const char *line)
15671569
* Write a message line to the windows event log
15681570
*/
15691571
static void
1570-
write_eventlog(int level, const char *line)
1572+
write_eventlog(int level, const char *line, int len)
15711573
{
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;
15741577

15751578
if (evtHandle == INVALID_HANDLE_VALUE)
15761579
{
@@ -1606,8 +1609,34 @@ write_eventlog(int level, const char *line)
16061609
break;
16071610
}
16081611

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,
16111640
eventlevel,
16121641
0,
16131642
0, /* All events are Id 0 */
@@ -1619,6 +1648,52 @@ write_eventlog(int level, const char *line)
16191648
}
16201649
#endif /* WIN32 */
16211650

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+
16221697
/*
16231698
* setup formatted_log_time, for consistent times between CSV and regular logs
16241699
*/
@@ -2206,7 +2281,7 @@ send_message_to_server_log(ErrorData *edata)
22062281
/* Write to eventlog, if enabled */
22072282
if (Log_destination & LOG_DESTINATION_EVENTLOG)
22082283
{
2209-
write_eventlog(edata->elevel, buf.data);
2284+
write_eventlog(edata->elevel, buf.data, buf.len);
22102285
}
22112286
#endif /* WIN32 */
22122287

@@ -2230,10 +2305,10 @@ send_message_to_server_log(ErrorData *edata)
22302305
* because that's really a pipe to the syslogger process.
22312306
*/
22322307
else if (pgwin32_is_service())
2233-
write_eventlog(edata->elevel, buf.data);
2308+
write_eventlog(edata->elevel, buf.data, buf.len);
22342309
#endif
22352310
else
2236-
write(fileno(stderr), buf.data, buf.len);
2311+
write_console(buf.data, buf.len);
22372312
}
22382313

22392314
/* If in the syslogger process, try to write messages direct to file */
@@ -2256,12 +2331,12 @@ send_message_to_server_log(ErrorData *edata)
22562331
{
22572332
const char *msg = _("Not safe to send CSV data\n");
22582333

2259-
write(fileno(stderr), msg, strlen(msg));
2334+
write_console(msg, strlen(msg));
22602335
if (!(Log_destination & LOG_DESTINATION_STDERR) &&
22612336
whereToSendOutput != DestDebug)
22622337
{
22632338
/* 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);
22652340
}
22662341
pfree(buf.data);
22672342
}
@@ -2642,6 +2717,9 @@ void
26422717
write_stderr(const char *fmt,...)
26432718
{
26442719
va_list ap;
2720+
#ifdef WIN32
2721+
char errbuf[2048]; /* Arbitrary size? */
2722+
#endif
26452723

26462724
fmt = _(fmt);
26472725

@@ -2651,23 +2729,20 @@ write_stderr(const char *fmt,...)
26512729
vfprintf(stderr, fmt, ap);
26522730
fflush(stderr);
26532731
#else
2732+
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
26542733

26552734
/*
26562735
* On Win32, we print to stderr if running on a console, or write to
26572736
* eventlog if running as a service
26582737
*/
26592738
if (pgwin32_is_service()) /* Running as a service */
26602739
{
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));
26662741
}
26672742
else
26682743
{
26692744
/* Not running as service, write to stderr */
2670-
vfprintf(stderr, fmt, ap);
2745+
write_console(errbuf, strlen(errbuf));
26712746
fflush(stderr);
26722747
}
26732748
#endif

src/backend/utils/mb/encnames.c

Lines changed: 48 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Encoding names and routines for work with it. All
33
* in this file is shared bedween FE and BE.
44
*
5-
* $PostgreSQL: pgsql/src/backend/utils/mb/encnames.c,v 1.39 2009/04/24 08:43:50 mha Exp $
5+
* $PostgreSQL: pgsql/src/backend/utils/mb/encnames.c,v 1.40 2009/10/17 00:24:51 mha Exp $
66
*/
77
#ifdef FRONTEND
88
#include "postgres_fe.h"
@@ -300,134 +300,55 @@ sizeof(pg_encname_tbl) / sizeof(pg_encname_tbl[0]) - 1;
300300
* XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h)
301301
* ----------
302302
*/
303+
#ifndef WIN32
304+
#define DEF_ENC2NAME(name, codepage) { #name, PG_##name }
305+
#else
306+
#define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage }
307+
#endif
303308
pg_enc2name pg_enc2name_tbl[] =
304309
{
305-
{
306-
"SQL_ASCII", PG_SQL_ASCII
307-
},
308-
{
309-
"EUC_JP", PG_EUC_JP
310-
},
311-
{
312-
"EUC_CN", PG_EUC_CN
313-
},
314-
{
315-
"EUC_KR", PG_EUC_KR
316-
},
317-
{
318-
"EUC_TW", PG_EUC_TW
319-
},
320-
{
321-
"EUC_JIS_2004", PG_EUC_JIS_2004
322-
},
323-
{
324-
"UTF8", PG_UTF8
325-
},
326-
{
327-
"MULE_INTERNAL", PG_MULE_INTERNAL
328-
},
329-
{
330-
"LATIN1", PG_LATIN1
331-
},
332-
{
333-
"LATIN2", PG_LATIN2
334-
},
335-
{
336-
"LATIN3", PG_LATIN3
337-
},
338-
{
339-
"LATIN4", PG_LATIN4
340-
},
341-
{
342-
"LATIN5", PG_LATIN5
343-
},
344-
{
345-
"LATIN6", PG_LATIN6
346-
},
347-
{
348-
"LATIN7", PG_LATIN7
349-
},
350-
{
351-
"LATIN8", PG_LATIN8
352-
},
353-
{
354-
"LATIN9", PG_LATIN9
355-
},
356-
{
357-
"LATIN10", PG_LATIN10
358-
},
359-
{
360-
"WIN1256", PG_WIN1256
361-
},
362-
{
363-
"WIN1258", PG_WIN1258
364-
},
365-
{
366-
"WIN866", PG_WIN866
367-
},
368-
{
369-
"WIN874", PG_WIN874
370-
},
371-
{
372-
"KOI8R", PG_KOI8R
373-
},
374-
{
375-
"WIN1251", PG_WIN1251
376-
},
377-
{
378-
"WIN1252", PG_WIN1252
379-
},
380-
{
381-
"ISO_8859_5", PG_ISO_8859_5
382-
},
383-
{
384-
"ISO_8859_6", PG_ISO_8859_6
385-
},
386-
{
387-
"ISO_8859_7", PG_ISO_8859_7
388-
},
389-
{
390-
"ISO_8859_8", PG_ISO_8859_8
391-
},
392-
{
393-
"WIN1250", PG_WIN1250
394-
},
395-
{
396-
"WIN1253", PG_WIN1253
397-
},
398-
{
399-
"WIN1254", PG_WIN1254
400-
},
401-
{
402-
"WIN1255", PG_WIN1255
403-
},
404-
{
405-
"WIN1257", PG_WIN1257
406-
},
407-
{
408-
"KOI8U", PG_KOI8U
409-
},
410-
{
411-
"SJIS", PG_SJIS
412-
},
413-
{
414-
"BIG5", PG_BIG5
415-
},
416-
{
417-
"GBK", PG_GBK
418-
},
419-
{
420-
"UHC", PG_UHC
421-
},
422-
{
423-
"GB18030", PG_GB18030
424-
},
425-
{
426-
"JOHAB", PG_JOHAB
427-
},
428-
{
429-
"SHIFT_JIS_2004", PG_SHIFT_JIS_2004
430-
}
310+
DEF_ENC2NAME(SQL_ASCII, 0),
311+
DEF_ENC2NAME(EUC_JP, 20932),
312+
DEF_ENC2NAME(EUC_CN, 20936),
313+
DEF_ENC2NAME(EUC_KR, 51949),
314+
DEF_ENC2NAME(EUC_TW, 0),
315+
DEF_ENC2NAME(EUC_JIS_2004, 20932),
316+
DEF_ENC2NAME(UTF8, 65001),
317+
DEF_ENC2NAME(MULE_INTERNAL, 0),
318+
DEF_ENC2NAME(LATIN1, 28591),
319+
DEF_ENC2NAME(LATIN2, 28592),
320+
DEF_ENC2NAME(LATIN3, 28593),
321+
DEF_ENC2NAME(LATIN4, 28594),
322+
DEF_ENC2NAME(LATIN5, 28599),
323+
DEF_ENC2NAME(LATIN6, 0),
324+
DEF_ENC2NAME(LATIN7, 0),
325+
DEF_ENC2NAME(LATIN8, 0),
326+
DEF_ENC2NAME(LATIN9, 28605),
327+
DEF_ENC2NAME(LATIN10, 0),
328+
DEF_ENC2NAME(WIN1256, 1256),
329+
DEF_ENC2NAME(WIN1258, 1258),
330+
DEF_ENC2NAME(WIN866, 866),
331+
DEF_ENC2NAME(WIN874, 874),
332+
DEF_ENC2NAME(KOI8R, 20866),
333+
DEF_ENC2NAME(WIN1251, 1251),
334+
DEF_ENC2NAME(WIN1252, 1252),
335+
DEF_ENC2NAME(ISO_8859_5, 28595),
336+
DEF_ENC2NAME(ISO_8859_6, 28596),
337+
DEF_ENC2NAME(ISO_8859_7, 28597),
338+
DEF_ENC2NAME(ISO_8859_8, 28598),
339+
DEF_ENC2NAME(WIN1250, 1250),
340+
DEF_ENC2NAME(WIN1253, 1253),
341+
DEF_ENC2NAME(WIN1254, 1254),
342+
DEF_ENC2NAME(WIN1255, 1255),
343+
DEF_ENC2NAME(WIN1257, 1257),
344+
DEF_ENC2NAME(KOI8U, 21866),
345+
DEF_ENC2NAME(SJIS, 932),
346+
DEF_ENC2NAME(BIG5, 950),
347+
DEF_ENC2NAME(GBK, 936),
348+
DEF_ENC2NAME(UHC, 0),
349+
DEF_ENC2NAME(GB18030, 54936),
350+
DEF_ENC2NAME(JOHAB, 0),
351+
DEF_ENC2NAME(SHIFT_JIS_2004, 932)
431352
};
432353

433354
/* ----------

0 commit comments

Comments
 (0)