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
}
Beispiel #3
0
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;
  }
}