Thanks to visit codestin.com
Credit goes to github.com

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)