PageRenderTime 27ms CodeModel.GetById 17ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 0ms

/usb-modeswitch-1.2.3/jim/jim-load.c

#
C | 126 lines | 96 code | 16 blank | 14 comment | 17 complexity | e4ddfc87ddce3101e4819125e3352ea1 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-3.0
  1#include "jim.h"
  2#include "jimautoconf.h"
  3#include <string.h>
  4
  5/* -----------------------------------------------------------------------------
  6 * Dynamic libraries support (WIN32 not supported)
  7 * ---------------------------------------------------------------------------*/
  8
  9#if defined(HAVE_DLOPEN) || defined(HAVE_DLOPEN_COMPAT)
 10
 11#ifdef HAVE_DLFCN_H
 12#include <dlfcn.h>
 13#endif
 14
 15#ifndef RTLD_NOW
 16    #define RTLD_NOW 0
 17#endif
 18#ifndef RTLD_LOCAL
 19    #define RTLD_LOCAL 0
 20#endif
 21
 22/**
 23 * Note that Jim_LoadLibrary() requires a path to an existing file.
 24 *
 25 * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead.
 26 */
 27int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
 28{
 29    void *handle = dlopen(pathName, RTLD_NOW | RTLD_LOCAL);
 30    if (handle == NULL) {
 31        Jim_SetResultFormatted(interp, "error loading extension \"%s\": %s", pathName,
 32            dlerror());
 33    }
 34    else {
 35        /* We use a unique init symbol depending on the extension name.
 36         * This is done for compatibility between static and dynamic extensions.
 37         * For extension readline.so, the init symbol is "Jim_readlineInit"
 38         */
 39        const char *pt;
 40        const char *pkgname;
 41        int pkgnamelen;
 42        char initsym[40];
 43        int (*onload) (Jim_Interp *);
 44
 45        pt = strrchr(pathName, '/');
 46        if (pt) {
 47            pkgname = pt + 1;
 48        }
 49        else {
 50            pkgname = pathName;
 51        }
 52        pt = strchr(pkgname, '.');
 53        if (pt) {
 54            pkgnamelen = pt - pkgname;
 55        }
 56        else {
 57            pkgnamelen = strlen(pkgname);
 58        }
 59        snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname);
 60
 61        if ((onload = dlsym(handle, initsym)) == NULL) {
 62            Jim_SetResultFormatted(interp,
 63                "No %s symbol found in extension %s", initsym, pathName);
 64        }
 65        else if (onload(interp) != JIM_ERR) {
 66            /* Add this handle to the stack of handles to be freed */
 67            if (!interp->loadHandles) {
 68                interp->loadHandles = Jim_Alloc(sizeof(*interp->loadHandles));
 69                Jim_InitStack(interp->loadHandles);
 70            }
 71            Jim_StackPush(interp->loadHandles, handle);
 72
 73            Jim_SetEmptyResult(interp);
 74
 75            return JIM_OK;
 76        }
 77    }
 78    if (handle) {
 79        dlclose(handle);
 80    }
 81    return JIM_ERR;
 82}
 83
 84static void JimFreeOneLoadHandle(void *handle)
 85{
 86    dlclose(handle);
 87}
 88
 89void Jim_FreeLoadHandles(Jim_Interp *interp)
 90{
 91    if (interp->loadHandles) {
 92        Jim_FreeStackElements(interp->loadHandles, JimFreeOneLoadHandle);
 93        Jim_Free(interp->loadHandles);
 94    }
 95}
 96
 97#else /* JIM_DYNLIB */
 98int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
 99{
100    JIM_NOTUSED(interp);
101    JIM_NOTUSED(pathName);
102
103    Jim_SetResultString(interp, "the Jim binary has no support for [load]", -1);
104    return JIM_ERR;
105}
106
107void Jim_FreeLoadHandles(Jim_Interp *interp)
108{
109}
110#endif /* JIM_DYNLIB */
111
112/* [load] */
113static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
114{
115    if (argc < 2) {
116        Jim_WrongNumArgs(interp, 1, argv, "libaryFile");
117        return JIM_ERR;
118    }
119    return Jim_LoadLibrary(interp, Jim_String(argv[1]));
120}
121
122int Jim_loadInit(Jim_Interp *interp)
123{
124    Jim_CreateCommand(interp, "load", Jim_LoadCoreCommand, NULL, NULL);
125    return JIM_OK;
126}