Changeset 783
- Timestamp:
- 10/14/06 09:09:59 (6 years ago)
- Location:
- branches/ithildin-scons
- Files:
-
- 1 added
- 6 edited
-
include/ithildin/hash.h (modified) (2 diffs)
-
include/ithildin/module.h (modified) (5 diffs)
-
lib/hash.c (modified) (6 diffs)
-
lib/module.c (modified) (25 diffs)
-
lib/string.c (modified) (1 diff)
-
modules/echo/SConscript (added)
-
source/main.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/ithildin-scons/include/ithildin/hash.h
r759 r783 12 12 13 13 typedef struct hashtable hashtable_t; 14 typedef int *(*hashcmp_function_t)(void *, void *, size_t); 14 15 15 16 SLIST_HEAD(hashbucket, hashent); … … 51 52 * int (*)(void *, void *, size_t). If the value is NULL then the memcmp 52 53 * function is used instead (with a little kludge-work ;) */ 53 struct msymbol *cmpsym;54 hashcmp_function_t cmpfunc; 54 55 }; 55 56 56 57 /* table management functions */ 57 hashtable_t *create_hash_table(uint32_t, size_t, size_t, int, const char *); 58 hashtable_t *create_hash_table(uint32_t, size_t, size_t, int, 59 hashcmp_function_t); 58 60 void destroy_hash_table(hashtable_t *); 59 61 int hash_insert(hashtable_t *, void *); -
branches/ithildin-scons/include/ithildin/module.h
r655 r783 29 29 SLIST_HEAD(module_savedata_list, module_savedata); 30 30 struct module_savedata { 31 char *name; /* the symbol name */32 size_t size; /* the size of the data */33 char *data; /* and the actual data */31 char *name; /* the symbol name */ 32 size_t size; /* the size of the data */ 33 char *data; /* and the actual data */ 34 34 35 35 SLIST_ENTRY(module_savedata) lp; … … 47 47 struct module_header *header; 48 48 49 char *fullpath; /* full path to file's module */ 50 char *depfile; /* full path to the file's dependency file, or NULL 51 if no file exists. */ 52 char *name; /* name of module */ 53 void *handle; /* dlopen() handle */ 49 char *fullpath; /* full path to file's module */ 50 char *name; /* name of module */ 51 void *handle; /* dlopen() handle */ 52 53 char *conffile; /* full path to the module's 54 configuration file, or NULL if it 55 does not exist */ 54 56 conf_list_t *confdata; 57 event_t *conf_reload; /* called when module configuration 58 is reloaded */ 59 60 55 61 module_load_function load_function; 56 62 module_unload_function unload_function; … … 115 121 struct module_savedata_list *savelist __UNUSED) 116 122 117 /* this macro should be used in the module loader function to export necessary118 * symbols */119 #define EXPORT_SYM(sym) export_symbol(#sym, module)120 121 123 /* and these two are wrappers on the 'savedata' functions below that take a 122 124 * symbol and do all the necessary legwork to add/restore it */ … … 143 145 void *); 144 146 145 /* msymbol definitions */146 typedef struct msymbol msymbol_t;147 struct msymbol {148 char name[32]; /* 31 characters worth of significant name info. if149 this isn't enough it can be changed later.. */150 void *val; /* the value of the symbol */151 module_t *module; /* the module which owns this symbol */152 153 LIST_ENTRY(msymbol) lp;154 };155 156 msymbol_t *export_symbol(char *, module_t *);157 msymbol_t *import_symbol(char *);158 #ifdef DEBUG159 # define getsym(sym) \160 ((sym->module != NULL && sym->module->handle == NULL) ? \161 (log_error("referenced unavailable symbol %s from module %s", sym->name, \162 sym->module->name)), (void *)NULL : sym->val)163 #else164 # define getsym(sym) (sym->val)165 #endif166 167 147 /* mdext stuff */ 168 148 typedef char **(*mdext_iter_function)(char **); … … 186 166 * convenience a void ** referring to the last item it worked on. This 187 167 * will be NULL at first. */ 188 m symbol_t *iter;168 mdext_iter_function iter; 189 169 }; 190 170 191 171 /* mdext management functions */ 192 struct mdext_header *create_mdext_header( const char *);172 struct mdext_header *create_mdext_header(mdext_iter_function); 193 173 void destroy_mdext_header(struct mdext_header *); 194 174 struct mdext_item *create_mdext_item(struct mdext_header *, size_t); -
branches/ithildin-scons/lib/hash.c
r761 r783 16 16 static void resize_hash_table(hashtable_t *table, uint32_t elems); 17 17 static unsigned int hash_get_key_hash(hashtable_t *, void *, size_t); 18 19 /* Set a minimum size for hastables. Tables smaller than this are not 20 * likely to be worth the overhead required to maintain them, in terms of 21 * saved CPU cycles vs. the size of the table. If you're seeing messages 22 * about hashtable size adjustment because you're asking for a table that's 23 * too small.. this is why. :) */ 24 #define MINIMUM_HASHTABLE_SIZE 64 /* must be a power of two! */ 18 25 19 26 /* … … 34 41 */ 35 42 hashtable_t *create_hash_table(uint32_t elems, size_t offset, size_t len, 36 int flags, const char *cmpname) {43 int flags, hashcmp_function_t cmpfunc) { 37 44 hashtable_t *htp = malloc(sizeof(hashtable_t)); 38 uint32_t real_elems = 0x80;45 uint32_t real_elems = MINIMUM_HASHTABLE_SIZE; 39 46 40 47 /* Take elems and begin shifting real_elems to the left until it is … … 67 74 #endif 68 75 htp->flags = flags; 69 if (cmpname != NULL) 70 htp->cmpsym = import_symbol((char *) cmpname); 71 else 72 htp->cmpsym = import_symbol("memcmp"); 76 if (cmpfunc != NULL) 77 htp->cmpfunc = cmpfunc; 78 else { 79 if (htp->flags & HASH_FL_STRING) { 80 if (htp->flags & HASH_FL_NOCASE) 81 htp->cmpfunc = (hashcmp_function_t)strncasecmp; 82 else 83 htp->cmpfunc = (hashcmp_function_t)strncmp; 84 } else 85 htp->cmpfunc = (hashcmp_function_t)memcmp; 86 } 73 87 74 88 htp->table = malloc(sizeof(struct hashbucket) * htp->size); … … 374 388 struct hashbucket *bucket = &table->table[hash]; 375 389 struct hashent *hep; 376 int (*cmpfunc)(void *, void *, size_t) =377 (int (*)(void *, void *, size_t))getsym(table->cmpsym);378 390 379 391 SLIST_FOREACH(hep, bucket, lp) { 380 if (hep->hv == hash && !cmpfunc(&((char *)hep->ent)[table->keyoffset], 381 key, table->keylen)) 392 if (hep->hv == hash && 393 !table->cmpfunc(&((char *)hep->ent)[table->keyoffset], key, 394 table->keylen)) 382 395 return hep->ent; 383 396 } … … 397 410 struct hashbucket *bucket = &table->table[hash]; 398 411 struct hashent *hep; 399 int (*cmpfunc)(void *, void *, size_t) =400 (int (*)(void *, void *, size_t))getsym(table->cmpsym);401 412 402 413 SLIST_FOREACH(hep, bucket, lp) { 403 if (hep->hv == hash && !cmpfunc(&((char *)hep->ent)[table->keyoffset], 404 key, table->keylen)) 414 if (hep->hv == hash && 415 !table->cmpfunc(&((char *)hep->ent)[table->keyoffset], key, 416 table->keylen)) 405 417 return hep; 406 418 } … … 413 425 struct hashent *ent) { 414 426 struct hashent *hep = ent; 415 int (*cmpfunc)(void *, void *, size_t) =416 (int (*)(void *, void *, size_t))getsym(table->cmpsym);417 427 418 428 /* we know where we are .. */ 419 429 while ((hep = SLIST_NEXT(hep, lp)) != NULL) { 420 if (! cmpfunc(&((char *)hep->ent)[table->keyoffset], key,430 if (!table->cmpfunc(&((char *)hep->ent)[table->keyoffset], key, 421 431 table->keylen)) 422 432 return hep; -
branches/ithildin-scons/lib/module.c
r761 r783 18 18 #endif 19 19 20 /* filename extension for modules, will become variable when multiple 21 * platforms become supported. */ 22 #define MODULE_EXTENSION ".so" 23 20 24 /* create a module structure. */ 21 static module_t *create_module(char *name); 25 static module_t *add_module_from_config(conf_entry_t *); 26 static module_t *create_module(char *); 22 27 static void destroy_module(module_t *); 23 24 static LIST_HEAD(, msymbol) msym_list;25 static msymbol_t *find_msymbol(char *);26 28 27 29 /* this is called both at start-up and at any time when the conf is reloaded … … 29 31 void build_module_list(void) { 30 32 conf_list_t *list = conf_find_list("modules", me.confhead, 1); 31 conf_list_t *clp = NULL;32 33 conf_entry_t *cep = NULL, *oldcep; 33 34 module_t *m = NULL; 34 module_t *last = NULL; /* track our last addition */ 35 char *s = NULL; 35 module_t *last = NULL; 36 36 37 37 if (list == NULL) { … … 47 47 /* now pull in each load statement and parse it */ 48 48 while (cep != NULL) { 49 do { /* use a do/while loop so we can 'break' from it without making 50 life miserable or using silly gotos */ 51 int new = 0; 52 if (cep->type == CONF_TYPE_LIST) { 53 /* check the 'string' value first, before checking the file 54 * value. */ 55 clp = cep->list; 56 if (cep->string != NULL) 57 s = cep->string; 58 else { 59 s = conf_find_entry("file", clp, 1); 60 if (s == NULL) 61 break; 62 } 63 } else 64 s = cep->string; 65 66 m = find_module(s); 67 if (m == NULL) { 68 m = create_module(s); 69 new++; 70 } 71 if (m == NULL) 72 break; 73 74 if (cep->type == CONF_TYPE_LIST) { 75 m->confdata = conf_find_list("data", clp, 1); 76 if ((s = conf_find_entry("load", clp, 1)) != NULL && 77 str_conv_bool(s, false)) 78 m->flags |= MODULE_FL_AUTOLOAD; 79 else 80 m->flags |= MODULE_FL_AUTOLOAD; /* default is to load. */ 81 if (str_conv_bool(conf_find_entry("export", clp, 1), 0)) 82 m->flags |= MODULE_FL_DEPENDLOAD; 83 if (cep->string != NULL) { 84 free(m->name); 85 m->name = strdup(cep->string); 86 } 87 } else { 88 /* We just got "module foo;" I bet they want to autoload 89 * it, so let's try that. */ 90 m->confdata = NULL; 91 m->flags |= MODULE_FL_AUTOLOAD; 92 } 93 94 if (new) { 95 if (last == NULL) 96 LIST_INSERT_HEAD(&me.modules, m, lp); 97 else 98 LIST_INSERT_AFTER(last, m, lp); 99 100 last = m; 101 } 102 } while (0); /* just a once-through, heh */ 49 m = add_module_from_config(cep); 103 50 oldcep = cep = conf_find_next("module", NULL, 0, oldcep, list, 1); 51 52 if (m == NULL) 53 continue; /* no need to add it to the list.. */ 54 if (last == NULL) 55 LIST_INSERT_HEAD(&me.modules, m, lp); 56 else 57 LIST_INSERT_AFTER(last, m, lp); 58 last = m; 104 59 } 105 60 … … 114 69 } 115 70 71 static module_t *add_module_from_config(conf_entry_t *cep) { 72 conf_list_t *clp = NULL; 73 module_t *m; 74 bool new = false; 75 char *s = NULL; 76 77 if (cep->type == CONF_TYPE_LIST) { 78 /* check the 'string' value first, before checking the file 79 * value. */ 80 clp = cep->list; 81 if (cep->string != NULL) 82 s = cep->string; 83 else { 84 s = conf_find_entry("file", clp, 1); 85 if (s == NULL) { 86 log_warn("module with no name configured"); 87 return NULL; 88 } 89 } 90 } else 91 s = cep->string; 92 93 m = find_module(s); 94 if (m == NULL) { 95 m = create_module(s); 96 new = true; 97 } 98 if (m == NULL) 99 return NULL; 100 101 if (clp != NULL) { 102 if ((s = conf_find_entry("config", clp, 1)) != NULL) { 103 /* try to access their config file as specified, if it does not 104 * come with a path prefix, we try prepending the conf 105 * directory, then with the full pathname make sure we can load 106 * the conf. if we can't we won't load the module */ 107 m->conffile = malloc(PATH_MAX); 108 if (*s != 's') /* XXX: this will suck come windows support time */ 109 snprintf(m->conffile, PATH_MAX, "%s/%s", me.conf_path, s); 110 else 111 strlcpy(m->conffile, s, PATH_MAX); 112 113 } 114 115 if ((s = conf_find_entry("load", clp, 1)) != NULL && 116 str_conv_bool(s, false)) 117 m->flags |= MODULE_FL_AUTOLOAD; 118 else 119 m->flags |= MODULE_FL_AUTOLOAD; /* default is to load. */ 120 121 /* allow module name to be overwritten (not sure why we'd want this, 122 * but let's see if it helps.. */ 123 if (cep->string != NULL) { 124 free(m->name); 125 m->name = strdup(cep->string); 126 } 127 } else { 128 /* We just got "module foo;" I bet they want to autoload 129 * it, so let's try that. */ 130 m->flags |= MODULE_FL_AUTOLOAD; 131 132 /* let's also take a stab at guessing their module config file name. 133 * We try two things: $confdir/modulename.conf and 134 * $confdir/modulename/modulename.conf. If neither works we do not 135 * make any further efforts. We determine the usability of these 136 * files through the access() call. */ 137 s = malloc(PATH_MAX); 138 snprintf(s, PATH_MAX, "%s/%s.conf", me.conf_path, m->name); 139 if (access(s, R_OK) == 0) 140 m->conffile = s; 141 else { 142 /* don't try the directory method if the module name already 143 * contains slashes (indicating it is subdirectory-ized already) */ 144 if (!strchr(s, '/')) { 145 snprintf(s, PATH_MAX, "%s/%s/%s.conf", me.conf_path, m->name, 146 m->name); 147 if (access(s, R_OK) == 0) 148 m->conffile = s; 149 } 150 } 151 } 152 153 if (m->conffile != NULL) { 154 if ((m->confdata = read_conf(m->conffile)) == NULL) { 155 log_error("could not parse config for module %s, not loading it.", 156 m->name); 157 destroy_module(m); 158 return NULL; 159 } 160 } 161 162 if (new) 163 return m; 164 165 return NULL; 166 } 167 116 168 /* this function unloads all modules rather indiscriminately. it just starts 117 169 * at the top of the load and starts dropping them. */ … … 125 177 } 126 178 127 /* this function handles all the necessary work to load a module. it first 128 * checks for a .deps file in the same place as the module, and if one exists, 129 * opens it and loads all dependencies listed therein. then it opens the dll, 130 * checks version headers, and calls the module's loader function. */ 179 /* this function handles all the necessary work to load a module. it opens the 180 * dll, checks version headers, loads dependencies, then calls the module's 181 * loader function (in that order). */ 131 182 int load_module(char *name, int flags) { 132 183 module_t *m = NULL; 133 /* initially, we don't resolve symbols, we will run another dlopen call 134 * when our dependancies are loaded with RTLD_NOW to ensure that things 135 * work as they should */ 184 /* never ask for explicit symbol resolution. every library a module 185 * depends on should be *already linked against* the module in question. 186 * we do not provide symbol help (because it is not reliably 187 * cross-platform) */ 136 188 int rtld_flags = RTLD_NOW; 137 189 char fn[33]; /* used for making function names */ 138 190 char *sn; /* short name */ 139 FILE *fp;140 191 struct module_savedata *msdp; 141 192 struct module_dependency *mdep; 142 msymbol_t *msym;193 char **deplist = NULL; 143 194 144 195 if ((m = find_module(name)) == NULL) { … … 165 216 log_notice("loading module %s...", m->name); 166 217 167 /* load dependcies. before we do, attest to the open-ness of this module. 168 * this isn't, technically, true, since we haven't initialized it. 169 * however, that can't be helped in the case of circular dependencies. 170 * this is simply a tough area... since we don't even do the dlopen() 171 * before we do the load_modules call, if you've got a circular dependency 172 * that won't survive on a lazy load, you're up the creek. sorry. */ 173 if (m->depfile != NULL && !(m->flags & MODULE_FL_LOADED)) { 174 char sname[PATH_MAX]; 175 176 m->flags |= MODULE_FL_LOADED; 177 fp = fopen(m->depfile, "r"); 178 if (fp != NULL) { 179 while ((sn = sfgets(sname, PATH_MAX, fp)) != NULL) { 180 module_t *m2 = find_module(sn); 181 182 /* okay, depending on what's going on here, we do different 183 * things. if the module is reloading and a dependency isn't 184 * loaded yet, we just return quietly because we assume we'll 185 * get called later (see down towards the bottom of this 186 * function), otherwise if we can't load that dependency, 187 * return an error. */ 188 if ((m2 == NULL || !(m2->flags & MODULE_FL_DEPENDLOAD))) { 189 if (m2 == NULL) 190 log_debug("loading dependant module %s for %s", 191 sn, name); 192 #if 0 193 if (m->flags & MODULE_FL_RELOADING) { 194 /* aaaaactually. we only return if the module already 195 * exists and is *also* reloading, this way a reload 196 * with a module that has new dependencies will still 197 * work! :) */ 198 if (m2 != NULL && m2->flags & MODULE_FL_RELOADING) { 199 m->flags &= ~MODULE_FL_LOADED; 200 fclose(fp); 201 return 0; /* waiting.. */ 202 } 203 } 204 #endif 205 if (!load_module(sn, flags | MODULE_FL_DEPENDLOAD | 206 MODULE_FL_CREATE | MODULE_FL_QUIET)) { 207 log_error( 208 "loading dependant failed, giving up for %s!", 209 sn); 210 fclose(fp); 211 return 0; 212 } 213 } 214 215 /* loaded? add our current module to this new module's 216 * dependency listing. */ 217 m2 = find_module(sn); 218 mdep = malloc(sizeof(struct module_dependency)); 219 mdep->mod = m; 220 LIST_INSERT_HEAD(&m2->deps, mdep, lp); 221 222 } 223 fclose(fp); 224 } 225 m->flags &= ~MODULE_FL_LOADED; /* undo this trickery. */ 226 } 227 228 /* check dependencies here */ 218 /* if we are being depend loaded make sure the module is set that way, 219 * if we've already been depend-loaded once we don't bother to go 220 * through the rest of the motions below. */ 229 221 if (flags & MODULE_FL_DEPENDLOAD) { 230 222 if (m->flags & MODULE_FL_DEPENDLOAD && m->flags & MODULE_FL_LOADED) 231 223 return 1; /* already depend loaded */ 232 //rtld_flags |= RTLD_GLOBAL;233 224 m->flags |= MODULE_FL_DEPENDLOAD; 234 225 } … … 244 235 return 1; 245 236 237 /* *********************************************************************** 238 * from this point on we are assured that m->opencalls is 1, that is, 239 * that this is our first try at loading the module, so any failures can 240 * safely be used to destroy the module/dlclose it/etc. 241 * ***********************************************************************/ 242 246 243 m->header = (struct module_header *)dlsym(m->handle, "mheader"); 247 244 if (m->header == NULL) { … … 252 249 } 253 250 251 deplist = (char **)dlsym(m->handle, "mdepends"); 252 254 253 sn = strrchr(m->name, '/'); 255 254 if (sn == NULL) … … 260 259 snprintf(fn, 32, "%s_loader", sn); 261 260 m->load_function = (module_load_function)dlsym(m->handle, fn); 262 snprintf(fn, 32, "%s_unloader", sn);263 m->unload_function = (module_unload_function)dlsym(m->handle, fn);264 261 265 262 /* Refuse to load modules compiled to use a module API version either … … 274 271 m->header->baseversion.revision, 275 272 MODULE_API_VERSION, MODULE_API_REVISION); 276 dlclose(m->handle); 277 m->opencalls = 0; 273 unload_module(m->name); 278 274 return 0; 279 275 } else if (m->header->baseversion.revision < MODULE_API_REVISION) { … … 285 281 } /* ugh, okay, it's an alright version :) */ 286 282 287 /* go ahead and say it's loaded now, so that if it tries to load other 288 * modules it will be okay. */ 283 /* load dependcies. before we do, attest to the open-ness of this module. 284 * this isn't, technically, true, since we haven't initialized it. 285 * however, that can't be helped in the case of circular dependencies. 286 * this is simply a tough area because they will try to load this module 287 * and.. well.. we'll be right back here! :/ */ 289 288 m->flags |= MODULE_FL_LOADED | flags; 289 290 while (deplist != NULL && *deplist != NULL) { 291 module_t *m2 = find_module(*deplist); 292 if (m2 == NULL || !(m2->flags & MODULE_FL_DEPENDLOAD)) { 293 if (m2 == NULL) 294 log_notice("loading dependant module %s for %s", *deplist, name); 295 if (!load_module(*deplist, flags | MODULE_FL_DEPENDLOAD | 296 MODULE_FL_CREATE | MODULE_FL_QUIET)) { 297 log_error("loading dependant failed, giving up for %s!", name); 298 unload_module(m->name); 299 return 0; 300 } 301 m2 = find_module(*deplist); 302 } 303 /* m2 now definitely exists (yay) */ 304 mdep = malloc(sizeof(struct module_dependency)); 305 mdep->mod = m; 306 LIST_INSERT_HEAD(&m2->deps, mdep, lp); 307 deplist++; /* and onto the next one */ 308 } 309 290 310 291 311 /* okay, hopefully this will stay here. I've decided to hook the 292 312 * 'load_module' event prior to load function being called so that other 293 313 * subsystems can do any data setup necessary that the load function might 294 * wish to rely on. hope this works. ;) */ 314 * wish to rely on. hope this works. ;) this kind of sucks because it 315 * might be totally false if the loader errors out. I'm not sure how to 316 * resolve this one, maybe we should hook the unload event right after? 317 * Hrmm... */ 295 318 hook_event(me.events.load_module, m->name); 296 319 … … 298 321 if (!m->load_function((m->flags & MODULE_FL_RELOADING ? 1 : 0), 299 322 &m->savedata, &m->confdata, m)) { 300 /* okay, it broke...clean up and go home */ 301 dlclose(m->handle); 302 m->opencalls = 0; 303 m->flags &= ~MODULE_FL_LOADED; 323 unload_module(m->name); 304 324 log_error("failed to load module %s", m->name); 305 325 return 0; 306 326 } 307 327 } 328 329 /* lookup and set the unload function late so that it cannot be used by 330 * unload_module() when we call it above in failure cases. */ 331 snprintf(fn, 32, "%s_unloader", sn); 332 m->unload_function = (module_unload_function)dlsym(m->handle, fn); 308 333 309 334 /* go ahead and take care of destroying the saved data for them */ … … 314 339 free(msdp->name); 315 340 free(msdp); 316 }317 318 /* fix symbol exports */319 LIST_FOREACH(msym, &msym_list, lp) {320 if (msym->module == m) {321 msym->val = dlsym(m->handle, msym->name);322 if (msym->val == NULL)323 log_error("yipes! invalidated module symbol %s(%s)",324 msym->name, m->name);325 }326 341 } 327 342 … … 372 387 module_t *m2; 373 388 struct module_dependency *mdep, *mdep2; 374 msymbol_t *msym;375 389 376 390 if (m == NULL) { … … 440 454 } 441 455 442 /* nullify symbols */443 LIST_FOREACH(msym, &msym_list, lp) {444 if (msym->module == m)445 msym->val = NULL;446 }447 448 456 /* now for each of our modules, if they have a dependency for this module, 449 457 * remove it from their listing. */ … … 540 548 m->name = strdup(name); 541 549 /* strip off the extension */ 542 s = strrchr(m->name, '.'); 543 if (s != NULL) { 544 if (!strcmp(s, ".so")) 545 *s = '\0'; 546 } 547 /* check to see if there's a dependncies file */ 548 sprintf(m->fullpath, "%s/%s.deps", me.lib_path, m->name); 549 if (access(m->fullpath, R_OK) != -1) 550 m->depfile = strdup(m->fullpath); 551 else 552 m->depfile = NULL; 553 sprintf(m->fullpath, "%s/%s.so", me.lib_path, m->name); 554 if (access(m->fullpath, R_OK) == -1) { 550 if (MODULE_EXTENSION[0]) { 551 s = strrchr(m->name, MODULE_EXTENSION[0]); 552 if (s != NULL) { 553 if (!strcmp(s, MODULE_EXTENSION)) 554 *s = '\0'; 555 } 556 } 557 558 sprintf(m->fullpath, "%s/%s" MODULE_EXTENSION, me.lib_path, m->name); 559 if (access(m->fullpath, R_OK | X_OK) == -1) { 555 560 log_error("unable to open module %s from %s: %s", m->name, 556 561 m->fullpath, strerror(errno)); 557 if (m->depfile != NULL) 558 free(m->depfile); 559 free(m->name); 560 free(m); 562 destroy_module(m); 561 563 return NULL; 562 564 } … … 566 568 static void destroy_module(module_t *mod) { 567 569 568 LIST_REMOVE(mod, lp); 570 /* only remove it if it's in the list */ 571 if (find_module(mod->name) != NULL) 572 LIST_REMOVE(mod, lp); 569 573 free(mod->name); 570 574 free(mod->fullpath); 571 if (mod->depfile != NULL) 572 free(mod->depfile); 575 if (mod->conffile != NULL) 576 free(mod->conffile); 577 if (mod->confdata != NULL) 578 destroy_conf_branch(mod->confdata); 573 579 free(mod); 574 }575 576 /* module symbol stuffs. */577 static msymbol_t *find_msymbol(char *name) {578 msymbol_t *msp;579 580 LIST_FOREACH(msp, &msym_list, lp) {581 if (!strcmp(msp->name, name))582 return msp;583 }584 585 return NULL;586 }587 588 /* this function 'exports' a symbol (basically, creates an msymbol structure589 * for it, and finds it, etc. it can be called by import_msymbol, and is590 * basically useful as a 'pre-declare' call. */591 msymbol_t *export_symbol(char *name, module_t *mod) {592 msymbol_t *msp;593 void *obj = NULL;594 595 if (mod != NULL && !(mod->flags & MODULE_FL_LOADED)) {596 log_error("export_symbol(%s, %s) called with unloaded module.",597 name, mod->name);598 return NULL; /* blech. */599 }600 601 msp = find_msymbol(name);602 if (msp != NULL && msp->module != mod) {603 log_warn("attempt to overwrite msymbol %s(%s)", msp->name,604 msp->module->name);605 return msp; /* hm..? */606 }607 608 if (msp == NULL) {609 msp = malloc(sizeof(msymbol_t));610 LIST_INSERT_HEAD(&msym_list, msp, lp);611 }612 613 strlcpy(msp->name, name, sizeof(msp->name));614 if (mod != NULL) {615 /* they told us where to get it from.. */616 if ((obj = dlsym(mod->handle, msp->name)) == NULL) {617 log_warn("export_symbol(%s, %s): could not find symbol", msp->name,618 mod->name);619 LIST_REMOVE(msp, lp);620 free(msp);621 return NULL;622 }623 msp->module = mod;624 msp->val = obj;625 return msp;626 } else {627 /* try the modules we know of first */628 mod = LIST_FIRST(&me.modules);629 while (obj == NULL && mod != NULL) {630 if (mod->flags & MODULE_FL_LOADED) {631 if ((obj = dlsym(mod->handle, msp->name)) != NULL)632 break;633 }634 mod = LIST_NEXT(mod, lp);635 }636 if (obj == NULL) {637 /* no luck? try RTLD_DEFAULT.. Actually, try NULL (the executable638 * itself), then RTLD_NEXT (all the shared modules loaded by the639 * executable .. which is actually more than we want, but will get640 * us to compile-time linked libraries when nothing else will) */641 mod = NULL;642 if ((obj = dlsym(NULL, msp->name)) == NULL)643 obj = dlsym(RTLD_NEXT, msp->name);644 }645 }646 if (obj == NULL) {647 log_warn("export_symbol(%s): could not find symbol", msp->name);648 LIST_REMOVE(msp, lp);649 free(msp);650 return NULL;651 }652 msp->module = mod;653 msp->val = obj;654 655 return msp;656 }657 658 /* this function is considerably simpler. do a symbol lookup to see if we659 * already know of this symbol, if we do then pass it back to the caller,660 * otherwise try to get it from an export, then return the final value. */661 msymbol_t *import_symbol(char *name) {662 msymbol_t *msp;663 664 msp = find_msymbol(name);665 if (msp == NULL)666 msp = export_symbol(name, NULL);667 668 return msp;669 580 } 670 581 … … 678 589 * mdext data. */ 679 590 680 #define mdext_realloc(header, data) do { \681 if (header->size != 0) \682 data = realloc(data, header->size); \683 else { \684 if (data != NULL) \685 free(data); \686 data = NULL; \687 } \591 #define mdext_realloc(header, data) do { \ 592 if (header->size != 0) \ 593 data = realloc(data, header->size); \ 594 else { \ 595 if (data != NULL) \ 596 free(data); \ 597 data = NULL; \ 598 } \ 688 599 } while (0) 689 600 … … 691 602 * type, not per structure. this is used as the head of the tracking data for 692 603 * that structure. */ 693 struct mdext_header *create_mdext_header( const char *iter) {604 struct mdext_header *create_mdext_header(mdext_iter_function iter) { 694 605 struct mdext_header *mdhp = NULL; 695 606 … … 697 608 mdhp->create = create_event(EVENT_FL_NORETURN); 698 609 mdhp->destroy = create_event(EVENT_FL_NORETURN); 699 mdhp->iter = i mport_symbol((char *) iter);610 mdhp->iter = iter; 700 611 701 612 return mdhp; … … 725 636 char **data; 726 637 char *rhold = NULL; /* data held for iter */ 727 mdext_iter_function iter = (mdext_iter_function)getsym(header->iter);728 638 729 639 mip = calloc(1, sizeof(struct mdext_item)); … … 734 644 735 645 /* go through and resize everything. also, zero-fill our new section. */ 736 while ((data = iter(&rhold)) != NULL) {646 while ((data = header->iter(&rhold)) != NULL) { 737 647 mdext_realloc(header, *data); 738 648 memset(*data + mip->offset, 0, mip->size); … … 750 660 char **data; 751 661 char *rhold = NULL; /* data held for iter */ 752 mdext_iter_function iter = (mdext_iter_function)getsym(header->iter);753 662 754 663 SLIST_FOREACH(mip, &header->items, lp) { … … 772 681 * total size (making this the last item)) then do so. */ 773 682 if (mip->offset + mip->size != header->size) { 774 while ((data = iter(&rhold)) != NULL)683 while ((data = header->iter(&rhold)) != NULL) 775 684 memmove(*data + mip->offset, *data + (mip->offset + mip->size), 776 685 (header->size - mip->offset - mip->size)); … … 778 687 header->size -= mip->size; 779 688 rhold = NULL; 780 while ((data = iter(&rhold)) != NULL)689 while ((data = header->iter(&rhold)) != NULL) 781 690 mdext_realloc(header, *data); 782 691 -
branches/ithildin-scons/lib/string.c
r761 r783 387 387 return def; 388 388 389 if (!strcasecmp(str, "yes") || !strcasecmp(str, "on") || atoi(str)) 389 if (!strcasecmp(str, "yes") || !strcasecmp(str, "on") || 390 !strcasecmp(str, "true") || atoi(str) == 1) 390 391 return 1; 391 else if (!strcasecmp(str, "no") || !strcasecmp(str, "off") || !atoi(str)) 392 else if (!strcasecmp(str, "no") || !strcasecmp(str, "off") || 393 !strcasecmp(str, "false") || atoi(str) == 0) 392 394 return 0; 393 395 -
branches/ithildin-scons/source/main.c
r764 r783 339 339 } 340 340 341 HOOK_FUNCTION(reload_conf) {342 char currdir[PATH_MAX];343 conf_list_t *newconf = NULL;344 conf_list_t *oldconf = NULL;345 346 getcwd(currdir, PATH_MAX);347 if (chdir(me.conf_path)) {348 log_error("couldn't chdir to conf directory %s while reloading conf ",349 me.conf_path);350 return NULL;351 }352 newconf = read_conf(me.conf_file);353 if (newconf == NULL) {354 log_error("couldn't read configuration file %s while reloading conf!",355 me.conf_file);356 return NULL;357 }358 chdir(currdir);359 360 oldconf = me.confhead;361 me.confhead = newconf;362 build_module_list(); /* rebuild the module list */363 hook_event(me.events.read_conf, (void *)me.confhead);364 destroy_conf_branch(oldconf);365 log_notice("reloaded configuration file %s/%s", me.conf_path,366 me.conf_file);367 368 return NULL;369 }370 371 /* eventually aborting existence should consist of more cleanup, right now372 * all we do is destroy all our sockets. probably what I should do is write373 * a *_shutdown function for each subsystem. later. */374 HOOK_FUNCTION(exit_process) {375 struct isocket *sp;376 377 /* if this function is called pre-shutdown, simply set the shutdown flag,378 * we will get called again later to do cleanup. */379 if (me.shutdown == 0) {380 me.shutdown = -1;381 return NULL;382 }383 384 /* unload all our modules */385 unload_all_modules();386 387 /* free our conf stuff */388 destroy_conf_branch(me.confhead);389 390 /* thrash all our sockets */391 reap_dead_sockets();392 LIST_FOREACH(sp, &allsockets, intlp) {393 destroy_socket(sp);394 }395 reap_dead_sockets();396 397 #ifdef HAVE_OPENSSL398 if (me.ssl.enabled)399 ERR_free_strings();400 #endif401 402 exit(0);403 return NULL; /* NOTREACHED */404 }405 406 341 void sighandler_generic(int sig) { 407 342 switch (sig) {
Note: See TracChangeset
for help on using the changeset viewer.
