diff options
Diffstat (limited to 'unix/tclLoadDl.c')
| -rw-r--r-- | unix/tclLoadDl.c | 42 | 
1 files changed, 30 insertions, 12 deletions
| diff --git a/unix/tclLoadDl.c b/unix/tclLoadDl.c index 96f0717..dc711f8 100644 --- a/unix/tclLoadDl.c +++ b/unix/tclLoadDl.c @@ -66,14 +66,16 @@ TclpDlopen(      Tcl_LoadHandle *loadHandle,	/* Filled with token for dynamically loaded  				 * file which will be passed back to  				 * (*unloadProcPtr)() to unload the file. */ -    Tcl_FSUnloadFileProc **unloadProcPtr) +    Tcl_FSUnloadFileProc **unloadProcPtr,  				/* Filled with address of Tcl_FSUnloadFileProc  				 * function which should be used for this  				 * file. */ +    int flags)  {      void *handle;      Tcl_LoadHandle newHandle;      const char *native; +    int dlopenflags = 0;      /*       * First try the full path the user gave us. This is particularly @@ -83,9 +85,19 @@ TclpDlopen(      native = Tcl_FSGetNativePath(pathPtr);      /* -     * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070] +     * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070]       */ -    handle = dlopen(native, RTLD_NOW | RTLD_LOCAL); +    if (flags & TCL_LOAD_GLOBAL) { +    	dlopenflags |= RTLD_GLOBAL; +    } else { +    	dlopenflags |= RTLD_LOCAL; +    } +    if (flags & TCL_LOAD_LAZY) { +    	dlopenflags |= RTLD_LAZY; +    } else { +    	dlopenflags |= RTLD_NOW; +    } +    handle = dlopen(native, dlopenflags);      if (handle == NULL) {  	/*  	 * Let the OS loader examine the binary search path for whatever @@ -98,9 +110,9 @@ TclpDlopen(  	native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);  	/* -	 * Use (RTLD_NOW|RTLD_LOCAL) always, see [Bug #3216070] +	 * Use (RTLD_NOW|RTLD_LOCAL) as default, see [Bug #3216070]  	 */ -	handle = dlopen(native, RTLD_NOW | RTLD_LOCAL); +	handle = dlopen(native, dlopenflags);  	Tcl_DStringFree(&ds);      } @@ -112,8 +124,9 @@ TclpDlopen(  	const char *errorStr = dlerror(); -	Tcl_AppendResult(interp, "couldn't load file \"", -		Tcl_GetString(pathPtr), "\": ", errorStr, NULL); +	Tcl_SetObjResult(interp, Tcl_ObjPrintf( +		"couldn't load file \"%s\": %s", +		Tcl_GetString(pathPtr), errorStr));  	return TCL_ERROR;      }      newHandle = ckalloc(sizeof(*newHandle)); @@ -151,7 +164,7 @@ FindSymbol(      const char *native;		/* Name of the library to be loaded, in  				 * system encoding */      Tcl_DString newName, ds;	/* Buffers for converting the name to -				 * system encoding and prepending an  +				 * system encoding and prepending an  				 * underscore*/      void *handle = (void *) loadHandle->clientData;  				/* Native handle to the loaded library */ @@ -168,16 +181,21 @@ FindSymbol(      proc = dlsym(handle, native);	/* INTL: Native. */      if (proc == NULL) {  	Tcl_DStringInit(&newName); -	Tcl_DStringAppend(&newName, "_", 1); +	TclDStringAppendLiteral(&newName, "_");  	native = Tcl_DStringAppend(&newName, native, -1);  	proc = dlsym(handle, native);	/* INTL: Native. */  	Tcl_DStringFree(&newName);      }      Tcl_DStringFree(&ds);      if (proc == NULL && interp != NULL) { -	Tcl_ResetResult(interp); -	Tcl_AppendResult(interp, "cannot find symbol \"", symbol, "\": ", -		dlerror(), NULL); +	const char *errorStr = dlerror(); + +	if (!errorStr) { +	    errorStr = "unknown"; +	} + +	Tcl_SetObjResult(interp, Tcl_ObjPrintf( +		"cannot find symbol \"%s\": %s", symbol, errorStr));  	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LOAD_SYMBOL", symbol,  		NULL);      } | 
