]> git.imager.perl.org - imager.git/blob - dynaload.c
WIP, more coverage and fixes
[imager.git] / dynaload.c
1 #if defined(OS_hpux)
2 #include <dl.h>
3 typedef shl_t minthandle_t;
4 #elif defined(WIN32)
5 #define WIN32_LEAN_AND_MEAN
6 #include <windows.h>
7 typedef HMODULE minthandle_t;
8 #undef WIN32_LEAN_AND_MEAN
9 #else 
10 #include <dlfcn.h>
11 typedef void *minthandle_t; 
12 #endif 
13
14 #include "plug.h"
15
16 struct DSO_handle_tag {
17   minthandle_t handle;
18   char *filename;
19   func_ptr *function_list;
20 };
21
22 #include "imager.h"
23 #include "dynaload.h"
24 /* #include "XSUB.h"  so we can compile on threaded perls */
25 #include "imageri.h"
26
27 static symbol_table_t symbol_table=
28   {
29     i_has_format,
30     ICL_set_internal,
31     ICL_info,
32     i_img_new,
33     i_img_empty,
34     i_img_empty_ch,
35     i_img_exorcise,
36     i_img_info,
37     i_img_setmask,
38     i_img_getmask,
39     i_box,
40     i_line,
41     i_arc,
42     i_copyto,
43     i_copyto_trans,
44     i_rubthru
45   };
46
47
48 /*
49   Dynamic loading works like this:
50   dynaload opens the shared object and
51   loads all the functions into an array of functions
52   it returns a string from the dynamic function that
53   can be supplied to the parser for evaling.
54 */
55
56 void
57 DSO_call(DSO_handle *handle,int func_index,HV* hv) {
58   mm_log((1,"DSO_call(handle %p, func_index %d, hv %p)\n",
59           handle, func_index, hv));
60   (handle->function_list[func_index].iptr)((void*)hv);
61 }
62
63 func_ptr *
64 DSO_funclist(DSO_handle *handle) {
65   return handle->function_list;
66 }
67
68
69 #if defined( OS_hpux )
70
71 void*
72 DSO_open(char* file,char** evalstring) {
73   shl_t tt_handle;
74   void *d_handle,**plugin_symtab,**plugin_utiltab;
75   int  rc,*iptr, (*fptr)(int);
76   func_ptr *function_list;
77   DSO_handle *dso_handle;
78   void (*f)(void *s,void *u); /* these will just have to be void for now */
79   int i;
80
81   *evalstring=NULL;
82
83   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
84
85   if ( (tt_handle = shl_load(file, BIND_DEFERRED,0L)) == NULL) return NULL; 
86   if ( (shl_findsym(&tt_handle, I_EVALSTR,TYPE_UNDEFINED,(void*)evalstring))) return NULL;
87
88   /*
89   if ( (shl_findsym(&tt_handle, "symbol_table",TYPE_UNDEFINED,(void*)&plugin_symtab))) return NULL;
90   if ( (shl_findsym(&tt_handle, "util_table",TYPE_UNDEFINED,&plugin_utiltab))) return NULL;
91   (*plugin_symtab)=&symbol_table;
92   (*plugin_utiltab)=&i_UTIL_table;
93   */
94
95   if ( (shl_findsym(&tt_handle, I_INSTALL_TABLES ,TYPE_UNDEFINED, &f ))) return NULL; 
96  
97   mm_log( (1,"Calling install_tables\n") );
98   f(&symbol_table,&i_UTIL_table);
99   mm_log( (1,"Call ok.\n") ); 
100  
101   if ( (shl_findsym(&tt_handle, I_FUNCTION_LIST ,TYPE_UNDEFINED,(func_ptr*)&function_list))) return NULL; 
102   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
103     return NULL;
104
105   dso_handle->handle=tt_handle; /* needed to close again */
106   dso_handle->function_list=function_list;
107   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
108     free(dso_handle); return NULL;
109   }
110   strcpy(dso_handle->filename,file);
111
112   mm_log((1,"DSO_open <- (0x%X)\n",dso_handle));
113   return (void*)dso_handle;
114 }
115
116 undef_int
117 DSO_close(void *ptr) {
118   DSO_handle *handle=(DSO_handle*) ptr;
119   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
120   return !shl_unload((handle->handle));
121 }
122
123 #elif defined(WIN32)
124
125 void *
126 DSO_open(char *file, char **evalstring) {
127   HMODULE d_handle;
128   func_ptr *function_list;
129   DSO_handle *dso_handle;
130   
131   void (*f)(void *s,void *u); /* these will just have to be void for now */
132
133   mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",file,file,evalstring) );
134
135   *evalstring = NULL;
136   if ((d_handle = LoadLibrary(file)) == NULL) {
137     mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError()));
138     return NULL;
139   }
140   if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) {
141     mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError()));
142     FreeLibrary(d_handle);
143     return NULL;
144   }
145   if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) {
146     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError()));
147     FreeLibrary(d_handle);
148     return NULL;
149   }
150   mm_log((1, "Calling install tables\n"));
151   f(&symbol_table, &i_UTIL_table);
152   mm_log((1, "Call ok\n"));
153   
154   if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) {
155     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError()));
156     FreeLibrary(d_handle);
157     return NULL;
158   }
159   if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { /* checked 17jul05 tonyc */
160     mm_log( (1, "DSO_Open: out of memory\n") );
161     FreeLibrary(d_handle);
162     return NULL;
163   }
164   dso_handle->handle=d_handle; /* needed to close again */
165   dso_handle->function_list=function_list;
166   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
167     free(dso_handle);
168     FreeLibrary(d_handle); 
169     return NULL; 
170   }
171   strcpy(dso_handle->filename,file);
172
173   mm_log( (1,"DSO_open <- %p\n",dso_handle) );
174   return (void*)dso_handle;
175
176 }
177
178 undef_int
179 DSO_close(void *ptr) {
180   DSO_handle *handle = (DSO_handle *)ptr;
181   BOOL result = FreeLibrary(handle->handle);
182   free(handle->filename);
183   free(handle);
184
185   return result;
186 }
187
188 #else
189
190 /* OS/2 has no dlclose; Perl doesn't provide one. */
191 #ifdef __EMX__ /* OS/2 */
192 int
193 dlclose(minthandle_t h) {
194   return DosFreeModule(h) ? -1 : 0;
195 }
196 #endif /* __EMX__ */
197
198 void*
199 DSO_open(char* file,char** evalstring) {
200   void *d_handle;
201   func_ptr *function_list;
202   DSO_handle *dso_handle;
203
204   void (*f)(void *s,void *u); /* these will just have to be void for now */
205   
206   *evalstring=NULL;
207
208   mm_log( (1,"DSO_open(file '%s' (%p), evalstring %p)\n",
209            file, file, evalstring) );
210
211   if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
212     mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
213     return NULL;
214   }
215
216   if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) {
217     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) );
218     return NULL;
219   }
220
221   /*
222
223     I'll just leave this thing in here for now if I need it real soon
224
225    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE ));
226    if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) {
227      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) );
228      return NULL;
229    }
230   
231    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE ));
232     if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) {
233      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) );
234      return NULL;
235    }
236
237   */
238
239   f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES);
240   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES ));
241   if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) {
242     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) );
243     return NULL;
244   }
245
246   mm_log( (1,"Calling install_tables\n") );
247   f(&symbol_table,&i_UTIL_table);
248   mm_log( (1,"Call ok.\n") );
249
250   /* (*plugin_symtab)=&symbol_table;
251      (*plugin_utiltab)=&i_UTIL_table; */
252   
253   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST ));
254   if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) {
255     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) );
256     return NULL;
257   }
258   
259   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
260     return NULL;
261   
262   dso_handle->handle=d_handle; /* needed to close again */
263   dso_handle->function_list=function_list;
264   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
265     free(dso_handle); 
266     return NULL;
267   }
268   strcpy(dso_handle->filename,file);
269
270   mm_log( (1,"DSO_open <- %p\n",dso_handle) );
271   return (void*)dso_handle;
272 }
273
274 undef_int
275 DSO_close(void *ptr) {
276   DSO_handle *handle;
277   mm_log((1,"DSO_close(ptr %p)\n",ptr));
278   handle=(DSO_handle*) ptr;
279   return !dlclose(handle->handle);
280 }
281
282 #endif
283