• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/usb-modeswitch-2.2.3/jim/
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}
127