| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
=head1 NAME |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
DynaLoader::Functions - deconstructed dynamic C library loading |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use DynaLoader::Functions qw( |
|
8
|
|
|
|
|
|
|
loadable_for_module |
|
9
|
|
|
|
|
|
|
linkable_for_loadable linkable_for_module); |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
$loadable = loadable_for_module("Acme::Widget"); |
|
12
|
|
|
|
|
|
|
@linkable = linkable_for_loadable($loadable); |
|
13
|
|
|
|
|
|
|
@linkable = linkable_for_module("Acme::Widget"); |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use DynaLoader::Functions qw(dyna_load dyna_resolve dyna_unload); |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
$libh = dyna_load($loadable, { |
|
18
|
|
|
|
|
|
|
require_symbols => ["boot_Acme__Widget"], |
|
19
|
|
|
|
|
|
|
}); |
|
20
|
|
|
|
|
|
|
my $bootfunc = dyna_resolve($libh, "boot_Acme__Widget"); |
|
21
|
|
|
|
|
|
|
dyna_unload($libh); |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
This module provides a function-based interface to dynamic loading as used |
|
26
|
|
|
|
|
|
|
by Perl. Some details of dynamic loading are very platform-dependent, |
|
27
|
|
|
|
|
|
|
so correct use of these functions requires the programmer to be mindful |
|
28
|
|
|
|
|
|
|
of the space of platform variations. |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=cut |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
package DynaLoader::Functions; |
|
33
|
|
|
|
|
|
|
|
|
34
|
2
|
|
|
2
|
|
244495
|
{ use 5.006; } |
|
|
2
|
|
|
|
|
8
|
|
|
35
|
2
|
|
|
2
|
|
13
|
use warnings; |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
73
|
|
|
36
|
2
|
|
|
2
|
|
15
|
use strict; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
71
|
|
|
37
|
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
our $VERSION = "0.003"; |
|
39
|
|
|
|
|
|
|
|
|
40
|
2
|
|
|
2
|
|
244
|
use parent "Exporter"; |
|
|
2
|
|
|
|
|
228
|
|
|
|
2
|
|
|
|
|
15
|
|
|
41
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
|
42
|
|
|
|
|
|
|
loadable_for_module linkable_for_loadable linkable_for_module |
|
43
|
|
|
|
|
|
|
dyna_load dyna_resolve dyna_unload |
|
44
|
|
|
|
|
|
|
); |
|
45
|
|
|
|
|
|
|
|
|
46
|
2
|
|
|
2
|
|
138
|
use constant _IS_VMS => $^O eq "VMS"; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
153
|
|
|
47
|
2
|
|
|
2
|
|
9
|
use constant _IS_NETWARE => $^O eq "NetWare"; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
2800
|
|
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# It is presumed that VMS::Filespec will always be installed on VMS. |
|
50
|
|
|
|
|
|
|
# It is not listed as a dependency of this module, because it is |
|
51
|
|
|
|
|
|
|
# unavailable on other platforms. |
|
52
|
|
|
|
|
|
|
require VMS::Filespec if _IS_VMS; |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# Load Carp lazily, as do DynaLoader and other things at this level. |
|
55
|
0
|
|
|
0
|
|
0
|
sub _carp { require Carp; Carp::carp(@_); } |
|
|
0
|
|
|
|
|
0
|
|
|
56
|
0
|
|
|
0
|
|
0
|
sub _croak { require Carp; Carp::croak(@_); } |
|
|
0
|
|
|
|
|
0
|
|
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# Logic duplicated from Params::Classify. This is too much of an |
|
59
|
|
|
|
|
|
|
# infrastructure module, an early build dependency, for it to have such |
|
60
|
|
|
|
|
|
|
# a dependency. |
|
61
|
|
|
|
|
|
|
sub _is_string($) { |
|
62
|
6
|
|
|
6
|
|
18
|
my($arg) = @_; |
|
63
|
6
|
|
33
|
|
|
100
|
return defined($arg) && ref(\$arg) eq "SCALAR"; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
1
|
50
|
|
1
|
|
9
|
sub _check_string($) { die "argument is not a string\n" unless &_is_string; } |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# Logic duplicated from Module::Runtime for the same reason. |
|
68
|
|
|
|
|
|
|
sub _check_module_name($) { |
|
69
|
0
|
0
|
|
0
|
|
0
|
if(!&_is_string) { |
|
|
|
0
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
0
|
die "argument is not a module name\n"; |
|
71
|
|
|
|
|
|
|
} elsif($_[0] !~ /\A[A-Z_a-z][0-9A-Z_a-z]*(?:::[0-9A-Z_a-z]+)*\z/) { |
|
72
|
0
|
|
|
|
|
0
|
die "`$_[0]' is not a module name\n"; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 File finding |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
=over |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=item loadable_for_module(MODULE_NAME) |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
I<MODULE_NAME> must be the name of a Perl module, in bareword syntax with |
|
85
|
|
|
|
|
|
|
C<::> separators. The named module is presumed to be an XS extension |
|
86
|
|
|
|
|
|
|
following standard conventions, and its runtime-loadable C library file is |
|
87
|
|
|
|
|
|
|
searched for. If found, the name of the library file is returned. If it |
|
88
|
|
|
|
|
|
|
cannot be found, the function C<die>s with an informative error message. |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
If the named module is actually not an XS extension, or is not installed, |
|
91
|
|
|
|
|
|
|
or stores its C library in a non-standard place, there is a non-trivial |
|
92
|
|
|
|
|
|
|
danger that this function will find some other library file and believe |
|
93
|
|
|
|
|
|
|
it to be the right one. This function should therefore only be used |
|
94
|
|
|
|
|
|
|
when there is an expectation that the module is installed and would in |
|
95
|
|
|
|
|
|
|
normal operation load its corresponding C library. |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=cut |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub loadable_for_module($) { |
|
100
|
0
|
|
|
0
|
1
|
0
|
my($modname) = @_; |
|
101
|
0
|
|
|
|
|
0
|
_check_module_name($modname); |
|
102
|
0
|
|
|
|
|
0
|
require DynaLoader; |
|
103
|
|
|
|
|
|
|
# This logic is derived from DynaLoader::bootstrap(). In places |
|
104
|
|
|
|
|
|
|
# it mixes native directory names from @INC and Unix-style |
|
105
|
|
|
|
|
|
|
# /-separated path syntax. This apparently works correctly |
|
106
|
|
|
|
|
|
|
# everywhere, except for VMS where there's an explicit conversion. |
|
107
|
0
|
|
|
|
|
0
|
my @modparts = split(/::/,$modname); |
|
108
|
0
|
|
|
|
|
0
|
my $modfname = $modparts[-1]; |
|
109
|
0
|
0
|
|
|
|
0
|
$modfname = &DynaLoader::mod2fname(\@modparts) |
|
110
|
|
|
|
|
|
|
if defined &DynaLoader::mod2fname; |
|
111
|
0
|
|
|
|
|
0
|
if(_IS_NETWARE) { |
|
112
|
|
|
|
|
|
|
# This ought to be part of mod2fname. |
|
113
|
|
|
|
|
|
|
$modfname = substr($modfname, 0, 8); |
|
114
|
|
|
|
|
|
|
} |
|
115
|
0
|
|
|
|
|
0
|
my $modpname = join("/",@modparts); |
|
116
|
|
|
|
|
|
|
my $loadlib = DynaLoader::dl_findfile( |
|
117
|
|
|
|
|
|
|
(map { |
|
118
|
0
|
0
|
|
|
|
0
|
my $d = $_; |
|
|
0
|
|
|
|
|
0
|
|
|
119
|
0
|
|
|
|
|
0
|
if(_IS_VMS) { |
|
120
|
|
|
|
|
|
|
$d = VMS::Filespec::unixpath($d); |
|
121
|
|
|
|
|
|
|
chop $d; |
|
122
|
|
|
|
|
|
|
} |
|
123
|
0
|
|
|
|
|
0
|
"-L$d/auto/$modpname"; |
|
124
|
|
|
|
|
|
|
} @INC), |
|
125
|
|
|
|
|
|
|
@INC, |
|
126
|
|
|
|
|
|
|
$modfname) |
|
127
|
|
|
|
|
|
|
or _croak "Can't locate loadable object ". |
|
128
|
|
|
|
|
|
|
"for module $modname in \@INC (\@INC contains: @INC)"; |
|
129
|
0
|
|
|
|
|
0
|
if(_IS_VMS && ((require Config), |
|
130
|
|
|
|
|
|
|
$Config::Config{d_vms_case_sensitive_symbols})) { |
|
131
|
|
|
|
|
|
|
$loadlib = uc($loadlib); |
|
132
|
|
|
|
|
|
|
} |
|
133
|
0
|
|
|
|
|
0
|
return $loadlib; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=item linkable_for_loadable(LOADABLE_FILENAME) |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
If symbols in one runtime-loadable C library are to be made available |
|
139
|
|
|
|
|
|
|
to another runtime-loadable C library, depending on the platform it |
|
140
|
|
|
|
|
|
|
may be necessary to refer to the exporting library when linking the |
|
141
|
|
|
|
|
|
|
importing library. Generally this is not required on Unix, but it is |
|
142
|
|
|
|
|
|
|
required on Windows. Where it is required to refer to the exporting |
|
143
|
|
|
|
|
|
|
library at link time, the file used may be the loadable library file |
|
144
|
|
|
|
|
|
|
itself, or may be a separate file used only for this purpose. Given the |
|
145
|
|
|
|
|
|
|
loadable form of an exporting library, this function determines what is |
|
146
|
|
|
|
|
|
|
required at link time for an importing library. |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
I<LOADABLE_FILENAME> must be the name of a runtime-loadable C library |
|
149
|
|
|
|
|
|
|
file. The function checks what is required to link a library that will |
|
150
|
|
|
|
|
|
|
at runtime import symbols from this library. It returns a list (which |
|
151
|
|
|
|
|
|
|
will be empty on many platforms) of names of files that must be used as |
|
152
|
|
|
|
|
|
|
additional objects when linking the importing library. |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=cut |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
my $linkable_finder = { |
|
157
|
|
|
|
|
|
|
MSWin32 => sub { |
|
158
|
|
|
|
|
|
|
require Config; |
|
159
|
|
|
|
|
|
|
if((my $basename = $_[0]) =~ |
|
160
|
|
|
|
|
|
|
s/\.\Q$Config::Config{dlext}\E\z//oi) { |
|
161
|
|
|
|
|
|
|
foreach my $suffix (qw(.lib .a)) { |
|
162
|
|
|
|
|
|
|
my $impname = $basename.$suffix; |
|
163
|
|
|
|
|
|
|
return ($impname) if -e $impname; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
} |
|
166
|
|
|
|
|
|
|
_croak "Can't locate linkable object for $_[0]"; |
|
167
|
|
|
|
|
|
|
}, |
|
168
|
|
|
|
|
|
|
cygwin => sub { ($_[0]) }, |
|
169
|
|
|
|
|
|
|
}->{$^O}; |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub linkable_for_loadable($) { |
|
172
|
0
|
|
|
0
|
1
|
0
|
_check_string($_[0]); |
|
173
|
0
|
0
|
|
|
|
0
|
if($linkable_finder) { |
|
174
|
0
|
|
|
|
|
0
|
return $linkable_finder->($_[0]); |
|
175
|
|
|
|
|
|
|
} else { |
|
176
|
0
|
|
|
|
|
0
|
return (); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=item linkable_for_module(MODULE_NAME) |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Performs the job of L</linkable_for_loadable> (which see for explanation), |
|
183
|
|
|
|
|
|
|
but based on a module name instead of a loadable library filename. |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
I<MODULE_NAME> must be the name of a Perl module, in bareword syntax |
|
186
|
|
|
|
|
|
|
with C<::> separators. The function checks what is required to link a |
|
187
|
|
|
|
|
|
|
library that will at runtime import symbols from the loadable C library |
|
188
|
|
|
|
|
|
|
associated with the module. It returns a list (which will be empty |
|
189
|
|
|
|
|
|
|
on many platforms) of names of files that must be used as additional |
|
190
|
|
|
|
|
|
|
objects when linking the importing library. |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=cut |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub linkable_for_module($) { |
|
195
|
0
|
0
|
|
0
|
1
|
0
|
if($linkable_finder) { |
|
196
|
0
|
|
|
|
|
0
|
return $linkable_finder->(loadable_for_module($_[0])); |
|
197
|
|
|
|
|
|
|
} else { |
|
198
|
0
|
|
|
|
|
0
|
_check_module_name($_[0]); |
|
199
|
0
|
|
|
|
|
0
|
return (); |
|
200
|
|
|
|
|
|
|
} |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=back |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=head2 Low-level dynamic loading |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=over |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item dyna_load(LOADABLE_FILENAME[, OPTIONS]) |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
Dynamically load the runtime-loadable C library in the file named |
|
212
|
|
|
|
|
|
|
I<LOADABLE_FILENAME>. The process is influenced by optional information |
|
213
|
|
|
|
|
|
|
supplied in the hash referenced by I<OPTIONS>. On the platforms that |
|
214
|
|
|
|
|
|
|
make dynamic loading easiest it is not necessary to supply any options |
|
215
|
|
|
|
|
|
|
(in which case the parameter may be omitted), but if wide portability |
|
216
|
|
|
|
|
|
|
is required then some options are required. The permitted keys in the |
|
217
|
|
|
|
|
|
|
I<OPTIONS> hash are: |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=over |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=item B<resolve_using> |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Reference to an array, default empty, of names of additional library |
|
224
|
|
|
|
|
|
|
files required to supply symbols used by the library being loaded. |
|
225
|
|
|
|
|
|
|
On most platforms this is not used. On those platforms where it is |
|
226
|
|
|
|
|
|
|
required, the need for this will be known by whatever generated the |
|
227
|
|
|
|
|
|
|
library to be loaded, and it will normally be set by a bootstrap file |
|
228
|
|
|
|
|
|
|
(see B<use_bootstrap_options> below). |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=item B<require_symbols> |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
Reference to an array, default empty, of names of symbols expected to be |
|
233
|
|
|
|
|
|
|
found in the library being loaded. On most platforms this is not used, |
|
234
|
|
|
|
|
|
|
but on some a library cannot be loaded without naming at least one symbol |
|
235
|
|
|
|
|
|
|
for which a need can be satisfied by the library. |
|
236
|
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=item B<use_bootstrap_options> |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Truth value, default false, controlling whether a "bootstrap" file will |
|
240
|
|
|
|
|
|
|
be consulted as an additional source of options to control loading. |
|
241
|
|
|
|
|
|
|
The "bootstrap" file, if it exists, is located in the same directory as |
|
242
|
|
|
|
|
|
|
the loadable library file, and has a similar name differing only in its |
|
243
|
|
|
|
|
|
|
C<.bs> ending. |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=item B<symbols_global> |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Truth value, default false, indicating whether symbols found in the |
|
248
|
|
|
|
|
|
|
library being loaded must be made available to subsequently-loaded |
|
249
|
|
|
|
|
|
|
libraries. Depending on platform, symbols may be so available even if |
|
250
|
|
|
|
|
|
|
it is not requested. Some platforms, on the other hand, can't provide |
|
251
|
|
|
|
|
|
|
this facility. |
|
252
|
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
On platforms incapable of making loaded symbols globally available, |
|
254
|
|
|
|
|
|
|
currently loading is liable to claim success while leaving the symbols |
|
255
|
|
|
|
|
|
|
de facto unavailable. It is intended that in the future such platforms |
|
256
|
|
|
|
|
|
|
will instead generate an exception when this facility is requested. |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=item B<unresolved_action> |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
String keyword indicating what should be done if unresolved symbols are |
|
261
|
|
|
|
|
|
|
detected while loading the library. It may be "B<ERROR>" (default) |
|
262
|
|
|
|
|
|
|
to treat it as an error, "B<WARN>" to emit a warning, or "B<IGNORE>" |
|
263
|
|
|
|
|
|
|
to ignore the situation. Some platforms can't detect this problem, |
|
264
|
|
|
|
|
|
|
so passing this check doesn't guarantee that there won't be any runtime |
|
265
|
|
|
|
|
|
|
problems due to unresolved symbols. |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=back |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
On success, returns a handle that can be used to refer to the loaded |
|
270
|
|
|
|
|
|
|
library for subsequent calls to L</dyna_resolve> and L</dyna_unload>. |
|
271
|
|
|
|
|
|
|
On failure, C<die>s. |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=cut |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub dyna_load($;$) { |
|
276
|
1
|
|
|
1
|
1
|
226217
|
my($loadable_filename, $options) = @_; |
|
277
|
1
|
50
|
|
|
|
14
|
$options = {} if @_ < 2; |
|
278
|
1
|
|
|
|
|
14
|
_check_string($loadable_filename); |
|
279
|
1
|
|
|
|
|
11
|
foreach(sort keys %$options) { |
|
280
|
1
|
50
|
|
|
|
21
|
_croak "bad dyna_load option `$_'" unless /\A(?: |
|
281
|
|
|
|
|
|
|
resolve_using|require_symbols|use_bootstrap_options| |
|
282
|
|
|
|
|
|
|
symbols_global|unresolved_action |
|
283
|
|
|
|
|
|
|
)\z/x; |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
my $unres_action = exists($options->{unresolved_action}) ? |
|
286
|
1
|
50
|
|
|
|
12
|
$options->{unresolved_action} : "ERROR"; |
|
287
|
1
|
50
|
33
|
|
|
7
|
_croak "bad dyna_load unresolved_action value `$unres_action'" |
|
288
|
|
|
|
|
|
|
unless _is_string($unres_action) && |
|
289
|
|
|
|
|
|
|
$unres_action =~ /\A(?:ERROR|WARN|IGNORE)\z/; |
|
290
|
1
|
|
|
|
|
20
|
require DynaLoader; |
|
291
|
1
|
50
|
|
|
|
7
|
_croak "dynamic loading not available in this perl" |
|
292
|
|
|
|
|
|
|
unless defined &DynaLoader::dl_load_file; |
|
293
|
|
|
|
|
|
|
local @DynaLoader::dl_resolve_using = |
|
294
|
|
|
|
|
|
|
exists($options->{resolve_using}) ? |
|
295
|
1
|
50
|
|
|
|
8
|
@{$options->{resolve_using}} : (); |
|
|
0
|
|
|
|
|
0
|
|
|
296
|
|
|
|
|
|
|
local @DynaLoader::dl_require_symbols = |
|
297
|
|
|
|
|
|
|
exists($options->{require_symbols}) ? |
|
298
|
1
|
50
|
|
|
|
8
|
@{$options->{require_symbols}} : (); |
|
|
1
|
|
|
|
|
9
|
|
|
299
|
1
|
50
|
|
|
|
7
|
if($options->{use_bootstrap_options}) { |
|
300
|
0
|
|
|
|
|
0
|
(my $bs = $loadable_filename) =~ |
|
301
|
|
|
|
|
|
|
s/(?:\.[0-9A-Z_a-z]+)?(?:;[0-9]*)?\z/\.bs/; |
|
302
|
0
|
0
|
|
|
|
0
|
if(-s $bs) { |
|
303
|
0
|
|
|
|
|
0
|
eval { package DynaLoader; do $bs; }; |
|
|
0
|
|
|
|
|
0
|
|
|
304
|
0
|
0
|
|
|
|
0
|
warn "$bs: $@" if $@ ne ""; |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
} |
|
307
|
|
|
|
|
|
|
my $libh = DynaLoader::dl_load_file($loadable_filename, |
|
308
|
1
|
50
|
|
|
|
121
|
$options->{symbols_global} ? 0x01 : 0) |
|
|
|
50
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
or _croak "failed to load library $loadable_filename: ". |
|
310
|
0
|
|
|
|
|
0
|
"@{[DynaLoader::dl_error()]}"; |
|
311
|
1
|
50
|
33
|
|
|
20
|
if($unres_action ne "IGNORE" && |
|
312
|
|
|
|
|
|
|
(my @unresolved = DynaLoader::dl_undef_symbols())) { |
|
313
|
0
|
|
|
|
|
0
|
my $e = "undefined symbols in $loadable_filename: @unresolved"; |
|
314
|
0
|
0
|
|
|
|
0
|
if($unres_action eq "ERROR") { |
|
315
|
0
|
|
|
|
|
0
|
DynaLoader::dl_unload_file($libh); |
|
316
|
0
|
|
|
|
|
0
|
_croak $e; |
|
317
|
|
|
|
|
|
|
} else { |
|
318
|
0
|
|
|
|
|
0
|
_carp $e; |
|
319
|
|
|
|
|
|
|
} |
|
320
|
|
|
|
|
|
|
} |
|
321
|
1
|
|
|
|
|
8
|
return $libh; |
|
322
|
|
|
|
|
|
|
} |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=item dyna_resolve(LIBRARY_HANDLE, SYMBOL_NAME[, OPTIONS]) |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
Resolve the symbol I<SYMBOL> in the previously-loaded library |
|
327
|
|
|
|
|
|
|
identified by the I<LIBRARY_HANDLE>. The process is influenced by |
|
328
|
|
|
|
|
|
|
optional information supplied in the hash referenced by I<OPTIONS>. |
|
329
|
|
|
|
|
|
|
The permitted keys in the I<OPTIONS> hash are: |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=over |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=item B<unresolved_action> |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
String keyword indicating what should be done if the symbol cannot |
|
336
|
|
|
|
|
|
|
be resolved. It may be "B<ERROR>" (default) to treat it as an error, |
|
337
|
|
|
|
|
|
|
"B<WARN>" to emit a warning and return C<undef>, or "B<IGNORE>" to return |
|
338
|
|
|
|
|
|
|
C<undef> without a warning. |
|
339
|
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=back |
|
341
|
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
On success, returns the value of the specified symbol, in a |
|
343
|
|
|
|
|
|
|
platform-dependent format. Returns C<undef> if the symbol could not be |
|
344
|
|
|
|
|
|
|
resolved and this is not being treated as an error. |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=cut |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
sub dyna_resolve($$;$) { |
|
349
|
3
|
|
|
3
|
1
|
840
|
my($libh, $symbol, $options) = @_; |
|
350
|
3
|
50
|
|
|
|
13
|
$options = {} if @_ < 3; |
|
351
|
3
|
|
|
|
|
19
|
foreach(sort keys %$options) { |
|
352
|
3
|
50
|
|
|
|
23
|
_croak "bad dyna_resolve option `$_'" |
|
353
|
|
|
|
|
|
|
unless /\Aunresolved_action\z/; |
|
354
|
|
|
|
|
|
|
} |
|
355
|
|
|
|
|
|
|
my $unres_action = exists($options->{unresolved_action}) ? |
|
356
|
3
|
50
|
|
|
|
15
|
$options->{unresolved_action} : "ERROR"; |
|
357
|
3
|
50
|
33
|
|
|
11
|
_croak "bad dyna_load unresolved_action value `$unres_action'" |
|
358
|
|
|
|
|
|
|
unless _is_string($unres_action) && |
|
359
|
|
|
|
|
|
|
$unres_action =~ /\A(?:ERROR|WARN|IGNORE)\z/; |
|
360
|
3
|
|
|
|
|
26
|
require DynaLoader; |
|
361
|
3
|
|
|
|
|
49
|
my $val = DynaLoader::dl_find_symbol($libh, $symbol); |
|
362
|
3
|
50
|
66
|
|
|
22
|
if(!defined($val) && $unres_action ne "IGNORE") { |
|
363
|
0
|
|
|
|
|
0
|
my $e = "undefined symbol: $symbol"; |
|
364
|
0
|
0
|
|
|
|
0
|
if($unres_action eq "ERROR") { |
|
365
|
0
|
|
|
|
|
0
|
_croak $e; |
|
366
|
|
|
|
|
|
|
} else { |
|
367
|
0
|
|
|
|
|
0
|
_carp $e; |
|
368
|
|
|
|
|
|
|
} |
|
369
|
|
|
|
|
|
|
} |
|
370
|
3
|
|
|
|
|
24
|
return $val; |
|
371
|
|
|
|
|
|
|
} |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=item dyna_unload(LIBRARY_HANDLE[, OPTIONS]) |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
Unload the previously-loaded library identified by the I<LIBRARY_HANDLE>. |
|
376
|
|
|
|
|
|
|
The process is influenced by optional information supplied in the hash |
|
377
|
|
|
|
|
|
|
referenced by I<OPTIONS>. The permitted keys in the I<OPTIONS> hash are: |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=over |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=item B<fail_action> |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
String keyword indicating what should be done if unloading detectably |
|
384
|
|
|
|
|
|
|
fails. It may be "B<ERROR>" (default) to treat it as an error, "B<WARN>" |
|
385
|
|
|
|
|
|
|
to emit a warning, or "B<IGNORE>" to ignore the situation. |
|
386
|
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=back |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
On some platforms unloading is not possible. On any platform, |
|
390
|
|
|
|
|
|
|
unloading can be expected to cause mayhem if any code from the library |
|
391
|
|
|
|
|
|
|
is currently executing, if there are any live references to data in the |
|
392
|
|
|
|
|
|
|
library, or if any symbols provided by the library are referenced by |
|
393
|
|
|
|
|
|
|
any subsequently-loaded library. |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=cut |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
sub dyna_unload($;$) { |
|
398
|
1
|
|
|
1
|
1
|
4
|
my($libh, $options) = @_; |
|
399
|
1
|
50
|
|
|
|
6
|
$options = {} if @_ < 2; |
|
400
|
1
|
|
|
|
|
7
|
foreach(sort keys %$options) { |
|
401
|
1
|
50
|
|
|
|
11
|
_croak "bad dyna_unload option `$_'" unless /\Afail_action\z/; |
|
402
|
|
|
|
|
|
|
} |
|
403
|
|
|
|
|
|
|
my $fail_action = exists($options->{fail_action}) ? |
|
404
|
1
|
50
|
|
|
|
8
|
$options->{fail_action} : "ERROR"; |
|
405
|
1
|
50
|
33
|
|
|
5
|
_croak "bad dyna_load fail_action value `$fail_action'" |
|
406
|
|
|
|
|
|
|
unless _is_string($fail_action) && |
|
407
|
|
|
|
|
|
|
$fail_action =~ /\A(?:ERROR|WARN|IGNORE)\z/; |
|
408
|
1
|
|
|
|
|
4
|
my $err; |
|
409
|
1
|
|
|
|
|
7
|
require DynaLoader; |
|
410
|
1
|
50
|
|
|
|
6
|
if(defined &DynaLoader::dl_unload_file) { |
|
411
|
1
|
50
|
|
|
|
64
|
DynaLoader::dl_unload_file($_[0]) |
|
412
|
|
|
|
|
|
|
or $err = DynaLoader::dl_error(); |
|
413
|
|
|
|
|
|
|
} else { |
|
414
|
0
|
|
|
|
|
0
|
$err = "can't unload on this platform"; |
|
415
|
|
|
|
|
|
|
} |
|
416
|
1
|
50
|
33
|
|
|
10
|
if(defined($err) && $fail_action ne "IGNORE") { |
|
417
|
0
|
|
|
|
|
|
my $e = "failed to unload library: $err"; |
|
418
|
0
|
0
|
|
|
|
|
if($fail_action eq "ERROR") { |
|
419
|
0
|
|
|
|
|
|
_croak $e; |
|
420
|
|
|
|
|
|
|
} else { |
|
421
|
0
|
|
|
|
|
|
_carp $e; |
|
422
|
|
|
|
|
|
|
} |
|
423
|
|
|
|
|
|
|
} |
|
424
|
|
|
|
|
|
|
} |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=back |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
L<DynaLoader>, |
|
431
|
|
|
|
|
|
|
L<ExtUtils::CBuilder>, |
|
432
|
|
|
|
|
|
|
L<XSLoader> |
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=head1 AUTHOR |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
Andrew Main (Zefram) <zefram@fysh.org> |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=head1 COPYRIGHT |
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Copyright (C) 2011, 2012, 2013, 2017 |
|
441
|
|
|
|
|
|
|
Andrew Main (Zefram) <zefram@fysh.org> |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head1 LICENSE |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
This module is free software; you can redistribute it and/or modify it |
|
446
|
|
|
|
|
|
|
under the same terms as Perl itself. |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=cut |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
1; |