static AthenaTransportLinkModule * _LoadModule(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, const char *moduleName) { PARCArrayList *newModuleList = NULL; // XXX need to dynamically load these, they're all hardwired for now if (strcasecmp(moduleName, "TCP") == 0) { newModuleList = athenaTransportLinkModuleTCP_Init(); } if (strcasecmp(moduleName, "UDP") == 0) { newModuleList = athenaTransportLinkModuleUDP_Init(); } if (strcasecmp(moduleName, "ETH") == 0) { newModuleList = athenaTransportLinkModuleETH_Init(); } if (newModuleList) { for (int index = 0; index < parcArrayList_Size(newModuleList); index++) { AthenaTransportLinkModule *athenaTransportLinkModule = parcArrayList_Get(newModuleList, index); _AddModule(athenaTransportLinkAdapter, athenaTransportLinkModule); } parcArrayList_Destroy(&newModuleList); } return _LookupModule(athenaTransportLinkAdapter, moduleName); }
static AthenaTransportLinkModule * _LoadModule(AthenaTransportLinkAdapter *athenaTransportLinkAdapter, const char *moduleName) { assertTrue(_LookupModule(athenaTransportLinkAdapter, moduleName) == NULL, "attempt to load an already loaded module"); // Derive the entry initialization name from the provided module name const char *moduleEntry; moduleEntry = _moduleNameToInitMethod(moduleName); // Check to see if the module was statically linked in. void *linkModule = RTLD_DEFAULT; ModuleInit _init = dlsym(linkModule, moduleEntry); // If not statically linked in, look for a shared library and load it from there if (_init == NULL) { // Derive the library name from the provided module name const char *moduleLibrary; moduleLibrary = _moduleNameToLibrary(moduleName); void *linkModule = dlopen(moduleLibrary, RTLD_NOW | RTLD_GLOBAL); parcMemory_Deallocate(&moduleLibrary); // If the shared library wasn't found, look for the symbol in our existing image. This // allows a link module to be linked directly into Athena without modifying the forwarder. if (linkModule == NULL) { parcLog_Error(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "Unable to dlopen %s: %s", moduleName, dlerror()); parcMemory_Deallocate(&moduleEntry); errno = ENOENT; return NULL; } _init = dlsym(linkModule, moduleEntry); if (_init == NULL) { parcLog_Error(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "Unable to find %s module _init method: %s", moduleName, dlerror()); parcMemory_Deallocate(&moduleEntry); dlclose(linkModule); errno = ENOENT; return NULL; } } parcMemory_Deallocate(&moduleEntry); // Call the initialization method. PARCArrayList *moduleList = _init(); if (moduleList == NULL) { // if the init method fails, unload the module if it was loaded parcLog_Error(athenaTransportLinkAdapter_GetLogger(athenaTransportLinkAdapter), "Empty module list returned from %s module", moduleName); if (linkModule != RTLD_DEFAULT) { dlclose(linkModule); } errno = ENOENT; return NULL; } // Process each link module instance (typically only one) for (int index = 0; index < parcArrayList_Size(moduleList); index++) { AthenaTransportLinkModule *athenaTransportLinkModule = parcArrayList_Get(moduleList, index); _AddModule(athenaTransportLinkAdapter, athenaTransportLinkModule); } parcArrayList_Destroy(&moduleList); return _LookupModule(athenaTransportLinkAdapter, moduleName); }