summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compat.c2
-rw-r--r--src/log.c47
2 files changed, 41 insertions, 8 deletions
diff --git a/src/compat.c b/src/compat.c
index b9931ced9..a45483542 100644
--- a/src/compat.c
+++ b/src/compat.c
@@ -43,7 +43,7 @@ int snprintf(char *buf, size_t len, const char *fmt, ...)
va_start(args, fmt);
return vsnprintf(buf, len, fmt, args);
- /* Again should have va_end() here */
+ va_end(args);
}
#endif /* !HAVE_SNPRINTF */
diff --git a/src/log.c b/src/log.c
index a929d2dba..1d2048a10 100644
--- a/src/log.c
+++ b/src/log.c
@@ -121,7 +121,7 @@ void close_log(void)
void alog(const char *fmt, ...)
{
- va_list args;
+ va_list args, logargs, consoleargs, logchanargs;
time_t t;
struct tm tm;
char buf[256];
@@ -134,6 +134,20 @@ void alog(const char *fmt, ...)
}
va_start(args, fmt);
+
+ /* 64-bit safety:
+ *
+ * GCC on many 64-bit boxes causes the stack used for the va_list
+ * to become unavailable after you use them, so we need to make copies
+ * of the va_list for all of our logging targets, otherwise Anope will
+ * crash. :(
+ *
+ * --nenolod
+ */
+ va_copy(logargs, args);
+ va_copy(consoleargs, args);
+ va_copy(logchanargs, args);
+
time(&t);
tm = *localtime(&t);
#if HAVE_GETTIMEOFDAY
@@ -154,21 +168,24 @@ void alog(const char *fmt, ...)
#endif
if (logfile) {
fputs(buf, logfile);
- vfprintf(logfile, fmt, args);
+ vfprintf(logfile, fmt, logargs);
fputc('\n', logfile);
}
if (nofork) {
fputs(buf, stderr);
- vfprintf(stderr, fmt, args);
+ vfprintf(stderr, fmt, consoleargs);
fputc('\n', stderr);
}
if (LogChannel && logchan && !debug && findchan(LogChannel)) {
char str[BUFSIZE];
- vsnprintf(str, sizeof(str), fmt, args);
+ vsnprintf(str, sizeof(str), fmt, logchanargs);
privmsg(s_GlobalNoticer, LogChannel, "%s", str);
}
+ va_end(logargs);
+ va_end(consoleargs);
+ va_end(logchanargs);
va_end(args);
errno = errno_save;
}
@@ -180,7 +197,7 @@ void alog(const char *fmt, ...)
void log_perror(const char *fmt, ...)
{
- va_list args;
+ va_list args, logargs, consoleargs;
time_t t;
struct tm tm;
char buf[256];
@@ -193,6 +210,19 @@ void log_perror(const char *fmt, ...)
}
va_start(args, fmt);
+
+ /* 64-bit safety:
+ *
+ * GCC on many 64-bit boxes causes the stack used for the va_list
+ * to become unavailable after you use them, so we need to make copies
+ * of the va_list for all of our logging targets, otherwise Anope will
+ * crash. :(
+ *
+ * --nenolod
+ */
+ va_copy(logargs, args);
+ va_copy(consoleargs, args);
+
time(&t);
tm = *localtime(&t);
#if HAVE_GETTIMEOFDAY
@@ -213,15 +243,18 @@ void log_perror(const char *fmt, ...)
#endif
if (logfile) {
fputs(buf, logfile);
- vfprintf(logfile, fmt, args);
+ vfprintf(logfile, fmt, logargs);
fprintf(logfile, ": %s\n", strerror(errno_save));
}
if (nofork) {
fputs(buf, stderr);
- vfprintf(stderr, fmt, args);
+ vfprintf(stderr, fmt, consoleargs);
fprintf(stderr, ": %s\n", strerror(errno_save));
}
errno = errno_save;
+
+ va_end(logargs);
+ va_end(consoleargs);
va_end(args);
}