tclLoadDl.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tclLoadDl.c --
  3.  *
  4.  * This procedure provides a version of the TclLoadFile that
  5.  * works with the "dlopen" and "dlsym" library procedures for
  6.  * dynamic loading.
  7.  *
  8.  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  *
  13.  * RCS: @(#) $Id: tclLoadDl.c,v 1.13.2.1 2006/06/13 22:54:01 dkf Exp $
  14.  */
  15. #include "tclInt.h"
  16. #ifdef NO_DLFCN_H
  17. #   include "../compat/dlfcn.h"
  18. #else
  19. #   include <dlfcn.h>
  20. #endif
  21. /*
  22.  * In some systems, like SunOS 4.1.3, the RTLD_NOW flag isn't defined
  23.  * and this argument to dlopen must always be 1.  The RTLD_GLOBAL
  24.  * flag is needed on some systems (e.g. SCO and UnixWare) but doesn't
  25.  * exist on others;  if it doesn't exist, set it to 0 so it has no effect.
  26.  */
  27. #ifndef RTLD_NOW
  28. #   define RTLD_NOW 1
  29. #endif
  30. #ifndef RTLD_GLOBAL
  31. #   define RTLD_GLOBAL 0
  32. #endif
  33. /*
  34.  *---------------------------------------------------------------------------
  35.  *
  36.  * TclpDlopen --
  37.  *
  38.  * Dynamically loads a binary code file into memory and returns
  39.  * a handle to the new code.
  40.  *
  41.  * Results:
  42.  * A standard Tcl completion code.  If an error occurs, an error
  43.  * message is left in the interp's result. 
  44.  *
  45.  * Side effects:
  46.  * New code suddenly appears in memory.
  47.  *
  48.  *---------------------------------------------------------------------------
  49.  */
  50. int
  51. TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
  52.     Tcl_Interp *interp; /* Used for error reporting. */
  53.     Tcl_Obj *pathPtr; /* Name of the file containing the desired
  54.  * code (UTF-8). */
  55.     Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded
  56.  * file which will be passed back to 
  57.  * (*unloadProcPtr)() to unload the file. */
  58.     Tcl_FSUnloadFileProc **unloadProcPtr;
  59. /* Filled with address of Tcl_FSUnloadFileProc
  60.  * function which should be used for
  61.  * this file. */
  62. {
  63.     VOID *handle;
  64.     CONST char *native;
  65.     /* 
  66.      * First try the full path the user gave us.  This is particularly
  67.      * important if the cwd is inside a vfs, and we are trying to load
  68.      * using a relative path.
  69.      */
  70.     native = Tcl_FSGetNativePath(pathPtr);
  71.     handle = dlopen(native, RTLD_NOW | RTLD_GLOBAL);
  72.     if (handle == NULL) {
  73. /* 
  74.  * Let the OS loader examine the binary search path for
  75.  * whatever string the user gave us which hopefully refers
  76.  * to a file on the binary path
  77.  */
  78. Tcl_DString ds;
  79. char *fileName = Tcl_GetString(pathPtr);
  80. native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
  81. handle = dlopen(native, RTLD_NOW | RTLD_GLOBAL);
  82. Tcl_DStringFree(&ds);
  83.     }
  84.     
  85.     if (handle == NULL) {
  86. /*
  87.  * Write the string to a variable first to work around a compiler bug
  88.  * in the Sun Forte 6 compiler. [Bug 1503729]
  89.  */
  90. CONST char *errorStr = dlerror();
  91. Tcl_AppendResult(interp, "couldn't load file "", 
  92. Tcl_GetString(pathPtr), "": ", errorStr, (char *) NULL);
  93. return TCL_ERROR;
  94.     }
  95.     *unloadProcPtr = &TclpUnloadFile;
  96.     *loadHandle = (Tcl_LoadHandle)handle;
  97.     return TCL_OK;
  98. }
  99. /*
  100.  *----------------------------------------------------------------------
  101.  *
  102.  * TclpFindSymbol --
  103.  *
  104.  * Looks up a symbol, by name, through a handle associated with
  105.  * a previously loaded piece of code (shared library).
  106.  *
  107.  * Results:
  108.  * Returns a pointer to the function associated with 'symbol' if
  109.  * it is found.  Otherwise returns NULL and may leave an error
  110.  * message in the interp's result.
  111.  *
  112.  *----------------------------------------------------------------------
  113.  */
  114. Tcl_PackageInitProc*
  115. TclpFindSymbol(interp, loadHandle, symbol) 
  116.     Tcl_Interp *interp;
  117.     Tcl_LoadHandle loadHandle;
  118.     CONST char *symbol;
  119. {
  120.     CONST char *native;
  121.     Tcl_DString newName, ds;
  122.     VOID *handle = (VOID*)loadHandle;
  123.     Tcl_PackageInitProc *proc;
  124.     /* 
  125.      * Some platforms still add an underscore to the beginning of symbol
  126.      * names.  If we can't find a name without an underscore, try again
  127.      * with the underscore.
  128.      */
  129.     native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds);
  130.     proc = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
  131.     native);
  132.     if (proc == NULL) {
  133. Tcl_DStringInit(&newName);
  134. Tcl_DStringAppend(&newName, "_", 1);
  135. native = Tcl_DStringAppend(&newName, native, -1);
  136. proc = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */
  137. native);
  138. Tcl_DStringFree(&newName);
  139.     }
  140.     Tcl_DStringFree(&ds);
  141.     return proc;
  142. }
  143. /*
  144.  *----------------------------------------------------------------------
  145.  *
  146.  * TclpUnloadFile --
  147.  *
  148.  * Unloads a dynamically loaded binary code file from memory.
  149.  * Code pointers in the formerly loaded file are no longer valid
  150.  * after calling this function.
  151.  *
  152.  * Results:
  153.  * None.
  154.  *
  155.  * Side effects:
  156.  * Code removed from memory.
  157.  *
  158.  *----------------------------------------------------------------------
  159.  */
  160. void
  161. TclpUnloadFile(loadHandle)
  162.     Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call
  163.  * to TclpDlopen().  The loadHandle is 
  164.  * a token that represents the loaded 
  165.  * file. */
  166. {
  167.     VOID *handle;
  168.     handle = (VOID *) loadHandle;
  169.     dlclose(handle);
  170. }
  171. /*
  172.  *----------------------------------------------------------------------
  173.  *
  174.  * TclGuessPackageName --
  175.  *
  176.  * If the "load" command is invoked without providing a package
  177.  * name, this procedure is invoked to try to figure it out.
  178.  *
  179.  * Results:
  180.  * Always returns 0 to indicate that we couldn't figure out a
  181.  * package name;  generic code will then try to guess the package
  182.  * from the file name.  A return value of 1 would have meant that
  183.  * we figured out the package name and put it in bufPtr.
  184.  *
  185.  * Side effects:
  186.  * None.
  187.  *
  188.  *----------------------------------------------------------------------
  189.  */
  190. int
  191. TclGuessPackageName(fileName, bufPtr)
  192.     CONST char *fileName; /* Name of file containing package (already
  193.  * translated to local form if needed). */
  194.     Tcl_DString *bufPtr; /* Initialized empty dstring.  Append
  195.  * package name to this if possible. */
  196. {
  197.     return 0;
  198. }