dynload.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* dynload.c Dynamic Loader for TinyScheme */
  2. /* Original Copyright (c) 1999 Alexander Shendi */
  3. /* Modifications for NT and dl_* interface, scm_load_ext: D. Souflis */
  4. /* Refurbished by Stephen Gildea */
  5. #define _SCHEME_SOURCE
  6. #include "dynload.h"
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #ifndef MAXPATHLEN
  11. # define MAXPATHLEN 1024
  12. #endif
  13. static void make_filename(const char *name, char *filename);
  14. static void make_init_fn(const char *name, char *init_fn);
  15. #ifdef _WIN32
  16. # include <windows.h>
  17. #else
  18. typedef void *HMODULE;
  19. typedef void (*FARPROC)();
  20. #define SUN_DL
  21. #include <dlfcn.h>
  22. #endif
  23. #ifdef _WIN32
  24. #define PREFIX ""
  25. #define SUFFIX ".dll"
  26. static void display_w32_error_msg(const char *additional_message)
  27. {
  28. LPVOID msg_buf;
  29. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  30. NULL, GetLastError(), 0,
  31. (LPTSTR)&msg_buf, 0, NULL);
  32. fprintf(stderr, "scheme load-extension: %s: %s", additional_message, msg_buf);
  33. LocalFree(msg_buf);
  34. }
  35. static HMODULE dl_attach(const char *module) {
  36. HMODULE dll = LoadLibrary(module);
  37. if (!dll) display_w32_error_msg(module);
  38. return dll;
  39. }
  40. static FARPROC dl_proc(HMODULE mo, const char *proc) {
  41. FARPROC procedure = GetProcAddress(mo,proc);
  42. if (!procedure) display_w32_error_msg(proc);
  43. return procedure;
  44. }
  45. static void dl_detach(HMODULE mo) {
  46. (void)FreeLibrary(mo);
  47. }
  48. #elif defined(SUN_DL)
  49. #include <dlfcn.h>
  50. #define PREFIX "lib"
  51. #define SUFFIX ".so"
  52. static HMODULE dl_attach(const char *module) {
  53. HMODULE so=dlopen(module,RTLD_LAZY);
  54. if(!so) {
  55. fprintf(stderr, "Error loading scheme extension \"%s\": %s\n", module, dlerror());
  56. }
  57. return so;
  58. }
  59. static FARPROC dl_proc(HMODULE mo, const char *proc) {
  60. const char *errmsg;
  61. FARPROC fp=(FARPROC)dlsym(mo,proc);
  62. if ((errmsg = dlerror()) == 0) {
  63. return fp;
  64. }
  65. fprintf(stderr, "Error initializing scheme module \"%s\": %s\n", proc, errmsg);
  66. return 0;
  67. }
  68. static void dl_detach(HMODULE mo) {
  69. (void)dlclose(mo);
  70. }
  71. #endif
  72. pointer scm_load_ext(scheme *sc, pointer args)
  73. {
  74. pointer first_arg;
  75. pointer retval;
  76. char filename[MAXPATHLEN], init_fn[MAXPATHLEN+6];
  77. char *name;
  78. HMODULE dll_handle;
  79. void (*module_init)(scheme *sc);
  80. if ((args != sc->NIL) && is_string((first_arg = pair_car(args)))) {
  81. name = string_value(first_arg);
  82. make_filename(name,filename);
  83. make_init_fn(name,init_fn);
  84. dll_handle = dl_attach(filename);
  85. if (dll_handle == 0) {
  86. retval = sc -> F;
  87. }
  88. else {
  89. module_init = (void(*)(scheme *))dl_proc(dll_handle, init_fn);
  90. if (module_init != 0) {
  91. (*module_init)(sc);
  92. retval = sc -> T;
  93. }
  94. else {
  95. retval = sc->F;
  96. }
  97. }
  98. }
  99. else {
  100. retval = sc -> F;
  101. }
  102. return(retval);
  103. }
  104. static void make_filename(const char *name, char *filename) {
  105. strcpy(filename,name);
  106. strcat(filename,SUFFIX);
  107. }
  108. static void make_init_fn(const char *name, char *init_fn) {
  109. const char *p=strrchr(name,'/');
  110. if(p==0) {
  111. p=name;
  112. } else {
  113. p++;
  114. }
  115. strcpy(init_fn,"init_");
  116. strcat(init_fn,p);
  117. }