tclLoadOSF.c

Go to the documentation of this file.
00001 /*
00002  * tclLoadOSF.c --
00003  *
00004  *      This function provides a version of the TclLoadFile that works under
00005  *      OSF/1 1.0/1.1/1.2 and related systems, utilizing the old OSF/1
00006  *      /sbin/loader and /usr/include/loader.h. OSF/1 versions from 1.3 and on
00007  *      use ELF, rtld, and dlopen()[/usr/include/ldfcn.h].
00008  *
00009  *      This is useful for:
00010  *              OSF/1 1.0, 1.1, 1.2 (from OSF)
00011  *                      includes: MK4 and AD1 (from OSF RI)
00012  *              OSF/1 1.3 (from OSF) using ROSE
00013  *              HP OSF/1 1.0 ("Acorn") using COFF
00014  *
00015  *      This is likely to be useful for:
00016  *              Paragon OSF/1 (from Intel)
00017  *              HI-OSF/1 (from Hitachi)
00018  *
00019  *      This is NOT to be used on:
00020  *              Digitial Alpha OSF/1 systems
00021  *              OSF/1 1.3 or later (from OSF) using ELF
00022  *                      includes: MK6, MK7, AD2, AD3 (from OSF RI)
00023  *
00024  *      This approach to things was utter @&^#; thankfully, OSF/1 eventually
00025  *      supported dlopen().
00026  *
00027  *      John Robert LoVerso <loverso@freebsd.osf.org>
00028  *
00029  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
00030  *
00031  * See the file "license.terms" for information on usage and redistribution of
00032  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
00033  *
00034  * RCS: @(#) $Id: tclLoadOSF.c,v 1.13 2005/11/11 23:46:34 dkf Exp $
00035  */
00036 
00037 #include "tclInt.h"
00038 #include <sys/types.h>
00039 #include <loader.h>
00040 
00041 /*
00042  *----------------------------------------------------------------------
00043  *
00044  * TclpDlopen --
00045  *
00046  *      Dynamically loads a binary code file into memory and returns a handle
00047  *      to the new code.
00048  *
00049  * Results:
00050  *      A standard Tcl completion code.  If an error occurs, an error message
00051  *      is left in the interp's result.
00052  *
00053  * Side effects:
00054  *      New code suddenly appears in memory.
00055  *
00056  *----------------------------------------------------------------------
00057  */
00058 
00059 int
00060 TclpDlopen(
00061     Tcl_Interp *interp,         /* Used for error reporting. */
00062     Tcl_Obj *pathPtr,           /* Name of the file containing the desired
00063                                  * code (UTF-8). */
00064     Tcl_LoadHandle *loadHandle, /* Filled with token for dynamically loaded
00065                                  * file which will be passed back to
00066                                  * (*unloadProcPtr)() to unload the file. */
00067     Tcl_FSUnloadFileProc **unloadProcPtr)
00068                                 /* Filled with address of Tcl_FSUnloadFileProc
00069                                  * function which should be used for this
00070                                  * file. */
00071 {
00072     ldr_module_t lm;
00073     char *pkg;
00074     char *fileName = Tcl_GetString(pathPtr);
00075     CONST char *native;
00076 
00077     /*
00078      * First try the full path the user gave us.  This is particularly
00079      * important if the cwd is inside a vfs, and we are trying to load using a
00080      * relative path.
00081      */
00082 
00083     native = Tcl_FSGetNativePath(pathPtr);
00084     lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS);
00085 
00086     if (lm == LDR_NULL_MODULE) {
00087         /*
00088          * Let the OS loader examine the binary search path for whatever
00089          * string the user gave us which hopefully refers to a file on the
00090          * binary path
00091          */
00092 
00093         Tcl_DString ds;
00094 
00095         native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds);
00096         lm = (Tcl_PackageInitProc *) load(native, LDR_NOFLAGS);
00097         Tcl_DStringFree(&ds);
00098     }
00099 
00100     if (lm == LDR_NULL_MODULE) {
00101         Tcl_AppendResult(interp, "couldn't load file \"", fileName, "\": ",
00102                 Tcl_PosixError(interp), NULL);
00103         return TCL_ERROR;
00104     }
00105 
00106     *clientDataPtr = NULL;
00107 
00108     /*
00109      * My convention is to use a [OSF loader] package name the same as shlib,
00110      * since the idiots never implemented ldr_lookup() and it is otherwise
00111      * impossible to get a package name given a module.
00112      *
00113      * I build loadable modules with a makefile rule like
00114      *          ld ... -export $@: -o $@ $(OBJS)
00115      */
00116 
00117     if ((pkg = strrchr(fileName, '/')) == NULL) {
00118         pkg = fileName;
00119     } else {
00120         pkg++;
00121     }
00122     *loadHandle = pkg;
00123     *unloadProcPtr = &TclpUnloadFile;
00124     return TCL_OK;
00125 }
00126 
00127 /*
00128  *----------------------------------------------------------------------
00129  *
00130  * TclpFindSymbol --
00131  *
00132  *      Looks up a symbol, by name, through a handle associated with a
00133  *      previously loaded piece of code (shared library).
00134  *
00135  * Results:
00136  *      Returns a pointer to the function associated with 'symbol' if it is
00137  *      found.  Otherwise returns NULL and may leave an error message in the
00138  *      interp's result.
00139  *
00140  *----------------------------------------------------------------------
00141  */
00142 
00143 Tcl_PackageInitProc *
00144 TclpFindSymbol(
00145     Tcl_Interp *interp,
00146     Tcl_LoadHandle loadHandle,
00147     CONST char *symbol)
00148 {
00149     return ldr_lookup_package((char *)loadHandle, symbol);
00150 }
00151 
00152 /*
00153  *----------------------------------------------------------------------
00154  *
00155  * TclpUnloadFile --
00156  *
00157  *      Unloads a dynamically loaded binary code file from memory. Code
00158  *      pointers in the formerly loaded file are no longer valid after calling
00159  *      this function.
00160  *
00161  * Results:
00162  *      None.
00163  *
00164  * Side effects:
00165  *      Does nothing.  Can anything be done?
00166  *
00167  *----------------------------------------------------------------------
00168  */
00169 
00170 void
00171 TclpUnloadFile(
00172     Tcl_LoadHandle loadHandle)  /* loadHandle returned by a previous call to
00173                                  * TclpDlopen(). The loadHandle is a token
00174                                  * that represents the loaded file. */
00175 {
00176 }
00177 
00178 /*
00179  *----------------------------------------------------------------------
00180  *
00181  * TclGuessPackageName --
00182  *
00183  *      If the "load" command is invoked without providing a package name,
00184  *      this function is invoked to try to figure it out.
00185  *
00186  * Results:
00187  *      Always returns 0 to indicate that we couldn't figure out a package
00188  *      name; generic code will then try to guess the package from the file
00189  *      name.  A return value of 1 would have meant that we figured out the
00190  *      package name and put it in bufPtr.
00191  *
00192  * Side effects:
00193  *      None.
00194  *
00195  *----------------------------------------------------------------------
00196  */
00197 
00198 int
00199 TclGuessPackageName(
00200     CONST char *fileName,       /* Name of file containing package (already
00201                                  * translated to local form if needed). */
00202     Tcl_DString *bufPtr)        /* Initialized empty dstring. Append package
00203                                  * name to this if possible. */
00204 {
00205     return 0;
00206 }
00207 
00208 /*
00209  * Local Variables:
00210  * mode: c
00211  * c-basic-offset: 4
00212  * fill-column: 78
00213  * End:
00214  */



Generated on Wed Mar 12 12:18:25 2008 by  doxygen 1.5.1