From 19f8866bb1bbccd0abd18838251d242c1b81b7cc Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 26 Feb 2008 14:09:08 +0000 Subject: bugfix: rsyslogd segfaulted on second SIGHUP tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=38 --- modules.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) (limited to 'modules.c') diff --git a/modules.c b/modules.c index 5c252dd3..568ea768 100644 --- a/modules.c +++ b/modules.c @@ -348,33 +348,69 @@ rsRetVal modUnloadAndDestructAll(void) moduleDestruct(pModPrev); } + /* indicate list is now empty */ + pLoadedModules = NULL; + pLoadedModulesLast = NULL; + RETiRet; } +/* unlink and destroy a module. The caller must provide a pointer to the module + * itself as well as one to its immediate predecessor. + * rgerhards, 2008-02-26 + */ +static rsRetVal +modUnlinkAndDestroy(modInfo_t *pThis, modInfo_t *pPrev) +{ + DEFiRet; + + /* we need to unlink the module before we can destruct it -- rgerhards, 2008-02-26 */ + if(pPrev == NULL) { + /* module is root, so we need to set a new root */ + pLoadedModules = pThis->pNext; + } else { + pPrev->pNext = pThis->pNext; + } + + /* check if we need to update the "last" pointer */ + if(pLoadedModulesLast == pThis) { + pLoadedModulesLast = pPrev; + } + + /* finally, we are ready for the module to go away... */ + dbgprintf("Unloading module %s\n", modGetName(pThis)); + modPrepareUnload(pThis); + moduleDestruct(pThis); + + RETiRet; +} + + +/* unload dynamically loaded modules + */ rsRetVal modUnloadAndDestructDynamic(void) { DEFiRet; modInfo_t *pMod; - modInfo_t *pModPrev; - - pLoadedModulesLast = NULL; + modInfo_t *pModCurr; /* module currently being processed */ + modInfo_t *pModPrev; /* last module in active linked list */ + pModPrev = NULL; /* we do not yet have a previous module */ pMod = modGetNxt(NULL); while(pMod != NULL) { - pModPrev = pMod; - pMod = modGetNxt(pModPrev); /* get next */ + pModCurr = pMod; + pMod = modGetNxt(pModCurr); /* get next */ /* now we can destroy the previous module */ - if(pModPrev->eLinkType != eMOD_LINK_STATIC) { - dbgprintf("Unloading module %s\n", modGetName(pModPrev)); - modPrepareUnload(pModPrev); - moduleDestruct(pModPrev); + if(pModCurr->eLinkType != eMOD_LINK_STATIC) { + modUnlinkAndDestroy(pModCurr, pModPrev); } else { - pLoadedModulesLast = pModPrev; + pModPrev = pModCurr; /* don't delete, so this is the new prev ptr */ } } RETiRet; } + /* vi:set ai: */ -- cgit