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