usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src / router / usbmodeswitch / jim / jim-load.c
blob4dc6ed2d87069af1d62f80fdb380904e1d818e46
1 #include "jim.h"
2 #include "jimautoconf.h"
3 #include <string.h>
5 /* -----------------------------------------------------------------------------
6 * Dynamic libraries support (WIN32 not supported)
7 * ---------------------------------------------------------------------------*/
9 #if defined(HAVE_DLOPEN) || defined(HAVE_DLOPEN_COMPAT)
11 #ifdef HAVE_DLFCN_H
12 #include <dlfcn.h>
13 #endif
15 #ifndef RTLD_NOW
16 #define RTLD_NOW 0
17 #endif
18 #ifndef RTLD_LOCAL
19 #define RTLD_LOCAL 0
20 #endif
22 /**
23 * Note that Jim_LoadLibrary() requires a path to an existing file.
25 * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead.
27 int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
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());
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"
39 const char *pt;
40 const char *pkgname;
41 int pkgnamelen;
42 char initsym[40];
43 int (*onload) (Jim_Interp *);
45 pt = strrchr(pathName, '/');
46 if (pt) {
47 pkgname = pt + 1;
49 else {
50 pkgname = pathName;
52 pt = strchr(pkgname, '.');
53 if (pt) {
54 pkgnamelen = pt - pkgname;
56 else {
57 pkgnamelen = strlen(pkgname);
59 snprintf(initsym, sizeof(initsym), "Jim_%.*sInit", pkgnamelen, pkgname);
61 if ((onload = dlsym(handle, initsym)) == NULL) {
62 Jim_SetResultFormatted(interp,
63 "No %s symbol found in extension %s", initsym, pathName);
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);
71 Jim_StackPush(interp->loadHandles, handle);
73 Jim_SetEmptyResult(interp);
75 return JIM_OK;
78 if (handle) {
79 dlclose(handle);
81 return JIM_ERR;
84 static void JimFreeOneLoadHandle(void *handle)
86 dlclose(handle);
89 void Jim_FreeLoadHandles(Jim_Interp *interp)
91 if (interp->loadHandles) {
92 Jim_FreeStackElements(interp->loadHandles, JimFreeOneLoadHandle);
93 Jim_Free(interp->loadHandles);
97 #else /* JIM_DYNLIB */
98 int Jim_LoadLibrary(Jim_Interp *interp, const char *pathName)
100 JIM_NOTUSED(interp);
101 JIM_NOTUSED(pathName);
103 Jim_SetResultString(interp, "the Jim binary has no support for [load]", -1);
104 return JIM_ERR;
107 void Jim_FreeLoadHandles(Jim_Interp *interp)
110 #endif /* JIM_DYNLIB */
112 /* [load] */
113 static int Jim_LoadCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
115 if (argc < 2) {
116 Jim_WrongNumArgs(interp, 1, argv, "libaryFile");
117 return JIM_ERR;
119 return Jim_LoadLibrary(interp, Jim_String(argv[1]));
122 int Jim_loadInit(Jim_Interp *interp)
124 Jim_CreateCommand(interp, "load", Jim_LoadCoreCommand, NULL, NULL);
125 return JIM_OK;