3 #include "jimautoconf.h"
6 /* -----------------------------------------------------------------------------
7 * Dynamic libraries support (WIN32 not supported)
8 * ---------------------------------------------------------------------------*/
10 #if defined(HAVE_DLOPEN) || defined(HAVE_DLOPEN_COMPAT)
23 static void JimFreeLoadHandles(Jim_Interp
*interp
, void *data
);
26 * Note that Jim_LoadLibrary() requires a path to an existing file.
28 * If it is necessary to search JIM_LIBPATH, use Jim_PackageRequire() instead.
30 int Jim_LoadLibrary(Jim_Interp
*interp
, const char *pathName
)
32 void *handle
= dlopen(pathName
, RTLD_NOW
| RTLD_LOCAL
);
34 Jim_SetResultFormatted(interp
, "error loading extension \"%s\": %s", pathName
,
38 /* We use a unique init symbol depending on the extension name.
39 * This is done for compatibility between static and dynamic extensions.
40 * For extension readline.so, the init symbol is "Jim_readlineInit"
46 typedef int jim_module_init_func_type(Jim_Interp
*);
47 jim_module_init_func_type
*onload
;
49 pt
= strrchr(pathName
, '/');
56 pt
= strchr(pkgname
, '.');
58 pkgnamelen
= pt
- pkgname
;
61 pkgnamelen
= strlen(pkgname
);
63 snprintf(initsym
, sizeof(initsym
), "Jim_%.*sInit", pkgnamelen
, pkgname
);
65 if ((onload
= (jim_module_init_func_type
*)dlsym(handle
, initsym
)) == NULL
) {
66 Jim_SetResultFormatted(interp
,
67 "No %s symbol found in extension %s", initsym
, pathName
);
69 else if (onload(interp
) != JIM_ERR
) {
70 /* Add this handle to the stack of handles to be freed */
71 Jim_Stack
*loadHandles
= Jim_GetAssocData(interp
, "load::handles");
72 if (loadHandles
== NULL
) {
73 loadHandles
= Jim_Alloc(sizeof(*loadHandles
));
74 Jim_InitStack(loadHandles
);
75 Jim_SetAssocData(interp
, "load::handles", JimFreeLoadHandles
, loadHandles
);
77 Jim_StackPush(loadHandles
, handle
);
79 Jim_SetEmptyResult(interp
);
90 static void JimFreeOneLoadHandle(void *handle
)
95 static void JimFreeLoadHandles(Jim_Interp
*interp
, void *data
)
97 Jim_Stack
*handles
= data
;
100 Jim_FreeStackElements(handles
, JimFreeOneLoadHandle
);
101 Jim_FreeStack(handles
);
106 #else /* JIM_DYNLIB */
107 int Jim_LoadLibrary(Jim_Interp
*interp
, const char *pathName
)
110 JIM_NOTUSED(pathName
);
112 Jim_SetResultString(interp
, "the Jim binary has no support for [load]", -1);
116 void Jim_FreeLoadHandles(Jim_Interp
*interp
)
119 #endif /* JIM_DYNLIB */
122 static int Jim_LoadCoreCommand(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
125 Jim_WrongNumArgs(interp
, 1, argv
, "libraryFile");
128 return Jim_LoadLibrary(interp
, Jim_String(argv
[1]));
131 int Jim_loadInit(Jim_Interp
*interp
)
133 Jim_CreateCommand(interp
, "load", Jim_LoadCoreCommand
, NULL
, NULL
);