tclLoadDl.cGo to the documentation of this file.00001 /* 00002 * tclLoadDl.c -- 00003 * 00004 * This procedure provides a version of the TclLoadFile that works with 00005 * the "dlopen" and "dlsym" library procedures for dynamic loading. 00006 * 00007 * Copyright (c) 1995-1997 Sun Microsystems, Inc. 00008 * 00009 * See the file "license.terms" for information on usage and redistribution of 00010 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 00011 * 00012 * RCS: @(#) $Id: tclLoadDl.c,v 1.16 2006/06/13 22:10:19 dkf Exp $ 00013 */ 00014 00015 #include "tclInt.h" 00016 #ifdef NO_DLFCN_H 00017 # include "../compat/dlfcn.h" 00018 #else 00019 # include <dlfcn.h> 00020 #endif 00021 00022 /* 00023 * In some systems, like SunOS 4.1.3, the RTLD_NOW flag isn't defined and this 00024 * argument to dlopen must always be 1. The RTLD_GLOBAL flag is needed on some 00025 * systems (e.g. SCO and UnixWare) but doesn't exist on others; if it doesn't 00026 * exist, set it to 0 so it has no effect. 00027 */ 00028 00029 #ifndef RTLD_NOW 00030 # define RTLD_NOW 1 00031 #endif 00032 00033 #ifndef RTLD_GLOBAL 00034 # define RTLD_GLOBAL 0 00035 #endif 00036 00037 /* 00038 *--------------------------------------------------------------------------- 00039 * 00040 * TclpDlopen -- 00041 * 00042 * Dynamically loads a binary code file into memory and returns a handle 00043 * to the new code. 00044 * 00045 * Results: 00046 * A standard Tcl completion code. If an error occurs, an error message 00047 * is left in the interp's result. 00048 * 00049 * Side effects: 00050 * New code suddenly appears in memory. 00051 * 00052 *--------------------------------------------------------------------------- 00053 */ 00054 00055 int 00056 TclpDlopen( 00057 Tcl_Interp *interp, /* Used for error reporting. */ 00058 Tcl_Obj *pathPtr, /* Name of the file containing the desired 00059 * code (UTF-8). */ 00060 Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded 00061 * file which will be passed back to 00062 * (*unloadProcPtr)() to unload the file. */ 00063 Tcl_FSUnloadFileProc **unloadProcPtr) 00064 /* Filled with address of Tcl_FSUnloadFileProc 00065 * function which should be used for this 00066 * file. */ 00067 { 00068 void *handle; 00069 CONST char *native; 00070 00071 /* 00072 * First try the full path the user gave us. This is particularly 00073 * important if the cwd is inside a vfs, and we are trying to load using a 00074 * relative path. 00075 */ 00076 00077 native = Tcl_FSGetNativePath(pathPtr); 00078 handle = dlopen(native, RTLD_NOW | RTLD_GLOBAL); 00079 if (handle == NULL) { 00080 /* 00081 * Let the OS loader examine the binary search path for whatever 00082 * string the user gave us which hopefully refers to a file on the 00083 * binary path. 00084 */ 00085 00086 Tcl_DString ds; 00087 char *fileName = Tcl_GetString(pathPtr); 00088 00089 native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); 00090 handle = dlopen(native, RTLD_NOW | RTLD_GLOBAL); 00091 Tcl_DStringFree(&ds); 00092 } 00093 00094 if (handle == NULL) { 00095 /* 00096 * Write the string to a variable first to work around a compiler bug 00097 * in the Sun Forte 6 compiler. [Bug 1503729] 00098 */ 00099 00100 const char *errorStr = dlerror(); 00101 00102 Tcl_AppendResult(interp, "couldn't load file \"", 00103 Tcl_GetString(pathPtr), "\": ", errorStr, NULL); 00104 return TCL_ERROR; 00105 } 00106 00107 *unloadProcPtr = &TclpUnloadFile; 00108 *loadHandle = (Tcl_LoadHandle) handle; 00109 return TCL_OK; 00110 } 00111 00112 /* 00113 *---------------------------------------------------------------------- 00114 * 00115 * TclpFindSymbol -- 00116 * 00117 * Looks up a symbol, by name, through a handle associated with a 00118 * previously loaded piece of code (shared library). 00119 * 00120 * Results: 00121 * Returns a pointer to the function associated with 'symbol' if it is 00122 * found. Otherwise returns NULL and may leave an error message in the 00123 * interp's result. 00124 * 00125 *---------------------------------------------------------------------- 00126 */ 00127 00128 Tcl_PackageInitProc * 00129 TclpFindSymbol( 00130 Tcl_Interp *interp, /* Place to put error messages. */ 00131 Tcl_LoadHandle loadHandle, /* Value from TcpDlopen(). */ 00132 CONST char *symbol) /* Symbol to look up. */ 00133 { 00134 CONST char *native; 00135 Tcl_DString newName, ds; 00136 VOID *handle = (VOID*)loadHandle; 00137 Tcl_PackageInitProc *proc; 00138 00139 /* 00140 * Some platforms still add an underscore to the beginning of symbol 00141 * names. If we can't find a name without an underscore, try again with 00142 * the underscore. 00143 */ 00144 00145 native = Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); 00146 proc = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */ 00147 native); 00148 if (proc == NULL) { 00149 Tcl_DStringInit(&newName); 00150 Tcl_DStringAppend(&newName, "_", 1); 00151 native = Tcl_DStringAppend(&newName, native, -1); 00152 proc = (Tcl_PackageInitProc *) dlsym(handle, /* INTL: Native. */ 00153 native); 00154 Tcl_DStringFree(&newName); 00155 } 00156 Tcl_DStringFree(&ds); 00157 00158 return proc; 00159 } 00160 00161 /* 00162 *---------------------------------------------------------------------- 00163 * 00164 * TclpUnloadFile -- 00165 * 00166 * Unloads a dynamically loaded binary code file from memory. Code 00167 * pointers in the formerly loaded file are no longer valid after calling 00168 * this function. 00169 * 00170 * Results: 00171 * None. 00172 * 00173 * Side effects: 00174 * Code removed from memory. 00175 * 00176 *---------------------------------------------------------------------- 00177 */ 00178 00179 void 00180 TclpUnloadFile( 00181 Tcl_LoadHandle loadHandle) /* loadHandle returned by a previous call to 00182 * TclpDlopen(). The loadHandle is a token 00183 * that represents the loaded file. */ 00184 { 00185 void *handle; 00186 00187 handle = (void *) loadHandle; 00188 dlclose(handle); 00189 } 00190 00191 /* 00192 *---------------------------------------------------------------------- 00193 * 00194 * TclGuessPackageName -- 00195 * 00196 * If the "load" command is invoked without providing a package name, 00197 * this procedure is invoked to try to figure it out. 00198 * 00199 * Results: 00200 * Always returns 0 to indicate that we couldn't figure out a package 00201 * name; generic code will then try to guess the package from the file 00202 * name. A return value of 1 would have meant that we figured out the 00203 * package name and put it in bufPtr. 00204 * 00205 * Side effects: 00206 * None. 00207 * 00208 *---------------------------------------------------------------------- 00209 */ 00210 00211 int 00212 TclGuessPackageName( 00213 CONST char *fileName, /* Name of file containing package (already 00214 * translated to local form if needed). */ 00215 Tcl_DString *bufPtr) /* Initialized empty dstring. Append package 00216 * name to this if possible. */ 00217 { 00218 return 0; 00219 } 00220 00221 /* 00222 * Local Variables: 00223 * mode: c 00224 * c-basic-offset: 4 00225 * fill-column: 78 00226 * End: 00227 */
Generated on Wed Mar 12 12:18:25 2008 by 1.5.1 |