/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}