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; |