#define _COMMON_STANDARD_H
#include <limits.h>
+#include <time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <common/config.h>
extern int strl2irc(const char *s, int len, int *ret);
extern int strl2llrc(const char *s, int len, long long *ret);
+/* This function converts the time_t value <now> into a broken out struct tm
+ * which must be allocated by the caller. It is highly recommended to use this
+ * function intead of localtime() because that one requires a time_t* which
+ * is not always compatible with tv_sec depending on OS/hardware combinations.
+ */
+static inline void get_localtime(const time_t now, struct tm *tm)
+{
+ localtime_r(&now, tm);
+}
+
#endif /* _COMMON_STANDARD_H */
void Alert(const char *fmt, ...)
{
va_list argp;
- struct tm *tm;
+ struct tm tm;
if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
va_start(argp, fmt);
- tm = localtime((time_t *)&now.tv_sec);
+ get_localtime(now.tv_sec, &tm);
fprintf(stderr, "[ALERT] %03d/%02d%02d%02d (%d) : ",
- tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)getpid());
+ tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)getpid());
vfprintf(stderr, fmt, argp);
fflush(stderr);
va_end(argp);
void Warning(const char *fmt, ...)
{
va_list argp;
- struct tm *tm;
+ struct tm tm;
if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) {
va_start(argp, fmt);
- tm = localtime((time_t *)&now.tv_sec);
+ get_localtime(now.tv_sec, &tm);
fprintf(stderr, "[WARNING] %03d/%02d%02d%02d (%d) : ",
- tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)getpid());
+ tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)getpid());
vfprintf(stderr, fmt, argp);
fflush(stderr);
va_end(argp);
if (now.tv_sec != tvsec || dataptr == NULL) {
/* this string is rebuild only once a second */
- struct tm *tm = localtime((time_t *)&now.tv_sec);
+ struct tm tm;
+
tvsec = now.tv_sec;
+ get_localtime(tvsec, &tm);
hdr_len = snprintf(logmsg, sizeof(logmsg),
"<<<<>%s %2d %02d:%02d:%02d %s[%d]: ",
- monthname[tm->tm_mon],
- tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
+ monthname[tm.tm_mon],
+ tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
progname, pid);
/* WARNING: depending upon implementations, snprintf may return
* either -1 or the number of bytes that would be needed to store
struct proxy *prx_log;
int tolog;
char *svid;
- struct tm *tm;
+ struct tm tm;
if (s->cli_addr.ss_family == AF_INET)
inet_ntop(AF_INET,
(const void *)&((struct sockaddr_in6 *)(&s->cli_addr))->sin6_addr,
pn, sizeof(pn));
- tm = localtime((time_t *)&s->logs.tv_accept.tv_sec);
+ get_localtime(s->logs.tv_accept.tv_sec, &tm);
if (fe->logfac1 >= 0)
prx_log = fe;
(s->cli_addr.ss_family == AF_INET) ?
ntohs(((struct sockaddr_in *)&s->cli_addr)->sin_port) :
ntohs(((struct sockaddr_in6 *)&s->cli_addr)->sin6_port),
- tm->tm_mday, monthname[tm->tm_mon], tm->tm_year+1900,
- tm->tm_hour, tm->tm_min, tm->tm_sec, s->logs.tv_accept.tv_usec/1000,
+ tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, s->logs.tv_accept.tv_usec/1000,
fe->id, be->id, svid,
(s->logs.t_queue >= 0) ? s->logs.t_queue : -1,
(s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1,
int tolog;
char *uri, *h;
char *svid;
- struct tm *tm;
+ struct tm tm;
static char tmpline[MAX_SYSLOG_LEN];
int hdr;
(const void *)&((struct sockaddr_in6 *)(&s->cli_addr))->sin6_addr,
pn, sizeof(pn));
- tm = localtime((time_t *)&s->logs.tv_accept.tv_sec);
-
+ get_localtime(s->logs.tv_accept.tv_sec, &tm);
/* FIXME: let's limit ourselves to frontend logging for now. */
tolog = fe->to_log;
(s->cli_addr.ss_family == AF_INET) ?
ntohs(((struct sockaddr_in *)&s->cli_addr)->sin_port) :
ntohs(((struct sockaddr_in6 *)&s->cli_addr)->sin6_port),
- tm->tm_mday, monthname[tm->tm_mon], tm->tm_year+1900,
- tm->tm_hour, tm->tm_min, tm->tm_sec, s->logs.tv_accept.tv_usec/1000,
+ tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, s->logs.tv_accept.tv_usec/1000,
fe->id, be->id, svid,
s->logs.t_request,
(s->logs.t_queue >= 0) ? s->logs.t_queue - s->logs.t_request : -1,