Commit | Line | Data |
a0d0e21e |
1 | /* dlutils.c - handy functions and definitions for dl_*.xs files |
2 | * |
3 | * Currently this file is simply #included into dl_*.xs/.c files. |
4 | * It should really be split into a dlutils.h and dlutils.c |
5 | * |
abb9e9dc |
6 | * Modified: |
7 | * 29th Feburary 2000 - Alan Burlison: Added functionality to close dlopen'd |
8 | * files when the interpreter exits |
a0d0e21e |
9 | */ |
10 | |
11 | |
12 | /* pointer to allocated memory for last error message */ |
13 | static char *LastError = (char*)NULL; |
14 | |
8e07c86e |
15 | /* flag for immediate rather than lazy linking (spots unresolved symbol) */ |
16 | static int dl_nonlazy = 0; |
17 | |
18 | #ifdef DL_LOADONCEONLY |
19 | static HV *dl_loaded_files = Nullhv; /* only needed on a few systems */ |
20 | #endif |
a0d0e21e |
21 | |
22 | |
23 | #ifdef DEBUGGING |
1001cf6c |
24 | static int dl_debug = 0; /* value copied from $DynaLoader::dl_debug */ |
8e07c86e |
25 | #define DLDEBUG(level,code) if (dl_debug>=level) { code; } |
a0d0e21e |
26 | #else |
27 | #define DLDEBUG(level,code) |
28 | #endif |
29 | |
c6c619a9 |
30 | #ifdef DL_UNLOAD_ALL_AT_EXIT |
abb9e9dc |
31 | /* Close all dlopen'd files */ |
32 | static void |
33 | dl_unload_all_files(pTHXo_ void *unused) |
34 | { |
35 | CV *sub; |
36 | AV *dl_librefs; |
37 | SV *dl_libref; |
38 | |
39 | if ((sub = get_cv("DynaLoader::dl_unload_file", FALSE)) != NULL) { |
40 | dl_librefs = get_av("DynaLoader::dl_librefs", FALSE); |
41 | while ((dl_libref = av_pop(dl_librefs)) != &PL_sv_undef) { |
42 | dSP; |
43 | ENTER; |
44 | SAVETMPS; |
45 | PUSHMARK(SP); |
46 | XPUSHs(sv_2mortal(dl_libref)); |
47 | PUTBACK; |
22851543 |
48 | call_sv((SV*)sub, G_DISCARD | G_NODEBUG); |
abb9e9dc |
49 | FREETMPS; |
50 | LEAVE; |
51 | } |
52 | } |
53 | } |
c6c619a9 |
54 | #endif |
abb9e9dc |
55 | |
a0d0e21e |
56 | static void |
0cb96387 |
57 | dl_generic_private_init(pTHXo) /* called by dl_*.xs dl_private_init() */ |
a0d0e21e |
58 | { |
8e07c86e |
59 | char *perl_dl_nonlazy; |
a0d0e21e |
60 | #ifdef DEBUGGING |
9426adcd |
61 | SV *sv = get_sv("DynaLoader::dl_debug", 0); |
62 | dl_debug = sv ? SvIV(sv) : 0; |
8e07c86e |
63 | #endif |
64 | if ( (perl_dl_nonlazy = getenv("PERL_DL_NONLAZY")) != NULL ) |
65 | dl_nonlazy = atoi(perl_dl_nonlazy); |
66 | if (dl_nonlazy) |
bf49b057 |
67 | DLDEBUG(1,PerlIO_printf(Perl_debug_log, "DynaLoader bind mode is 'non-lazy'\n")); |
8e07c86e |
68 | #ifdef DL_LOADONCEONLY |
69 | if (!dl_loaded_files) |
70 | dl_loaded_files = newHV(); /* provide cache for dl_*.xs if needed */ |
a0d0e21e |
71 | #endif |
23d2500b |
72 | #ifdef DL_UNLOAD_ALL_AT_EXIT |
abb9e9dc |
73 | call_atexit(&dl_unload_all_files, (void*)0); |
23d2500b |
74 | #endif |
a0d0e21e |
75 | } |
76 | |
77 | |
78 | /* SaveError() takes printf style args and saves the result in LastError */ |
a0d0e21e |
79 | static void |
0cb96387 |
80 | SaveError(pTHXo_ char* pat, ...) |
a0d0e21e |
81 | { |
82 | va_list args; |
a6c40364 |
83 | SV *msv; |
a0d0e21e |
84 | char *message; |
a6c40364 |
85 | STRLEN len; |
a0d0e21e |
86 | |
8e07c86e |
87 | /* This code is based on croak/warn, see mess() in util.c */ |
a0d0e21e |
88 | |
a0d0e21e |
89 | va_start(args, pat); |
5a844595 |
90 | msv = vmess(pat, &args); |
a0d0e21e |
91 | va_end(args); |
92 | |
a6c40364 |
93 | message = SvPV(msv,len); |
94 | len++; /* include terminating null char */ |
a0d0e21e |
95 | |
96 | /* Allocate some memory for the error message */ |
97 | if (LastError) |
98 | LastError = (char*)saferealloc(LastError, len) ; |
99 | else |
2e5d53bf |
100 | LastError = (char *) safemalloc(len) ; |
a0d0e21e |
101 | |
102 | /* Copy message into LastError (including terminating null char) */ |
103 | strncpy(LastError, message, len) ; |
bf49b057 |
104 | DLDEBUG(2,PerlIO_printf(Perl_debug_log, "DynaLoader: stored error msg '%s'\n",LastError)); |
a0d0e21e |
105 | } |
106 | |