From 5245f1f9d4e15ca518729e8fee02f9ab59399faf Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Fri, 22 Mar 2013 11:19:33 +0100 Subject: [PATCH] reopen log file on SIGHUP --- src/common/rclinit.cpp | 36 +++++++++++++++++-- src/common/rclinit.h | 3 ++ src/utils/debuglog.cpp | 81 +++++++++++++++++++++++++----------------- src/utils/debuglog.h | 2 ++ 4 files changed, 87 insertions(+), 35 deletions(-) diff --git a/src/common/rclinit.cpp b/src/common/rclinit.cpp index 699cfeaf..a17daff7 100644 --- a/src/common/rclinit.cpp +++ b/src/common/rclinit.cpp @@ -33,8 +33,15 @@ #include "smallut.h" #include "execmd.h" -static const int catchedSigs[] = {SIGHUP, SIGINT, SIGQUIT, SIGTERM, - SIGUSR1, SIGUSR2}; +static const int catchedSigs[] = {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2}; + +static pthread_t mainthread_id; + +static void siglogreopen(int) +{ + if (recoll_ismainthread()) + DebugLog::reopen(); +} RclConfig *recollinit(RclInitFlags flags, void (*cleanup)(void), void (*sigcleanup)(int), @@ -54,7 +61,7 @@ RclConfig *recollinit(RclInitFlags flags, // We would like to block SIGCHLD globally, but we can't because // QT uses it. Have to block it inside execmd.cpp - // Install signal handler + // Install app signal handler if (sigcleanup) { struct sigaction action; action.sa_handler = sigcleanup; @@ -105,11 +112,26 @@ RclConfig *recollinit(RclInitFlags flags, int lev = atoi(loglevel.c_str()); DebugLog::getdbl()->setloglevel(lev); } + // Install log rotate sig handler + { + struct sigaction action; + action.sa_handler = siglogreopen; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { + if (sigaction(SIGHUP, &action, 0) < 0) { + perror("Sigaction failed"); + } + } + } + // Make sure the locale charset is initialized (so that multiple // threads don't try to do it at once). config->getDefCharset(); + mainthread_id = pthread_self(); + // Init unac locking unac_init_mt(); // Init smallut and pathut static values @@ -160,5 +182,13 @@ void recoll_threadinit() for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++) sigaddset(&sset, catchedSigs[i]); + sigaddset(&sset, SIGHUP); pthread_sigmask(SIG_BLOCK, &sset, 0); } + +bool recoll_ismainthread() +{ + return pthread_equal(pthread_self(), mainthread_id); +} + + diff --git a/src/common/rclinit.h b/src/common/rclinit.h index 225db26e..82916f94 100644 --- a/src/common/rclinit.h +++ b/src/common/rclinit.h @@ -54,4 +54,7 @@ inline RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int), // The main thread handles all signals. extern void recoll_threadinit(); +// Check if main thread +extern bool recoll_ismainthread(); + #endif /* _RCLINIT_H_INCLUDED_ */ diff --git a/src/utils/debuglog.cpp b/src/utils/debuglog.cpp index bfdc6f06..7f0fe360 100644 --- a/src/utils/debuglog.cpp +++ b/src/utils/debuglog.cpp @@ -35,6 +35,7 @@ using std::string; #include "debuglog.h" #include "pathut.h" #include "smallut.h" +#include "ptmutex.h" #ifndef freeZ #define freeZ(X) {if (X) {free(X);X=0;}} @@ -57,17 +58,6 @@ class DebugLogWriter { virtual int put(const char *s) = 0; }; -class DLFWImpl; -class DebugLogFileWriter : public DebugLogWriter { - DLFWImpl *impl; - public: - DebugLogFileWriter(); - ~DebugLogFileWriter(); - virtual const char *getfilename(); - virtual int setfilename(const char *fname, int trnc = 1); - virtual int put(const char *s); -}; - class DLFWImpl { char *filename; FILE *fp; @@ -116,7 +106,9 @@ class DLFWImpl { public: - DLFWImpl() : filename(0), fp(0), truncate(1) { + DLFWImpl() + : filename(0), fp(0), truncate(1) + { setfilename("stderr", 0); } ~DLFWImpl() { @@ -126,6 +118,7 @@ class DLFWImpl { maybeclosefp(); filename = strdup(fn); truncate = trnc; + maybeopenfp(); return 0; } const char *getfilename() { @@ -139,30 +132,46 @@ class DLFWImpl { } }; -DebugLogFileWriter::DebugLogFileWriter() -{ - impl = new DLFWImpl; -} +class DebugLogFileWriter : public DebugLogWriter { + DLFWImpl *impl; + PTMutexInit loglock; + public: + DebugLogFileWriter() + { + impl = new DLFWImpl; + } -DebugLogFileWriter::~DebugLogFileWriter() -{ - delete impl; -} + virtual ~DebugLogFileWriter() + { + delete impl; + } -int DebugLogFileWriter::setfilename(const char *fn, int trnc) { - return impl ? impl->setfilename(fn, trnc) : -1; -} - -const char *DebugLogFileWriter::getfilename() -{ - return impl ? impl->getfilename() : 0; -} - -int DebugLogFileWriter::put(const char *s) -{ - return impl ? impl->put(s) : -1; + virtual int setfilename(const char *fn, int trnc) + { + PTMutexLocker lock(loglock); + return impl ? impl->setfilename(fn, trnc) : -1; + } + virtual const char *getfilename() + { + PTMutexLocker lock(loglock); + return impl ? impl->getfilename() : 0; + } + virtual int reopen() + { + PTMutexLocker lock(loglock); + if (!impl) + return -1; + string fn = impl->getfilename(); + return impl->setfilename(fn.c_str(), 1); + } + virtual int put(const char *s) + { + PTMutexLocker lock(loglock); + return impl ? impl->put(s) : -1; + }; }; + static set yesfiles; static void initfiles() { @@ -300,15 +309,23 @@ void DebugLog::poplevel() ////////////////////////////////////// static DebugLogFileWriter lwriter; static DebugLogFileWriter *theWriter = &lwriter; + const char *getfilename() { return theWriter ? theWriter->getfilename() : 0; } + int setfilename(const char *fname, int trnc) { return theWriter ? theWriter->setfilename(fname, trnc) : -1; } +int reopen() +{ + return theWriter ? theWriter->reopen() : -1; + +} + #if DEBUGLOG_USE_THREADS #include static pthread_key_t dbl_key; diff --git a/src/utils/debuglog.h b/src/utils/debuglog.h index 65a60835..04921bc6 100644 --- a/src/utils/debuglog.h +++ b/src/utils/debuglog.h @@ -66,6 +66,8 @@ class DebugLog { extern DebugLog *getdbl(); extern const char *getfilename(); extern int setfilename(const char *fname, int trnc = 1); +extern int reopen(); + #if STATICVERBOSITY >= DEBFATAL #define LOGFATAL(X) {if (DebugLog::getdbl()->getlevel()>=DEBFATAL){DebugLog::getdbl()->prolog(DEBFATAL,__FILE__,__LINE__) ;DebugLog::getdbl()->log X;}} #else