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

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tclLoadShl.c --
  3.  *
  4.  * This procedure provides a version of the TclLoadFile that works
  5.  * with the "shl_load" and "shl_findsym" library procedures for
  6.  * dynamic loading (e.g. for HP machines).
  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: tclLoadShl.c,v 1.13.2.1 2005/10/05 04:23:56 hobbs Exp $
  14.  */
  15. #include <dl.h>
  16. /*
  17.  * On some HP machines, dl.h defines EXTERN; remove that definition.
  18.  */
  19. #ifdef EXTERN
  20. #   undef EXTERN
  21. #endif
  22. #include "tclInt.h"
  23. /*
  24.  *----------------------------------------------------------------------
  25.  *
  26.  * TclpDlopen --
  27.  *
  28.  * Dynamically loads a binary code file into memory and returns
  29.  * a handle to the new code.
  30.  *
  31.  * Results:
  32.  * A standard Tcl completion code.  If an error occurs, an error
  33.  * message is left in the interp's result.
  34.  *
  35.  * Side effects:
  36.  * New code suddenly appears in memory.
  37.  *
  38.  *----------------------------------------------------------------------
  39.  */
  40. int
  41. TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr)
  42.     Tcl_Interp *interp; /* Used for error reporting. */
  43.     Tcl_Obj *pathPtr; /* Name of the file containing the desired
  44.  * code (UTF-8). */
  45.     Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded
  46.  * file which will be passed back to 
  47.  * (*unloadProcPtr)() to unload the file. */
  48.     Tcl_FSUnloadFileProc **unloadProcPtr;
  49. /* Filled with address of Tcl_FSUnloadFileProc
  50.  * function which should be used for
  51.  * this file. */
  52. {
  53.     shl_t handle;
  54.     CONST char *native;
  55.     char *fileName = Tcl_GetString(pathPtr);
  56.     /*
  57.      * The flags below used to be BIND_IMMEDIATE; they were changed at
  58.      * the suggestion of Wolfgang Kechel (wolfgang@prs.de): "This
  59.      * enables verbosity for missing symbols when loading a shared lib
  60.      * and allows to load libtk8.0.sl into tclsh8.0 without problems.
  61.      * In general, this delays resolving symbols until they are actually
  62.      * needed.  Shared libs do no longer need all libraries linked in
  63.      * when they are build."
  64.      */
  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 = shl_load(native, BIND_DEFERRED|BIND_VERBOSE, 0L);
  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. native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
  80. handle = shl_load(native,
  81.   BIND_DEFERRED|BIND_VERBOSE|DYNAMIC_PATH, 0L);
  82. Tcl_DStringFree(&ds);
  83.     }
  84.     if (handle == NULL) {
  85. Tcl_AppendResult(interp, "couldn't load file "", fileName,
  86. "": ", Tcl_PosixError(interp), (char *) NULL);
  87. return TCL_ERROR;
  88.     }
  89.     *loadHandle = (Tcl_LoadHandle) handle;
  90.     *unloadProcPtr = &TclpUnloadFile;
  91.     return TCL_OK;
  92. }
  93. /*
  94.  *----------------------------------------------------------------------
  95.  *
  96.  * TclpFindSymbol --
  97.  *
  98.  * Looks up a symbol, by name, through a handle associated with
  99.  * a previously loaded piece of code (shared library).
  100.  *
  101.  * Results:
  102.  * Returns a pointer to the function associated with 'symbol' if
  103.  * it is found.  Otherwise returns NULL and may leave an error
  104.  * message in the interp's result.
  105.  *
  106.  *----------------------------------------------------------------------
  107.  */
  108. Tcl_PackageInitProc*
  109. TclpFindSymbol(interp, loadHandle, symbol) 
  110.     Tcl_Interp *interp;
  111.     Tcl_LoadHandle loadHandle;
  112.     CONST char *symbol;
  113. {
  114.     Tcl_DString newName;
  115.     Tcl_PackageInitProc *proc=NULL;
  116.     shl_t handle = (shl_t)loadHandle;
  117.     /*
  118.      * Some versions of the HP system software still use "_" at the
  119.      * beginning of exported symbols while others don't;  try both
  120.      * forms of each name.
  121.      */
  122.     if (shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, (void *) &proc)
  123.     != 0) {
  124. Tcl_DStringInit(&newName);
  125. Tcl_DStringAppend(&newName, "_", 1);
  126. Tcl_DStringAppend(&newName, symbol, -1);
  127. if (shl_findsym(&handle, Tcl_DStringValue(&newName),
  128. (short) TYPE_PROCEDURE, (void *) &proc) != 0) {
  129.     proc = NULL;
  130. }
  131. Tcl_DStringFree(&newName);
  132.     }
  133.     return proc;
  134. }
  135. /*
  136.  *----------------------------------------------------------------------
  137.  *
  138.  * TclpUnloadFile --
  139.  *
  140.  * Unloads a dynamically loaded binary code file from memory.
  141.  * Code pointers in the formerly loaded file are no longer valid
  142.  * after calling this function.
  143.  *
  144.  * Results:
  145.  * None.
  146.  *
  147.  * Side effects:
  148.  * Code removed from memory.
  149.  *
  150.  *----------------------------------------------------------------------
  151.  */
  152. void
  153. TclpUnloadFile(loadHandle)
  154.     Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call
  155.  * to TclpDlopen().  The loadHandle is 
  156.  * a token that represents the loaded 
  157.  * file. */
  158. {
  159.     shl_t handle;
  160.     handle = (shl_t) loadHandle;
  161.     shl_unload(handle);
  162. }
  163. /*
  164.  *----------------------------------------------------------------------
  165.  *
  166.  * TclGuessPackageName --
  167.  *
  168.  * If the "load" command is invoked without providing a package
  169.  * name, this procedure is invoked to try to figure it out.
  170.  *
  171.  * Results:
  172.  * Always returns 0 to indicate that we couldn't figure out a
  173.  * package name;  generic code will then try to guess the package
  174.  * from the file name.  A return value of 1 would have meant that
  175.  * we figured out the package name and put it in bufPtr.
  176.  *
  177.  * Side effects:
  178.  * None.
  179.  *
  180.  *----------------------------------------------------------------------
  181.  */
  182. int
  183. TclGuessPackageName(fileName, bufPtr)
  184.     CONST char *fileName; /* Name of file containing package (already
  185.  * translated to local form if needed). */
  186.     Tcl_DString *bufPtr; /* Initialized empty dstring.  Append
  187.  * package name to this if possible. */
  188. {
  189.     return 0;
  190. }