diff --git a/CHANGES b/CHANGES index fbeb126..40a149d 100644 --- a/CHANGES +++ b/CHANGES @@ -64,6 +64,12 @@ corrections: Option o-nonblock in combination with large transfer block sizes may result in partial writes and/or EAGAIN errors that were not handled properly but resulted in data loss or process termination. + + Fixed a bug that could freeze socat when during assembly of a log + message a signal was handled that also printed a log message. socat + development had been aware that localtime() is not thread safe but had + only expected broken messages, not corrupted stack (glibc 2.11.1, + Ubuntu 10.4) docu mentions option so-bindtodev but correct name is so-bindtodevice. Thanks to Jim Zimmerman for reporting. diff --git a/error.c b/error.c index 9130936..b45b014 100644 --- a/error.c +++ b/error.c @@ -1,5 +1,5 @@ /* source: error.c */ -/* Copyright Gerhard Rieger 2001-2008 */ +/* Copyright Gerhard Rieger 2001-2012 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* the logging subsystem */ @@ -191,6 +191,9 @@ void msg(int level, const char *format, ...) { #else /* !HAVE_GETTIMEOFDAY */ time_t now; #endif /* !HAVE_GETTIMEOFDAY */ +#if HAVE_STRFTIME + struct tm struct_tm; +#endif #define BUFLEN 512 char buff[BUFLEN], *bufp, *syslp; size_t bytes; @@ -211,11 +214,11 @@ void msg(int level, const char *format, ...) { nowt = now.tv_sec; #if HAVE_STRFTIME if (diagopts.micros) { - bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime(&nowt)); + bytes = strftime(buff, 20, "%Y/%m/%d %H:%M:%S", localtime_r(&nowt, &struct_tm)); bytes += sprintf(buff+19, "."F_tv_usec" ", now.tv_usec); } else { bytes = - strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime(&nowt)); + strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime_r(&nowt, &struct_tm)); } #else strcpy(buff, ctime(&nowt)); @@ -231,7 +234,7 @@ void msg(int level, const char *format, ...) { strcpy(buff, "unknown time "); bytes = 20; } else { #if HAVE_STRFTIME - bytes = strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime(&now)); + bytes = strftime(buff, 21, "%Y/%m/%d %H:%M:%S ", localtime_r(&now, &struct_tm)); #else strcpy(buff, ctime(&now)); bytes = strlen(buff);