LmHandle loadDll( const char *containerName, const char *externalPath, LmHandle extLoader, ComUInt32 *containerSize, ComDiagsArea *da, NAMemory *heap) { #ifdef LMCOMMON_CANNOT_CALL_DLOPEN *da << DgSqlCode(-LME_INTERNAL_ERROR) << DgString0(": dlopen() is not supported"); *da << DgSqlCode(-LME_DLL_CONT_NOT_FOUND) << DgString0(containerName) << DgString1(externalPath); return NULL; #else char *libraryName = NULL; if (str_len(externalPath) == 0) externalPath = "."; libraryName = new (heap) char[str_len(externalPath) + str_len(containerName) + 2]; sprintf(libraryName, "%s/%s", externalPath, containerName); // TBD: For now, set container size to 0. Need to see how to get // the actual size if (containerSize) *containerSize = 0; // extLoader is an object of LmCLoader class. It's not used to // load the library. We can simply load the DLL. LmHandle container = NULL; const char *operation = "dlopen"; container = (LmHandle) dlopen(libraryName, RTLD_NOW | RTLD_GLOBAL); LM_DEBUG3("%s(%s) returned 0x%08x\n", operation, libraryName, container); if (container == NULL) { *da << DgSqlCode(-LME_DLL_CONT_NOT_FOUND) << DgString0(containerName) << DgString1(externalPath); addDllErrors(*da, operation, FALSE); } NADELETEBASIC(libraryName, heap); return container; #endif // LMCOMMON_CANNOT_CALL_DLOPEN }
void unloadDll(LmHandle containerHandle, ComDiagsArea *da) { if (containerHandle == NULL) return; #ifndef LMCOMMON_CANNOT_CALL_DLOPEN Int32 retcode = 0; const char *operation = "dlclose"; retcode = dlclose(containerHandle); LM_DEBUG3("%s(0x%08x) returned 0x%08x\n", operation, containerHandle, retcode); // Return a warning condition if (retcode != 0 && da) addDllErrors(*da, operation, TRUE); #endif // LMCOMMON_CANNOT_CALL_DLOPEN }
LmResult LmLanguageManagerC::getRoutine( ComUInt32 numSqlParam, LmParameter parameters[], ComUInt32 numTableInfo, LmTableInfo tableInfo[], LmParameter *returnValue, ComRoutineParamStyle paramStyle, ComRoutineTransactionAttributes transactionAttrs, ComRoutineSQLAccess sqlAccessMode, const char *parentQid, ComUInt32 inputRowLen, ComUInt32 outputRowLen, const char *sqlName, const char *externalName, const char *routineSig, const char *containerName, const char *externalPath, const char *librarySqlName, const char *currentUserName, const char *sessionUserName, ComRoutineExternalSecurity externalSecurity, Int32 routineOwnerId, LmRoutine **handle, LmHandle getNextRowPtr, LmHandle emitRowPtr, ComUInt32 maxResultSets, ComDiagsArea *diagsArea) { *handle = NULL; LmContainer *container = NULL; LmResult result = LM_OK; ComDiagsArea *da = (diagsArea != NULL) ? diagsArea : diagsArea_; // Get the requested container from the CM. result = contManager_->getContainer(containerName, externalPath, &container, da); if (result == LM_ERR) return LM_ERR; // Get a handle to the requested routine LmHandle routinePtr = NULL; routinePtr = getRoutinePtr(container->getHandle(), externalName); const char *operation = "dlsym"; if (routinePtr == NULL) { char *libraryName = new (collHeap()) char[str_len(externalPath) + str_len(containerName) + 2]; sprintf(libraryName, "%s/%s", externalPath, containerName); *da << DgSqlCode(-LME_DLL_METHOD_NOT_FOUND) << DgString0(externalName) << DgString1(libraryName); addDllErrors(*da, operation, FALSE); NADELETEBASIC(libraryName, collHeap()); return LM_ERR; } // allocate an LM handle for the external method. LmRoutine *routineHandle = NULL; if (paramStyle == COM_STYLE_SQL) { routineHandle = new (collHeap()) LmRoutineCSql(sqlName, externalName, librarySqlName, numSqlParam, (char *)routineSig, maxResultSets, transactionAttrs, sqlAccessMode, externalSecurity, routineOwnerId, parentQid, inputRowLen, outputRowLen, currentUserName, sessionUserName, parameters, this, routinePtr, container, da); } else if (paramStyle == COM_STYLE_SQLROW) { routineHandle = new (collHeap()) LmRoutineCSqlRow(sqlName, externalName, librarySqlName, numSqlParam, (char *)routineSig, maxResultSets, transactionAttrs, sqlAccessMode, externalSecurity, routineOwnerId, parentQid, inputRowLen, outputRowLen, currentUserName, sessionUserName, parameters, this, routinePtr, container, da); } else if (paramStyle == COM_STYLE_TM) { routineHandle = new (collHeap()) LmRoutineCSqlRowTM(sqlName, externalName, librarySqlName, numSqlParam, numTableInfo, tableInfo, (char *)routineSig, maxResultSets, transactionAttrs, sqlAccessMode, externalSecurity, routineOwnerId, parentQid, inputRowLen, outputRowLen, currentUserName, sessionUserName, parameters, this, routinePtr, getNextRowPtr, emitRowPtr, container, da); } else { // XXX LM_ASSERT(0); char *paramStyleMsg = new (collHeap()) char[100]; sprintf(paramStyleMsg, "Unknown ParameterStyle(%d)", paramStyle); *da << DgSqlCode(-LME_VALIDATION_FAILED) << DgString0(externalName) << DgString1(paramStyleMsg); addDllErrors(*da, operation, FALSE); } // Verify the handle. if (routineHandle == NULL) { // DiagsArea is already filled if (container) contManager_->putContainer(container); return LM_ERR; } else { *handle = routineHandle; return LM_OK; } }