]> git.imager.perl.org - imager.git/blob - dynaload.c
- added support for registering file readers
[imager.git] / dynaload.c
1 #include "imager.h"
2 #include "dynaload.h"
3 /* #include "XSUB.h"  so we can compile on threaded perls */
4 #include "imageri.h"
5
6 static symbol_table_t symbol_table=
7   {
8     i_has_format,
9     ICL_set_internal,
10     ICL_info,
11     i_img_new,
12     i_img_empty,
13     i_img_empty_ch,
14     i_img_exorcise,
15     i_img_info,
16     i_img_setmask,
17     i_img_getmask,
18     i_box,
19     i_line,
20     i_arc,
21     i_copyto,
22     i_copyto_trans,
23     i_rubthru
24   };
25
26
27 /*
28   Dynamic loading works like this:
29   dynaload opens the shared object and
30   loads all the functions into an array of functions
31   it returns a string from the dynamic function that
32   can be supplied to the parser for evaling.
33 */
34
35 void
36 DSO_call(DSO_handle *handle,int func_index,HV* hv) {
37   mm_log((1,"DSO_call(handle 0x%X, func_index %d, hv 0x%X)\n",handle,func_index,hv));
38   (handle->function_list[func_index].iptr)((void*)hv);
39 }
40
41
42 #if defined( OS_hpux )
43
44 void*
45 DSO_open(char* file,char** evalstring) {
46   shl_t tt_handle;
47   void *d_handle,**plugin_symtab,**plugin_utiltab;
48   int  rc,*iptr, (*fptr)(int);
49   func_ptr *function_list;
50   DSO_handle *dso_handle;
51   void (*f)(void *s,void *u); /* these will just have to be void for now */
52   int i;
53
54   *evalstring=NULL;
55
56   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
57
58   if ( (tt_handle = shl_load(file, BIND_DEFERRED,0L)) == NULL) return NULL; 
59   if ( (shl_findsym(&tt_handle, I_EVALSTR,TYPE_UNDEFINED,(void*)evalstring))) return NULL;
60
61   /*
62   if ( (shl_findsym(&tt_handle, "symbol_table",TYPE_UNDEFINED,(void*)&plugin_symtab))) return NULL;
63   if ( (shl_findsym(&tt_handle, "util_table",TYPE_UNDEFINED,&plugin_utiltab))) return NULL;
64   (*plugin_symtab)=&symbol_table;
65   (*plugin_utiltab)=&i_UTIL_table;
66   */
67
68   if ( (shl_findsym(&tt_handle, I_INSTALL_TABLES ,TYPE_UNDEFINED, &f ))) return NULL; 
69  
70   mm_log( (1,"Calling install_tables\n") );
71   f(&symbol_table,&i_UTIL_table);
72   mm_log( (1,"Call ok.\n") ); 
73  
74   if ( (shl_findsym(&tt_handle, I_FUNCTION_LIST ,TYPE_UNDEFINED,(func_ptr*)&function_list))) return NULL; 
75   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
76     return NULL;
77
78   dso_handle->handle=tt_handle; /* needed to close again */
79   dso_handle->function_list=function_list;
80   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
81     free(dso_handle); return NULL;
82   }
83   strcpy(dso_handle->filename,file);
84
85   mm_log((1,"DSO_open <- (0x%X)\n",dso_handle));
86   return (void*)dso_handle;
87 }
88
89 undef_int
90 DSO_close(void *ptr) {
91   DSO_handle *handle=(DSO_handle*) ptr;
92   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
93   return !shl_unload((handle->handle));
94 }
95
96 #elif defined(WIN32)
97
98 void *
99 DSO_open(char *file, char **evalstring) {
100   HMODULE d_handle;
101   func_ptr *function_list;
102   DSO_handle *dso_handle;
103   
104   void (*f)(void *s,void *u); /* these will just have to be void for now */
105
106   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
107
108   *evalstring = NULL;
109   if ((d_handle = LoadLibrary(file)) == NULL) {
110     mm_log((1, "DSO_open: LoadLibrary(%s) failed: %lu\n", file, GetLastError()));
111     return NULL;
112   }
113   if ( (*evalstring = (char *)GetProcAddress(d_handle, I_EVALSTR)) == NULL) {
114     mm_log((1,"DSO_open: GetProcAddress didn't fine '%s': %lu\n", I_EVALSTR, GetLastError()));
115     FreeLibrary(d_handle);
116     return NULL;
117   }
118   if ((f = (void (*)(void *, void*))GetProcAddress(d_handle, I_INSTALL_TABLES)) == NULL) {
119     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_INSTALL_TABLES, GetLastError()));
120     FreeLibrary(d_handle);
121     return NULL;
122   }
123   mm_log((1, "Calling install tables\n"));
124   f(&symbol_table, &i_UTIL_table);
125   mm_log((1, "Call ok\n"));
126   
127   if ( (function_list = (func_ptr *)GetProcAddress(d_handle, I_FUNCTION_LIST)) == NULL) {
128     mm_log((1, "DSO_open: GetProcAddress didn't find '%s': %lu\n", I_FUNCTION_LIST, GetLastError()));
129     FreeLibrary(d_handle);
130     return NULL;
131   }
132   if ( (dso_handle = (DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) { /* checked 17jul05 tonyc */
133     mm_log( (1, "DSO_Open: out of memory\n") );
134     FreeLibrary(d_handle);
135     return NULL;
136   }
137   dso_handle->handle=d_handle; /* needed to close again */
138   dso_handle->function_list=function_list;
139   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
140     free(dso_handle);
141     FreeLibrary(d_handle); 
142     return NULL; 
143   }
144   strcpy(dso_handle->filename,file);
145
146   mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
147   return (void*)dso_handle;
148
149 }
150
151 undef_int
152 DSO_close(void *ptr) {
153   DSO_handle *handle = (DSO_handle *)ptr;
154   BOOL result = FreeLibrary(handle->handle);
155   free(handle->filename);
156   free(handle);
157
158   return result;
159 }
160
161 #else
162
163 /* OS/2 has no dlclose; Perl doesn't provide one. */
164 #ifdef __EMX__ /* OS/2 */
165 int
166 dlclose(minthandle_t h) {
167   return DosFreeModule(h) ? -1 : 0;
168 }
169 #endif /* __EMX__ */
170
171 #ifdef OS_darwin
172
173 #import <mach-o/dyld.h>
174
175 static char *dl_error = "unknown";
176
177 static char *dlopen(char *path, int mode /* mode is ignored */)
178 {
179   int dyld_result;
180   NSObjectFileImage ofile;
181   NSModule handle = NULL;
182
183
184
185   dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
186   if (dyld_result != NSObjectFileImageSuccess)
187     {
188      switch (dyld_result) {
189        case NSObjectFileImageFailure:
190            dl_error = "object file setup failure";
191            break;
192        case NSObjectFileImageInappropriateFile:
193            dl_error = "not a Mach-O MH_BUNDLE file type";
194            break;
195        case NSObjectFileImageArch:
196            dl_error = "no object for this architecture";
197            break;
198        case NSObjectFileImageFormat:
199            dl_error = "bad object file format";
200            break;
201        case NSObjectFileImageAccess:
202            dl_error = "can't read object file";
203            break;
204        default:
205            dl_error = "unknown error from NSCreateObjectFileImageFromFile()";
206            break;
207      }
208     }
209     else
210       {
211         // NSLinkModule will cause the run to abort on any link error's
212         // not very friendly but the error recovery functionality is limited.
213         handle = NSLinkModule(ofile, path, TRUE);
214       }
215
216   return handle;
217 }
218
219 static void *
220 dlsym(void *handle, char *symbol)
221 {
222   void *addr;
223
224   if (NSIsSymbolNameDefined(symbol))
225   {
226     addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
227   }
228   else
229   {
230     dl_error = "cannot find symbol";
231     addr = NULL;
232   }
233
234   return addr;
235 }
236
237 static int dlclose(void *handle) /* stub only */
238 {
239   return 0;
240 }
241
242 static char *dlerror(void) /* stub only */
243 {
244   printf("Error occurred\n");
245   return dl_error; 
246 }
247
248 #define RTLD_LAZY 0
249
250 #endif 
251
252 void*
253 DSO_open(char* file,char** evalstring) {
254   void *d_handle;
255   func_ptr *function_list;
256   DSO_handle *dso_handle;
257
258   void (*f)(void *s,void *u); /* these will just have to be void for now */
259   
260   *evalstring=NULL;
261
262   mm_log( (1,"DSO_open(file '%s' (0x%08X), evalstring 0x%08X)\n",file,file,evalstring) );
263
264   if ( (d_handle = dlopen(file, RTLD_LAZY)) == NULL) {
265     mm_log( (1,"DSO_open: dlopen failed: %s.\n",dlerror()) );
266     return NULL;
267   }
268
269   if ( (*evalstring = (char *)dlsym(d_handle, I_EVALSTR)) == NULL) {
270     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_EVALSTR,dlerror()) );
271     return NULL;
272   }
273
274   /*
275
276     I'll just leave this thing in here for now if I need it real soon
277
278    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_SYMBOL_TABLE ));
279    if ( (plugin_symtab = dlsym(d_handle, I_SYMBOL_TABLE)) == NULL) {
280      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_SYMBOL_TABLE,dlerror()) );
281      return NULL;
282    }
283   
284    mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_UTIL_TABLE ));
285     if ( (plugin_utiltab = dlsym(d_handle, I_UTIL_TABLE)) == NULL) {
286      mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_UTIL_TABLE,dlerror()) );
287      return NULL;
288    }
289
290   */
291
292   f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES);
293   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_INSTALL_TABLES ));
294   if ( (f = (void(*)(void *s,void *u))dlsym(d_handle, I_INSTALL_TABLES)) == NULL) {
295     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_INSTALL_TABLES,dlerror()) );
296     return NULL;
297   }
298
299   mm_log( (1,"Calling install_tables\n") );
300   f(&symbol_table,&i_UTIL_table);
301   mm_log( (1,"Call ok.\n") );
302
303   /* (*plugin_symtab)=&symbol_table;
304      (*plugin_utiltab)=&i_UTIL_table; */
305   
306   mm_log( (1,"DSO_open: going to dlsym '%s'\n", I_FUNCTION_LIST ));
307   if ( (function_list=(func_ptr *)dlsym(d_handle, I_FUNCTION_LIST)) == NULL) {
308     mm_log( (1,"DSO_open: dlsym didn't find '%s': %s.\n",I_FUNCTION_LIST,dlerror()) );
309     return NULL;
310   }
311   
312   if ( (dso_handle=(DSO_handle*)malloc(sizeof(DSO_handle))) == NULL) /* checked 17jul05 tonyc */
313     return NULL;
314   
315   dso_handle->handle=d_handle; /* needed to close again */
316   dso_handle->function_list=function_list;
317   if ( (dso_handle->filename=(char*)malloc(strlen(file)+1)) == NULL) { /* checked 17jul05 tonyc */
318     free(dso_handle); 
319     return NULL;
320   }
321   strcpy(dso_handle->filename,file);
322
323   mm_log( (1,"DSO_open <- 0x%X\n",dso_handle) );
324   return (void*)dso_handle;
325 }
326
327 undef_int
328 DSO_close(void *ptr) {
329   DSO_handle *handle;
330   mm_log((1,"DSO_close(ptr 0x%X)\n",ptr));
331   handle=(DSO_handle*) ptr;
332   return !dlclose(handle->handle);
333 }
334
335 #endif
336