]> jfr.im git - irc/quakenet/newserv.git/blobdiff - core/modules.c
Don't unload modules at shutdown when we're running on Valgrind.
[irc/quakenet/newserv.git] / core / modules.c
index 4b9de8b6ac3dba4144b875b1c33ad6c314d77730..6bdd7a2ef100bf56d52694794e20687156608e9f 100644 (file)
@@ -12,6 +12,7 @@
 #include "../lib/irc_string.h"
 #include "../lib/splitline.h"
 #include "../lib/strlfunc.h"
+#include "../lib/valgrind.h"
 #include "config.h"
 #include "error.h"
 #include <stdio.h>
@@ -22,7 +23,7 @@
 
 #define DEPFILE        "modules.dep"
 
-#define MAXMODULES 100
+#define MAXMODULES 200
 
 /* Module dependency stuff.
  *
@@ -139,6 +140,7 @@ void initmoduledeps() {
         Error("core",ERR_ERROR,
                "Too many modules in dependency file; rebuild with higher MAXMODULES.  Module dependencies disabled.\n");
         clearmoduledeps();
+        fclose(fp);
         return;
       }
       
@@ -155,11 +157,14 @@ void initmoduledeps() {
           Error("core",ERR_WARNING,"Couldn't find parent module %s of %s.  Module dependencies disabled.",
                   largv[i+1],largv[0]);
           clearmoduledeps();
+          fclose(fp);
           return;
         }
         mdp->parents[i]->numchildren++; /* break the bad news */
       }
     }
+
+    fclose(fp);
     
     /* Second pass */
     for (i=0;i<knownmodules;i++) {
@@ -319,7 +324,7 @@ int isloaded(char *modulename) {
 }
 
 
-int rmmod(char *modulename) {
+int rmmod(char *modulename, int close) {
   int i,j;
   module *mods;
   struct module_dep *mdp;
@@ -335,7 +340,7 @@ int rmmod(char *modulename) {
   if ((mdp=getmoduledep(modulebuf))) {
     for (j=0;j<mdp->numchildren;j++) {
       if (isloaded(mdp->children[j]->name->content)) {
-        if (rmmod(mdp->children[j]->name->content)) {
+        if (rmmod(mdp->children[j]->name->content, close)) {
           Error("core",ERR_WARNING,"Unable to remove child module %s (depends on %s)",
                  mdp->children[j]->name->content, modulebuf);
           return 1;
@@ -353,16 +358,18 @@ int rmmod(char *modulename) {
   
   mods=(module *)(modules.content);
     
+  if (!close
 #ifdef BROKEN_DLCLOSE
-  {
+      || 1
+#endif
+     ) {
     void (*fini)();
     fini = dlsym(mods[i].handle, "__fini");
     if(!dlerror())
       fini();
-  }
-#endif
+  } else
+    dlclose(mods[i].handle);
 
-  dlclose(mods[i].handle);
   freesstring(mods[i].name);
   array_delslot(&modules,i);
 
@@ -390,19 +397,20 @@ void setreloadmark(struct module_dep *mdp) {
 void preparereload(char *modulename) {
   unsigned int i;
   struct module_dep *mdp;
-  
-  delchars(modulename,"./\\;");
+  char modulebuf[1024];
+
+  strlcpy(modulebuf, modulename, sizeof(modulebuf));
+  delchars(modulebuf,"./\\;");
   
   /* First, clear the mark off all dependant modules */
   for (i=0;i<knownmodules;i++)
     moduledeps[i].reloading=0;
 
   /* Do nothing if this module is not loaded */
-  i=getindex(modulename);
-  if (i<0)
+  if (getindex(modulebuf)<0)
     return;
     
-  if ((mdp=getmoduledep(modulename))) {
+  if ((mdp=getmoduledep(modulebuf))) {
     setreloadmark(mdp);
   }
 }
@@ -429,7 +437,7 @@ void safereloadcallback(void *arg) {
     return;
   
   preparereload(safereload_str->content);
-  rmmod(safereload_str->content);
+  rmmod(safereload_str->content, 1);
   insmod(safereload_str->content);
   reloadmarked();
 
@@ -457,7 +465,11 @@ void newserv_shutdown() {
     mods=(module *)(modules.content);
 
     strlcpy(buf, mods[0].name->content, sizeof(buf));
-    rmmod(buf);
+
+    /* Unload the module unless we're running on Valgrind -
+     * in which case unloading the module would invalidate
+     * stacktraces Valgrind has captured so far. */
+    rmmod(buf, !RUNNING_ON_VALGRIND);
   }
   
   clearmoduledeps();