File Coverage

blib/lib/IPC/Run/Win32Helper.pm
Criterion Covered Total %
statement 42 175 24.0
branch 1 128 0.7
condition 0 69 0.0
subroutine 14 21 66.6
pod 3 3 100.0
total 60 396 15.1


line stmt bran cond sub pod time code
1             package IPC::Run::Win32Helper;
2              
3             =pod
4              
5             =head1 NAME
6              
7             IPC::Run::Win32Helper - helper routines for IPC::Run on Win32 platforms.
8              
9             =head1 SYNOPSIS
10              
11             use IPC::Run::Win32Helper; # Exports all by default
12              
13             =head1 DESCRIPTION
14              
15             IPC::Run needs to use sockets to redirect subprocess I/O so that the select() loop
16             will work on Win32. This seems to only work on WinNT and Win2K at this time, not
17             sure if it will ever work on Win95 or Win98. If you have experience in this area, please
18             contact me at barries@slaysys.com, thanks!.
19              
20             =cut
21              
22 1     1   77889 use strict;
  1         15  
  1         30  
23 1     1   5 use warnings;
  1         3  
  1         26  
24 1     1   5 use Carp;
  1         1  
  1         50  
25 1     1   546 use IO::Handle;
  1         6302  
  1         49  
26 1     1   7 use vars qw{ $VERSION @ISA @EXPORT };
  1         2  
  1         73  
27              
28             BEGIN {
29 1     1   4 $VERSION = '20231003.0';
30 1         16 @ISA = qw( Exporter );
31 1         35 @EXPORT = qw(
32             win32_spawn
33             win32_parse_cmd_line
34             _dont_inherit
35             _inherit
36             );
37             }
38              
39             require POSIX;
40              
41 1     1   7 use File::Spec ();
  1         2  
  1         16  
42 1     1   568 use Text::ParseWords;
  1         1357  
  1         61  
43 1     1   7 use Win32 ();
  1         2  
  1         17  
44 1     1   5 use Win32::Process;
  1         2  
  1         40  
45 1     1   6 use Win32::ShellQuote ();
  1         2  
  1         15  
46 1     1   455 use IPC::Run::Debug;
  1         3  
  1         85  
47 1         86 use Win32API::File qw(
48             FdGetOsFHandle
49             SetHandleInformation
50             HANDLE_FLAG_INHERIT
51 1     1   7 );
  1         2  
52              
53             # Replace Win32API::File::INVALID_HANDLE_VALUE, which does not match the C ABI
54             # on 64-bit builds (https://github.com/chorny/Win32API-File/issues/13).
55 1 50       2580 use constant C_ABI_INVALID_HANDLE_VALUE => length( pack 'P', undef ) == 4
56             ? 0xffffffff
57 1     1   5 : 0xffffffff << 32 | 0xffffffff;
  1         3  
