diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-10-14 16:41:13 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-10-14 16:41:13 +0000 |
commit | 98658dd40432c3c12ace9e0fd16315b32bb478f5 (patch) | |
tree | 52c213eeeb0be73fd21b9d8588a486c102811603 /src | |
parent | 7df6dfdda70f6264e6d4122f5c9b71c9b2676edb (diff) | |
download | postgresql-98658dd40432c3c12ace9e0fd16315b32bb478f5.tar.gz postgresql-98658dd40432c3c12ace9e0fd16315b32bb478f5.zip |
Pass a strdup'd ident string to openlog(), to ensure that reallocation
of GUC memory doesn't cause us to start emitting a bogus ident string.
Per report from Han Holl. Also some trivial code cleanup in write_syslog.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/error/elog.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 68d0b13a767..c919f7c2c65 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -42,7 +42,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.155.4.2 2005/08/12 21:38:00 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.155.4.3 2005/10/14 16:41:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -85,6 +85,7 @@ char *Syslog_ident; static void write_syslog(int level, const char *line); #endif + #ifdef WIN32 static void write_eventlog(int level, const char *line); #endif @@ -1152,41 +1153,51 @@ DebugFileOpen(void) #endif /* - * Write a message line to syslog if the syslog option is set. - * - * Our problem here is that many syslog implementations don't handle - * long messages in an acceptable manner. While this function doesn't - * help that fact, it does work around by splitting up messages into - * smaller pieces. + * Write a message line to syslog */ static void write_syslog(int level, const char *line) { static bool openlog_done = false; static unsigned long seq = 0; - static int syslog_fac = LOG_LOCAL0; - int len = strlen(line); + int len; if (!openlog_done) { + int syslog_fac; + char *syslog_ident; + if (pg_strcasecmp(Syslog_facility, "LOCAL0") == 0) syslog_fac = LOG_LOCAL0; - if (pg_strcasecmp(Syslog_facility, "LOCAL1") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL1") == 0) syslog_fac = LOG_LOCAL1; - if (pg_strcasecmp(Syslog_facility, "LOCAL2") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL2") == 0) syslog_fac = LOG_LOCAL2; - if (pg_strcasecmp(Syslog_facility, "LOCAL3") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL3") == 0) syslog_fac = LOG_LOCAL3; - if (pg_strcasecmp(Syslog_facility, "LOCAL4") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL4") == 0) syslog_fac = LOG_LOCAL4; - if (pg_strcasecmp(Syslog_facility, "LOCAL5") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL5") == 0) syslog_fac = LOG_LOCAL5; - if (pg_strcasecmp(Syslog_facility, "LOCAL6") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL6") == 0) syslog_fac = LOG_LOCAL6; - if (pg_strcasecmp(Syslog_facility, "LOCAL7") == 0) + else if (pg_strcasecmp(Syslog_facility, "LOCAL7") == 0) syslog_fac = LOG_LOCAL7; - openlog(Syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT, syslog_fac); + else + syslog_fac = LOG_LOCAL0; + /* + * openlog() usually just stores the passed char pointer as-is, + * so we must give it a string that will be unchanged for the life of + * the process. The Syslog_ident GUC variable does not meet this + * requirement, so strdup() it. This isn't a memory leak because + * this code is executed at most once per process. + */ + syslog_ident = strdup(Syslog_ident); + if (syslog_ident == NULL) /* out of memory already!? */ + syslog_ident = "postgres"; + + openlog(syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT, syslog_fac); openlog_done = true; } @@ -1196,8 +1207,16 @@ write_syslog(int level, const char *line) */ seq++; - /* divide into multiple syslog() calls if message is too long */ - /* or if the message contains embedded NewLine(s) '\n' */ + /* + * Our problem here is that many syslog implementations don't handle + * long messages in an acceptable manner. While this function doesn't + * help that fact, it does work around by splitting up messages into + * smaller pieces. + * + * We divide into multiple syslog() calls if message is too long + * or if the message contains embedded NewLine(s) '\n'. + */ + len = strlen(line); if (len > PG_SYSLOG_LIMIT || strchr(line, '\n') != NULL) { int chunk_nr = 0; @@ -1230,8 +1249,8 @@ write_syslog(int level, const char *line) buf[buflen] = '\0'; /* already word boundary? */ - if (!isspace((unsigned char) line[buflen]) && - line[buflen] != '\0') + if (line[buflen] != '\0' && + !isspace((unsigned char) line[buflen])) { /* try to divide at word boundary */ i = buflen - 1; @@ -1259,6 +1278,7 @@ write_syslog(int level, const char *line) } } #endif /* HAVE_SYSLOG */ + #ifdef WIN32 /* * Write a message line to the windows event log |