3 * Platform: OS/390, possibly others that use dllload(),dllfree() (VM/ESA?).
4 * Authors: John Goodyear && Peter Prymmer
5 * Created: 28 October 2000
7 * 16 January 2001 - based loosely on dl_dlopen.xs.
12 OS/390 Dynamic Loading functions:
16 dllhandle * dllload(const char *dllName)
18 This function takes the name of a dynamic object file and returns
19 a descriptor which can be used by dlllqueryfn() and/or dllqueryvar()
20 later. If dllName contains a slash, it is used to locate the dll.
21 If not then the LIBPATH environment variable is used to
22 search for the requested dll (at least within the HFS).
23 It returns NULL on error and sets errno.
27 int dllfree(dllhandle *handle);
29 dllfree() decrements the load count for the dll and frees
30 it if the count is 0. It returns zero on success, and
33 dllqueryfn && dllqueryvar
34 -------------------------
35 void (* dllqueryfn(dllhandle *handle, const char *function))();
36 void * dllqueryvar(dllhandle *handle, const char *symbol);
38 dllqueryfn() takes the handle returned from dllload() and the name
39 of a function to get the address of. If the function was found
40 a pointer is returned, otherwise NULL is returned.
42 dllqueryvar() takes the handle returned from dllload() and the name
43 of a symbol to get the address of. If the variable was found a
44 pointer is returned, otherwise NULL is returned.
46 The XS dl_find_symbol() first calls dllqueryfn(). If it fails
47 dlqueryvar() is then called.
51 char * strerror(int errno)
53 Returns a null-terminated string which describes the last error
54 that occurred with other functions (not necessarily unique to
59 In this implementation the two functions, dl_load_file() &&
60 dl_find_symbol(), return (void *). This is primarily because the
61 dlopen() && dlsym() style dynamic linker calls return (void *).
62 We suspect that casting to (void *) may be easier than teaching XS
63 typemaps about the (dllhandle *) type.
65 Dealing with Error Messages
66 ===========================
67 In order to make the handling of dynamic linking errors as generic as
68 possible you should store any error messages associated with your
69 implementation with the StoreError function.
71 In the case of OS/390 the function strerror(errno) returns the error
72 message associated with the last dynamic link error. As the S/390
73 dynamic linker functions dllload() && dllqueryvar() both return NULL
74 on error every call to an S/390 dynamic link routine is coded
77 RETVAL = dllload(filename) ;
79 SaveError("%s",strerror(errno)) ;
81 Note that SaveError() takes a printf format string. Use a "%s" as
82 the first parameter if the error may contain any % characters.
84 Other comments within the dl_dlopen.xs file may be helpful as well.
91 #include <dll.h> /* the dynamic linker include file for S/390 */
92 #include <errno.h> /* strerror() and friends */
94 #include "dlutils.c" /* SaveError() etc */
99 (void)dl_generic_private_init(aTHX);
102 MODULE = DynaLoader PACKAGE = DynaLoader
105 (void)dl_private_init(aTHX);
109 dl_load_file(filename, flags=0)
116 DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
117 /* add a (void *) dllload(filename) ; cast if needed */
118 RETVAL = dllload(filename) ;
119 DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%lx\n", (unsigned long) RETVAL));
120 ST(0) = sv_newmortal() ;
122 SaveError(aTHX_ "%s",strerror(errno)) ;
124 sv_setiv( ST(0), PTR2IV(RETVAL));
129 dl_unload_file(libref)
132 DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_unload_file(%lx):\n", PTR2ul(libref)));
133 /* RETVAL = (dllfree((dllhandle *)libref) == 0 ? 1 : 0); */
134 RETVAL = (dllfree(libref) == 0 ? 1 : 0);
136 SaveError(aTHX_ "%s", strerror(errno)) ;
137 DLDEBUG(2,PerlIO_printf(Perl_debug_log, " retval = %d\n", RETVAL));
143 dl_find_symbol(libhandle, symbolname)
147 DLDEBUG(2, PerlIO_printf(Perl_debug_log,
148 "dl_find_symbol(handle=%lx, symbol=%s)\n",
149 (unsigned long) libhandle, symbolname));
150 if((RETVAL = (void*)dllqueryfn(libhandle, symbolname)) == NULL)
151 RETVAL = dllqueryvar(libhandle, symbolname);
152 DLDEBUG(2, PerlIO_printf(Perl_debug_log,
153 " symbolref = %lx\n", (unsigned long) RETVAL));
154 ST(0) = sv_newmortal() ;
156 SaveError(aTHX_ "%s",strerror(errno)) ;
158 sv_setiv( ST(0), PTR2IV(RETVAL));
167 # These functions should not need changing on any platform:
170 dl_install_xsub(perl_name, symref, filename="$Package")
175 DLDEBUG(2,PerlIO_printf(Perl_debug_log, "dl_install_xsub(name=%s, symref=%lx)\n",
176 perl_name, (unsigned long) symref));
177 ST(0) = sv_2mortal(newRV((SV*)newXS_flags(perl_name,
178 (void(*)(pTHX_ CV *))symref,
180 XS_DYNAMIC_FILENAME)));
187 RETVAL = dl_last_error ;