58              
59             ## Takes an fd or a GLOB ref, never never never a Win32 handle.
60             sub _dont_inherit {
61 0     0     for (@_) {
62 0 0         next unless defined $_;
63 0           my $fd = $_;
64 0 0         $fd = fileno $fd if ref $fd;
65 0 0         _debug "disabling inheritance of ", $fd if _debugging_details;
66 0           my $osfh = FdGetOsFHandle $fd;
67              
68             # Contrary to documentation, $! has the failure reason
69             # (https://github.com/chorny/Win32API-File/issues/14)
70 0 0 0       croak "$!: FdGetOsFHandle( $fd )"
71             if !defined $osfh || $osfh == C_ABI_INVALID_HANDLE_VALUE;
72              
73 0           SetHandleInformation( $osfh, HANDLE_FLAG_INHERIT, 0 );
74             }
75             }
76              
77             sub _inherit { #### REMOVE
78 0     0     for (@_) { #### REMOVE
79 0 0         next unless defined $_; #### REMOVE
80 0           my $fd = $_; #### REMOVE
81 0 0         $fd = fileno $fd if ref $fd; #### REMOVE
82 0 0         _debug "enabling inheritance of ", $fd if _debugging_details; #### REMOVE
83 0           my $osfh = FdGetOsFHandle $fd; #### REMOVE
84              
85             # Contrary to documentation, $! has the failure reason
86             # (https://github.com/chorny/Win32API-File/issues/14)
87 0 0 0       croak "$!: FdGetOsFHandle( $fd )"
88             if !defined $osfh || $osfh == C_ABI_INVALID_HANDLE_VALUE;
89             #### REMOVE
90 0           SetHandleInformation( $osfh, HANDLE_FLAG_INHERIT, 1 ); #### REMOVE
91             } #### REMOVE
92             } #### REMOVE
93             #### REMOVE
94             #sub _inherit {
95             # for ( @_ ) {
96             # next unless defined $_;
97             # my $osfh = GetOsFHandle $_;
98             # croak $^E if ! defined $osfh || $osfh == INVALID_HANDLE_VALUE;
99             # SetHandleInformation( $osfh, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT );
100             # }
101             #}
102              
103             =pod
104              
105             =head1 FUNCTIONS
106              
107             =over
108              
109             =item optimize()
110              
111             Most common incantations of C (I C, C,
112             or C) now use temporary files to redirect input and output
113             instead of pumper processes.
114              
115             Temporary files are used when sending to child processes if input is
116             taken from a scalar with no filter subroutines. This is the only time
117             we can assume that the parent is not interacting with the child's
118             redirected input as it runs.
119              
120             Temporary files are used when receiving from children when output is
121             to a scalar or subroutine with or without filters, but only if
122             the child in question closes its inputs or takes input from
123             unfiltered SCALARs or named files. Normally, a child inherits its STDIN
124             from its parent; to close it, use "0<&-" or the C<< noinherit => 1 >> option.
125             If data is sent to the child from CODE refs, filehandles or from
126             scalars through filters than the child's outputs will not be optimized
127             because C assumes the parent is interacting with the child.
128             It is ok if the output is filtered or handled by a subroutine, however.
129              
130             This assumes that all named files are real files (as opposed to named
131             pipes) and won't change; and that a process is not communicating with
132             the child indirectly (through means not visible to IPC::Run).
133             These can be an invalid assumptions, but are the 99% case.
134             Write me if you need an option to enable or disable optimizations; I
135             suspect it will work like the C modifier.
136              
137             To detect cases that you might want to optimize by closing inputs, try
138             setting the C environment variable to the special C
139             value:
140              
141             C:> set IPCRUNDEBUG=notopt
142             C:> my_app_that_uses_IPC_Run.pl
143              
144             =item optimizer() rationalizations
145              
146             Only for that limited case can we be sure that it's ok to batch all the
147             input in to a temporary file. If STDIN is from a SCALAR or from a named
148             file or filehandle (again, only in C), then outputs to CODE refs
149             are also assumed to be safe enough to batch through a temp file,
150             otherwise only outputs to SCALAR refs are batched. This can cause a bit
151             of grief if the parent process benefits from or relies on a bit of
152             "early returns" coming in before the child program exits. As long as
153             the output is redirected to a SCALAR ref, this will not be visible.
154             When output is redirected to a subroutine or (deprecated) filters, the
155             subroutine will not get any data until after the child process exits,
156             and it is likely to get bigger chunks of data at once.
157              
158             The reason for the optimization is that, without it, "pumper" processes
159             are used to overcome the inconsistencies of the Win32 API. We need to
160             use anonymous pipes to connect to the child processes' stdin, stdout,
161             and stderr, yet select() does not work on these. select() only works on
162             sockets on Win32. So for each redirected child handle, there is
163             normally a "pumper" process that connects to the parent using a
164             socket--so the parent can select() on that fd--and to the child on an
165             anonymous pipe--so the child can read/write a pipe.
166              
167             Using a socket to connect directly to the child (as at least one MSDN
168             article suggests) seems to cause the trailing output from most children
169             to be lost. I think this is because child processes rarely close their
170             stdout and stderr explicitly, and the winsock dll does not seem to flush
171             output when a process that uses it exits without explicitly closing
172             them.
173              
174             Because of these pumpers and the inherent slowness of Win32
175             CreateProcess(), child processes with redirects are quite slow to
176             launch; so this routine looks for the very common case of
177             reading/writing to/from scalar references in a run() routine and
178             converts such reads and writes in to temporary file reads and writes.
179              
180             Such files are marked as FILE_ATTRIBUTE_TEMPORARY to increase speed and
181             as FILE_FLAG_DELETE_ON_CLOSE so it will be cleaned up when the child
182             process exits (for input files). The user's default permissions are
183             used for both the temporary files and the directory that contains them,
184             hope your Win32 permissions are secure enough for you. Files are
185             created with the Win32API::File defaults of
186             FILE_SHARE_READ|FILE_SHARE_WRITE.
187              
188             Setting the debug level to "details" or "gory" will give detailed
189             information about the optimization process; setting it to "basic" or
190             higher will tell whether or not a given call is optimized. Setting
191             it to "notopt" will highlight those calls that aren't optimized.
192              
193             =cut
194              
195             sub optimize {
196 0     0 1   my ($h) = @_;
197              
198 0           my @kids = @{ $h->{KIDS} };
  0            
199              
200 0           my $saw_pipe;
201              
202 0           my ( $ok_to_optimize_outputs, $veto_output_optimization );
203              
204 0           for my $kid (@kids) {
205 0 0         ( $ok_to_optimize_outputs, $veto_output_optimization ) = ()
206             unless $saw_pipe;
207              
208 0 0 0       _debug "Win32 optimizer: (kid $kid->{NUM}) STDIN piped, carrying over ok of non-SCALAR output optimization"
209             if _debugging_details && $ok_to_optimize_outputs;
210 0 0 0       _debug "Win32 optimizer: (kid $kid->{NUM}) STDIN piped, carrying over veto of non-SCALAR output optimization"
211             if _debugging_details && $veto_output_optimization;
212              
213 0 0 0       if ( $h->{noinherit} && !$ok_to_optimize_outputs ) {
214 0 0 0       _debug "Win32 optimizer: (kid $kid->{NUM}) STDIN not inherited from parent oking non-SCALAR output optimization"
215             if _debugging_details && $ok_to_optimize_outputs;
216 0           $ok_to_optimize_outputs = 1;
217             }
218              
219 0           for ( @{ $kid->{OPS} } ) {
  0            
220 0 0 0       if ( substr( $_->{TYPE}, 0, 1 ) eq "<" ) {
    0 0        
    0          
    0          
221 0 0         if ( $_->{TYPE} eq "<" ) {
222 0 0 0       if ( @{ $_->{FILTERS} } > 1 ) {
  0 0 0        
    0 0        
223             ## Can't assume that the filters are idempotent.
224             }
225             elsif (ref $_->{SOURCE} eq "SCALAR"
226             || ref $_->{SOURCE} eq "GLOB"
227             || UNIVERSAL::isa( $_, "IO::Handle" ) ) {
228 0 0         if ( $_->{KFD} == 0 ) {
229             _debug
230             "Win32 optimizer: (kid $kid->{NUM}) 0$_->{TYPE}",
231             ref $_->{SOURCE},
232 0 0         ", ok to optimize outputs"
233             if _debugging_details;
234 0           $ok_to_optimize_outputs = 1;
235             }
236 0           $_->{SEND_THROUGH_TEMP_FILE} = 1;
237 0           next;
238             }
239             elsif ( !ref $_->{SOURCE} && defined $_->{SOURCE} ) {
240 0 0         if ( $_->{KFD} == 0 ) {
241 0 0         _debug
242             "Win32 optimizer: (kid $kid->{NUM}) 0<$_->{SOURCE}, ok to optimize outputs",
243             if _debugging_details;
244 0           $ok_to_optimize_outputs = 1;
245             }
246 0           next;
247             }
248             }
249             _debug
250             "Win32 optimizer: (kid $kid->{NUM}) ",
251             $_->{KFD},
252             $_->{TYPE},
253             defined $_->{SOURCE}
254             ? ref $_->{SOURCE}
255             ? ref $_->{SOURCE}
256             : $_->{SOURCE}
257             : defined $_->{FILENAME} ? $_->{FILENAME}
258             : "",
259 0 0 0       @{ $_->{FILTERS} } > 1 ? " with filters" : (),
  0 0          
    0          
    0          
    0          
260             ", VETOING output opt."
261             if _debugging_details || _debugging_not_optimized;
262 0           $veto_output_optimization = 1;
263             }
264             elsif ( $_->{TYPE} eq "close" && $_->{KFD} == 0 ) {
265 0           $ok_to_optimize_outputs = 1;
266 0 0         _debug "Win32 optimizer: (kid $kid->{NUM}) saw 0<&-, ok to optimize outputs"
267             if _debugging_details;
268             }
269             elsif ( $_->{TYPE} eq "dup" && $_->{KFD2} == 0 ) {
270 0           $veto_output_optimization = 1;
271 0 0 0       _debug "Win32 optimizer: (kid $kid->{NUM}) saw 0<&$_->{KFD2}, VETOING output opt."
272             if _debugging_details || _debugging_not_optimized;
273             }
274             elsif ( $_->{TYPE} eq "|" ) {
275 0           $saw_pipe = 1;
276             }
277             }
278              
279 0 0 0       if ( !$ok_to_optimize_outputs && !$veto_output_optimization ) {
280 0 0 0       _debug "Win32 optimizer: (kid $kid->{NUM}) child STDIN not redirected, VETOING non-SCALAR output opt."
281             if _debugging_details || _debugging_not_optimized;
282 0           $veto_output_optimization = 1;
283             }
284              
285 0 0 0       if ( $ok_to_optimize_outputs && $veto_output_optimization ) {
286 0           $ok_to_optimize_outputs = 0;
287 0 0 0       _debug "Win32 optimizer: (kid $kid->{NUM}) non-SCALAR output optimizations VETOed"
288             if _debugging_details || _debugging_not_optimized;
289             }
290              
291             ## SOURCE/DEST ARRAY means it's a filter.
292             ## TODO: think about checking to see if the final input/output of
293             ## a filter chain (an ARRAY SOURCE or DEST) is a scalar...but
294             ## we may be deprecating filters.
295              
296 0           for ( @{ $kid->{OPS} } ) {
  0            
297 0 0         if ( $_->{TYPE} eq ">" ) {
298 0 0 0       if (
      0        
      0        
      0        
299             ref $_->{DEST} eq "SCALAR"
300             || (
301             (
302             @{ $_->{FILTERS} } > 1
303             || ref $_->{DEST} eq "CODE"
304             || ref $_->{DEST} eq "ARRAY" ## Filters?
305             )
306             && ( $ok_to_optimize_outputs && !$veto_output_optimization )
307             )
308             ) {
309 0           $_->{RECV_THROUGH_TEMP_FILE} = 1;
310 0           next;
311             }
312             _debug
313             "Win32 optimizer: NOT optimizing (kid $kid->{NUM}) ",
314             $_->{KFD},
315             $_->{TYPE},
316             defined $_->{DEST}
317             ? ref $_->{DEST}
318             ? ref $_->{DEST}
319             : $_->{SOURCE}
320             : defined $_->{FILENAME} ? $_->{FILENAME}
321             : "",
322 0 0         @{ $_->{FILTERS} } ? " with filters" : (),
  0 0          
    0          
    0          
    0          
323             if _debugging_details;
324             }
325             }
326             }
327              
328             }
329              
330             =pod
331              
332             =item win32_parse_cmd_line
333              
334             @words = win32_parse_cmd_line( q{foo bar 'baz baz' "bat bat"} );
335              
336             returns 4 words. This parses like the bourne shell (see
337             the bit about shellwords() in L), assuming we're
338             trying to be a little cross-platform here. The only difference is
339             that "\" is *not* treated as an escape except when it precedes
340             punctuation, since it's used all over the place in DOS path specs.
341              
342             TODO: strip caret escapes?
343              
344             TODO: use
345             https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args#parsing-c-command-line-arguments
346              
347             TODO: globbing? probably not (it's unDOSish).
348              
349             TODO: shebang emulation? Probably, but perhaps that should be part
350             of Run.pm so all spawned processes get the benefit.
351              
352             LIMITATIONS: shellwords dies silently on malformed input like
353              
354             a\"
355              
356             =cut
357              
358             sub win32_parse_cmd_line {
359 0     0 1   my $line = shift;
360 0           $line =~ s{(\\[\w\s])}{\\$1}g;
361 0           return shellwords $line;
362             }
363              
364             =pod
365              
366             =item win32_spawn
367              
368             Spawns a child process, possibly with STDIN, STDOUT, and STDERR (file descriptors 0, 1, and 2, respectively) redirected.
369              
370             B.
371              
372             Cannot redirect higher file descriptors due to lack of support for this in the
373             Win32 environment.
374              
375             This can be worked around by marking a handle as inheritable in the
376             parent (or leaving it marked; this is the default in perl), obtaining it's
377             Win32 handle with C or
378             C and passing it to the child using the command
379             line, the environment, or any other IPC mechanism (it's a plain old integer).
380             The child can then use C or C and possibly
381             C<&BAR">> or C<&$fd>> as need be. Ach, the pain!
382              
383             =cut
384              
385             sub _save {
386 0     0     my ( $saved, $saved_as, $fd ) = @_;
387              
388             ## We can only save aside the original fds once.
389 0 0         return if exists $saved->{$fd};
390              
391 0           my $saved_fd = IPC::Run::_dup($fd);
392 0           _dont_inherit $saved_fd;
393              
394 0           $saved->{$fd} = $saved_fd;
395 0           $saved_as->{$saved_fd} = $fd;
396              
397 0           _dont_inherit $saved->{$fd};
398             }
399              
400             sub _dup2_gently {
401 0     0     my ( $saved, $saved_as, $fd1, $fd2 ) = @_;
402 0           _save $saved, $saved_as, $fd2;
403              
404 0 0         if ( exists $saved_as->{$fd2} ) {
405             ## The target fd is colliding with a saved-as fd, gotta bump
406             ## the saved-as fd to another fd.
407 0           my $orig_fd = delete $saved_as->{$fd2};
408 0           my $saved_fd = IPC::Run::_dup($fd2);
409 0           _dont_inherit $saved_fd;
410              
411 0           $saved->{$orig_fd} = $saved_fd;
412 0           $saved_as->{$saved_fd} = $orig_fd;
413             }
414 0 0         _debug "moving $fd1 to kid's $fd2" if _debugging_details;
415 0           IPC::Run::_dup2_rudely( $fd1, $fd2 );
416             }
417              
418             sub win32_spawn {
419 0     0 1   my ( $cmd, $ops ) = @_;
420              
421 0           my ( $app, $cmd_line );
422 0           my $need_pct = 0;
423 0 0         if ( UNIVERSAL::isa( $cmd, 'IPC::Run::Win32Process' ) ) {
    0          
424 0           $app = $cmd->{lpApplicationName};
425 0           $cmd_line = $cmd->{lpCommandLine};
426             }
427             elsif ( $cmd->[0] !~ /\.(bat|cmd) *$/i ) {
428 0           $app = $cmd->[0];
429 0           $cmd_line = Win32::ShellQuote::quote_native(@$cmd);
430             }
431             else {
432             # Batch file, so follow the batch-specific guidance of
433             # https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
434             # There's no one true way to locate cmd.exe. In the unlikely event that
435             # %COMSPEC% is missing, fall back on a Windows API. We could search
436             # %PATH% like _wsystem() does. That would be prone to security bugs,
437             # and one fallback is enough.
438             $app = (
439             $ENV{COMSPEC}
440 0   0       || File::Spec->catfile(
441             Win32::GetFolderPath(Win32::CSIDL_SYSTEM),
442             'cmd.exe'
443             )
444             );
445              
446             # Win32 rejects attempts to create files with names containing certain
447             # characters. Ignore most, but reject the subset that might otherwise
448             # cause us to execute the wrong file instead of failing cleanly.
449 0 0         if ( $cmd->[0] =~ /["\r\n\0]/ ) {
450 0           croak "invalid batch file name";
451             }
452              
453             # Make cmd.exe see the batch file name as quoted. Suppose we instead
454             # used caret escapes, as we do for arguments. cmd.exe could then "break
455             # the command token at the first occurrence of , ; or ="
456             # (https://stackoverflow.com/a/4095133).
457 0           my @parts = qq{"$cmd->[0]"};
458              
459             # cmd.exe will strip escapes once when parsing our $cmd_line and again
460             # where the batch file injects the argument via %*, %1, etc. Compensate
461             # by adding one extra cmd_escape layer.
462 0 0         if ( @$cmd > 1 ) {
463 0           my @q = Win32::ShellQuote::quote_cmd( @{$cmd}[ 1 .. $#{$cmd} ] );
  0            
  0            
464 0           push @parts, map { Win32::ShellQuote::cmd_escape($_) } @q;
  0            
465             }
466              
467             # One can't stop cmd.exe from expanding %var%, so inject each literal %
468             # via an environment variable. Delete that variable before the real
469             # child can see it. See
470             # https://www.dostips.com/forum/viewtopic.php?f=3&t=10131 for more on
471             # this technique and the limitations of alternatives.
472 0           $cmd_line = join ' ', @parts;
473 0 0         if ( $cmd_line =~ s/%/%ipcrunpct%/g ) {
474 0           $cmd_line = qq{/c "set "ipcrunpct=" & $cmd_line"};
475 0           $need_pct = 1;
476             }
477             else {
478 0           $cmd_line = qq{/c "$cmd_line"};
479             }
480             }
481 0 0         _debug "app: ", $app
482             if _debugging;
483 0 0         _debug "cmd line: ", $cmd_line
484             if _debugging;
485              
486             ## NOTE: The debug pipe write handle is passed to pump processes as STDOUT.
487             ## and is not to the "real" child process, since they would not know
488             ## what to do with it...unlike Unix, we have no code executing in the
489             ## child before the "real" child is exec()ed.
490              
491 0           my %saved; ## Map of parent's orig fd -> saved fd
492             my %saved_as; ## Map of parent's saved fd -> orig fd, used to
493             ## detect collisions between a KFD and the fd a
494             ## parent's fd happened to be saved to.
495              
496 0           for my $op (@$ops) {
497 0 0         _dont_inherit $op->{FD} if defined $op->{FD};
498              
499 0 0 0       if ( defined $op->{KFD} && $op->{KFD} > 2 ) {
500             ## TODO: Detect this in harness()
501             ## TODO: enable temporary redirections if ever necessary, not
502             ## sure why they would be...
503             ## 4>&1 1>/dev/null 1>&4 4>&-
504 0           croak "Can't redirect fd #", $op->{KFD}, " on Win32";
505             }
506              
507             ## This is very similar logic to IPC::Run::_do_kid_and_exit().
508 0 0         if ( defined $op->{TFD} ) {
    0          
    0          
    0          
509 0 0         unless ( $op->{TFD} == $op->{KFD} ) {
510 0           _dup2_gently \%saved, \%saved_as, $op->{TFD}, $op->{KFD};
511 0           _dont_inherit $op->{TFD};
512             }
513             }
514             elsif ( $op->{TYPE} eq "dup" ) {
515             _dup2_gently \%saved, \%saved_as, $op->{KFD1}, $op->{KFD2}
516 0 0         unless $op->{KFD1} == $op->{KFD2};
517             }
518             elsif ( $op->{TYPE} eq "close" ) {
519 0           _save \%saved, \%saved_as, $op->{KFD};
520 0           IPC::Run::_close( $op->{KFD} );
521             }
522             elsif ( $op->{TYPE} eq "init" ) {
523             ## TODO: detect this in harness()
524 0           croak "init subs not allowed on Win32";
525             }
526             }
527              
528 0 0         local $ENV{ipcrunpct} = '%' if $need_pct;
529 0           my $process;
530             Win32::Process::Create(
531             $process,
532             $app,
533             $cmd_line,
534             1, ## Inherit handles
535             0, ## Inherit parent priority class. Was NORMAL_PRIORITY_CLASS
536             ".",
537             )
538 0 0         or do {
539 0           my $err = Win32::FormatMessage( Win32::GetLastError() );
540 0           $err =~ s/\r?\n$//s;
541 0           croak "$err: Win32::Process::Create()";
542             };
543              
544 0           for my $orig_fd ( keys %saved ) {
545 0           IPC::Run::_dup2_rudely( $saved{$orig_fd}, $orig_fd );
546 0           IPC::Run::_close( $saved{$orig_fd} );
547             }
548              
549 0           return ( $process->GetProcessID(), $process );
550             }
551              
552             1;
553              
554             =pod
555              
556             =back
557              
558             =head1 AUTHOR
559              
560             Barries Slaymaker . Funded by Perforce Software, Inc.
561              
562             =head1 COPYRIGHT
563              
564             Copyright 2001, Barrie Slaymaker, All Rights Reserved.
565              
566             You may use this under the terms of either the GPL 2.0 or the Artistic License.
567              
568             =cut