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