File Coverage

blib/lib/Argv.pm
Criterion Covered Total %
statement 399 861 46.3
branch 175 534 32.7
condition 50 157 31.8
subroutine 42 66 63.6
pod 15 28 53.5
total 681 1646 41.3


line stmt bran cond sub pod time code
1             package Argv;
2              
3             $VERSION = '1.28';
4             @ISA = qw(Exporter);
5              
6 1 50   1   1382 use constant MSWIN => $^O =~ /MSWin|Windows_NT/i ? 1 : 0;
  1         2  
  1         131  
7 1 50   1   87 use constant CYGWIN => $^O =~ /cygwin/i ? 1 : 0;
  1         3  
  1         245  
8              
9             # To support the "FUNCTIONAL INTERFACE"
10             @EXPORT_OK = qw(system exec qv pipe MSWIN CYGWIN);
11              
12 1     1   6 use strict;
  1         6  
  1         46  
13 1     1   5 use Carp;
  1         2  
  1         167  
14             require Exporter;
15              
16             my $class = __PACKAGE__;
17              
18             my $NUL = MSWIN ? 'NUL' : '/dev/null';
19              
20             # Adapted from perltootc (see): an "eponymous meta-object" implementing
21             # "translucent attributes".
22             # For each key in the hash below, a method is automatically generated.
23             # Each method sets the object attr if called as an instance method or
24             # the class attr if called as a class method. They return the instance
25             # attr if it's defined, the class attr otherwise. The method name is
26             # lower-case; e.g. 'qxargs'. The default value of each attribute comes
27             # from the hash value set here, which may be overridden in the environment.
28 1     1   7 use vars qw(%Argv);
  1         1  
  1         440  
29             %Argv = (
30             AUTOCHOMP => $ENV{ARGV_AUTOCHOMP} || 0,
31             AUTOFAIL => $ENV{ARGV_AUTOFAIL} || 0,
32             AUTOGLOB => $ENV{ARGV_AUTOGLOB} || 0,
33             AUTOQUOTE => defined($ENV{ARGV_AUTOQUOTE}) ? $ENV{ARGV_AUTOQUOTE} : 1,
34             DBGLEVEL => $ENV{ARGV_DBGLEVEL} || 0,
35             DFLTSETS => {'' => 1},
36             ENVP => undef,
37             EXECWAIT => defined($ENV{ARGV_EXECWAIT}) ?
38             $ENV{ARGV_EXECWAIT} : scalar(MSWIN),
39             INPATHNORM => $ENV{ARGV_INPATHNORM} || 0,
40             MUSTEXEC => $ENV{ARGV_MUSTEXEC} || 0,
41             NOEXEC => $ENV{ARGV_NOEXEC} || 0,
42             OUTPATHNORM => $ENV{ARGV_OUTPATHNORM} || 0,
43             QXARGS => $ENV{ARGV_QXARGS} || -1,
44             QXFAIL => $ENV{ARGV_QXFAIL} || 0,
45             QUIET => defined($ENV{ARGV_QUIET}) ? $ENV{ARGV_QUIET} : 0,
46             STDIN => defined($ENV{ARGV_STDIN}) ? $ENV{ARGV_STDIN} : 0,
47             STDOUT => defined($ENV{ARGV_STDOUT}) ? $ENV{ARGV_STDOUT} : 1,
48             STDERR => defined($ENV{ARGV_STDERR}) ? $ENV{ARGV_STDERR} : 2,
49             SYFAIL => $ENV{ARGV_SYFAIL} || 0,
50             SYXARGS => $ENV{ARGV_SYXARGS} || 0,
51             PIPECB => sub { print shift; return 1 },
52             );
53              
54             # Generates execution-attribute methods from the table above. Provided
55             # as a class method itself to potentially allow a derived class to
56             # generate more of these. Semantics of these methods are quite
57             # context-driven and are explained in the PODs.
58             sub gen_exec_method {
59 1     1 0 2 my $meta = shift;
60 1     1   6 no strict 'refs'; # must evaluate $meta as a symbolic ref
  1         2  
  1         902  
61 1 50       4 my @data = @_ ? map {uc} @_ : keys %{$meta};
  0         0  
  1         10  
62 1         4 for my $attr (@data) {
63 21   100     85 $$meta{$attr} ||= 0;
64 21         2751 my $method = lc $attr;
65             *$method = sub {
66 141     141   2127 my $self = shift;
67             # In null context with no args, set boolean value 'on'.
68 141 50 66     1058 @_ = (1) if !@_ && !defined(wantarray);
69 141         226 my $ret = 0;
70 141 100       384 if (ref $self) {
71 139 100       235 if (@_) {
72 9 100       27 if (defined(wantarray)) {
73 4 50       27 if (ref $self->{$attr}) {
    50          
74 0         0 unshift(@{$self->{$attr}}, shift);
  0         0  
75             } elsif (defined $self->{$attr}) {
76 0         0 $self->{$attr} = [shift, $self->{$attr}];
77             } else {
78 4         73 $self->{$attr} = [shift];
79             }
80 4         43 return $self;
81             } else {
82 5         20 $self->{$attr} = shift;
83 5         14 return undef;
84             }
85             } else {
86 130 100       976 $ret = defined($self->{$attr}) ?
87             $self->{$attr} : $class->{$attr};
88             }
89             } else {
90 2 50       681 if (@_) {
91 2 50       495 if (defined(wantarray)) {
92 0 0       0 if (ref $class->{$attr}) {
93 0         0 unshift(@{$class->{$attr}}, shift);
  0         0  
94             } else {
95 0         0 $class->{$attr} = [shift, $class->{$attr}];
96             }
97             } else {
98 2         59 $class->{$attr} = shift;
99             }
100             # If setting a class attribute, export it to the
101             # env in case we fork a child also using Argv.
102 2         45 my $ev = uc join('_', $class, $attr);
103 2         54 $ENV{$ev} = $class->{$attr};
104 2         16 return $self;
105             } else {
106 0         0 $ret = $class->{$attr};
107             }
108             }
109 130 100 100     483 if (ref($ret) eq 'ARRAY' && ref($ret->[0]) ne 'CODE') {
110 4         14 my $stack = $ret;
111 4         6 $ret = shift @$stack;
112 4 50       15 if (ref $self) {
113 4 50       12 if (@$stack) {
114 0         0 $self->{$attr} = shift @$stack;
115             } else {
116 4         15 delete $self->{$attr};
117             }
118             } else {
119 0         0 $self->{$attr} = shift @$stack;
120             }
121             }
122 130         3195 return $ret;
123             }
124 21         167 }
125             }
126              
127             # Generate all the attribute methods declared in %Argv above.
128             $class->gen_exec_method;
129              
130             # Generate methods for diverting stdin, stdout, and stderr in ->qx.
131             {
132             my %streams = (stdin => 1, stdout => 1, stderr => 2);
133             for my $name (keys %streams) {
134             my $method = "_qx_$name";
135 1     1   7 no strict 'refs';
  1         2  
  1         765  
136             *$method = sub {
137 2     2   5 my $self = shift;
138 2         3 my $r_cmd = shift;
139 2         3 my $nfd = shift;
140 2         4 my $fd = $streams{$name};
141 2 50       30 if ($nfd !~ m%^[\d-]*$%) {
    50          
    50          
    50          
    50          
142 0         0 push(@$r_cmd, "$fd$nfd");
143             } elsif ($fd == 0) {
144 0 0       0 warn "Error: illegal value '$nfd' for $name" if $nfd > 0;
145 0 0       0 push(@$r_cmd, "<$NUL") if $nfd < 0;
146             } elsif ($nfd == 0) {
147 0         0 push(@$r_cmd, "$fd>$NUL");
148             } elsif ($nfd == (3-$fd)) {
149 0         0 push(@$r_cmd, sprintf "%d>&%d", $fd, 3-$fd);
150             } elsif ($nfd != $fd) {
151 0         0 warn "Error: illegal value '$nfd' for $name";
152             }
153             };
154             }
155             }
156              
157             # Getopt::Long::GetOptions() respects '--' but strips it, while
158             # we want to respect '--' and leave it in. Thus this override.
159             sub GetOptions {
160 5 50   5 0 16 @ARGV = map {/^--$/ ? qw(=--= --) : $_} @ARGV;
  21         218  
161 5         36 my $ret = Getopt::Long::GetOptions(@_);
162 5 50       3147 @ARGV = map {/^=--=$/ ? qw(--) : $_} @ARGV;
  11         70  
163 5         17 return $ret;
164             }
165              
166             # This method is much like the generated exec methods but has some
167             # special-case logic: If called with a param which is true, it starts up
168             # a coprocess. If called with false (aka 0) it shuts down the coprocess
169             # and destroys the IPC::ChildSafe object. If called with no params at
170             # all it returns the existing IPC::ChildSafe object.
171             sub ipc_childsafe {
172 0     0 0 0 my $self = shift;
173 0         0 my $ipc_state = $_[0];
174 0         0 my $ipc_obj;
175 0 0       0 if ($ipc_state) {
176 0         0 eval { require IPC::ChildSafe };
  0         0  
177 0 0       0 return undef if $@;
178 0         0 IPC::ChildSafe->VERSION(3.10);
179 0         0 $ipc_obj = IPC::ChildSafe->new(@_);
180             }
181 1     1   7 no strict 'refs';
  1         1  
  1         1277  
182 0 0       0 if (ref $self) {
183 0 0       0 if (defined $ipc_state) {
184 0         0 $self->{_IPC_CHILDSAFE} = $ipc_obj;
185 0         0 return $self;
186             } else {
187 0 0       0 return exists($self->{_IPC_CHILDSAFE}) ?
188             $self->{_IPC_CHILDSAFE} : $class->{_IPC_CHILDSAFE};
189             }
190             } else {
191 0 0       0 if (defined $ipc_state) {
192 0         0 $class->{_IPC_CHILDSAFE} = $ipc_obj;
193 0         0 return $self;
194             } else {
195 0         0 return $class->{_IPC_CHILDSAFE};
196             }
197             }
198             }
199              
200             # Class/instance method. Parses command line for e.g. -/dbg=1. See PODs.
201             sub attropts {
202 0     0 1 0 my $self = shift;
203 0         0 my $r_argv = undef;
204 0         0 my $prefix = '-/';
205 0 0       0 if (ref $_[0] eq 'HASH') {
206 0         0 my $cfg = shift;
207 0         0 $r_argv = $cfg->{ARGV};
208 0         0 $prefix = $cfg->{PREFIX};
209             }
210 0         0 require Getopt::Long;
211 0         0 local $Getopt::Long::passthrough = 1;
212 0         0 local $Getopt::Long::genprefix = "($prefix)";
213 0         0 my @flags = map {"$_=i"} ((map lc, keys %Argv::Argv), @_);
  0         0  
214 0         0 my %opt;
215 0 0       0 if (ref $self) {
    0          
    0          
216 0 0       0 if ($r_argv) {
217 0         0 local @ARGV = @$r_argv;
218 0         0 GetOptions(\%opt, @flags);
219 0         0 @$r_argv = @ARGV;
220             } else {
221 0         0 local @ARGV = $self->args;
222 0 0       0 if (@ARGV) {
223 0         0 GetOptions(\%opt, @flags);
224 0         0 $self->args(@ARGV);
225             }
226             }
227             } elsif ($r_argv) {
228 0         0 local @ARGV = @$r_argv;
229 0         0 GetOptions(\%opt, @flags);
230 0         0 @$r_argv = @ARGV;
231             } elsif (@ARGV) {
232 0         0 GetOptions(\%opt, @flags);
233             }
234 0         0 for my $method (keys %opt) {
235 0         0 $self->$method($opt{$method});
236             }
237 0         0 return $self;
238             }
239             *stdopts = \&attropts; # backward compatibility
240              
241             # A class method which returns a summary of operations performed in
242             # printable format. Called with a void context to start data-
243             # collection, with a scalar context to end it and get the report.
244             sub summary {
245 0     0 0 0 my $cls = shift;
246 0         0 my($cmds, $operands);
247 0 0       0 if (!defined wantarray) {
248 0         0 $Argv::Summary = {};
249 0         0 return;
250             }
251 0 0       0 return unless $Argv::Summary;
252 0         0 my $fmt = "%30s: %4s\t%s\n";
253 0         0 my $str = sprintf $fmt, "$cls Summary", 'Cmds', 'Operands';
254 0         0 for (sort keys %{$Argv::Summary}) {
  0         0  
255 0         0 my @stats = @{$Argv::Summary->{$_}};
  0         0  
256 0         0 $cmds += $stats[0];
257 0         0 $operands += $stats[1];
258 0         0 $str .= sprintf $fmt, $_, $stats[0], $stats[1];
259             }
260 0 0       0 $str .= sprintf $fmt, 'TOTAL', $cmds, $operands if defined $cmds;
261 0         0 $Argv::Summary = 0;
262 0         0 return $str;
263             }
264              
265             # Constructor.
266             sub new {
267 8     8 0 586 my $proto = shift;
268 8 50       185 my $attrs = shift if ref($_[0]) eq 'HASH';
269 8         13 my $self;
270 8 100       56 if (ref($proto)) {
271             # As an instance method, make a deep clone of the invoking object.
272             # Some cloners are fast but not commonly installed, others the
273             # reverse. We try them in order of speed and fall back to
274             # Data::Dumper which is slow but core Perl as of 5.6.0. I could
275             # just inherit from Clone or Storable but want to not force
276             # users who don't need cloning to install them.
277 1         12 eval {
278 1         435 require Clone;
279 0         0 Clone->VERSION(0.12); # 0.11 has a bug that breaks Argv
280 0         0 $self = Clone::clone($proto);
281             };
282 1 50       25 if ($@) {
283 1         64 eval {
284 1         1333 require Storable;
285 1         4134 $self = Storable::dclone($proto);
286             };
287             }
288 1 50       4 if ($@) {
289 1         1492 require Data::Dumper;
290             # Older Perl versions may not have the XS interface installed,
291             # so try it and fall back to the pure-perl version on failure.
292 1         6462 my $copy = eval {
293 1         7 Data::Dumper->Deepcopy(1)->new([$proto], ['self'])->Dumpxs;
294             };
295 1 50       162 $copy = Data::Dumper->Deepcopy(1)->new([$proto], ['self'])->Dump
296             if $@;
297 1         123 eval $copy;
298             }
299 1 50 33     9 die $@ if $@ || !$self;
300             # At least some cloners can't clone a code ref...
301 1         6 $self->{PIPECB} = $proto->{PIPECB};
302             } else {
303 7         39 $self = {};
304 7 50       31 if ($proto ne __PACKAGE__) {
305             # Inherit class attributes from subclass class attributes.
306 1     1   7 no strict 'refs';
  1         1  
  1         813  
307 0         0 for (keys %$proto) {
308 0         0 $self->{$_} = $proto->{$_};
309             }
310             }
311 7         41 $self->{AV_PROG} = [];
312 7         35 $self->{AV_ARGS} = [];
313 7         40 $self->{PIPECB} = $Argv{PIPECB};
314 7         44 bless $self, $proto;
315 7         103 $self->optset('');
316             }
317 8 50       33 $self->attrs($attrs) if $attrs;
318 8 100       78 $self->argv(@_) if @_;
319 8         49 return $self;
320             }
321             *clone = \&new;
322              
323             # Nothing to do here, just avoiding interaction with AUTOLOAD.
324 0     0   0 sub DESTROY { }
325              
326             sub AUTOLOAD {
327 0     0   0 my $self = shift;
328 0         0 (my $cmd = $Argv::AUTOLOAD) =~ s/.*:://;
329 0 0       0 return if $cmd eq 'DESTROY';
330 1     1   8 no strict 'refs';
  1         2  
  1         1034  
331             # install a new method '$cmd' to avoid autoload next time ...
332             *$cmd = sub {
333 0     0   0 my $self = shift;
334 0 0       0 if (ref $self) {
335 0         0 $self->argv($cmd, @_);
336             } else {
337 0         0 $self->new($cmd, @_);
338             }
339 0         0 };
340             # ... then service this request
341 0         0 return $self->$cmd(@_);
342             }
343              
344             # Instance methods; most class methods are auto-generated above.
345              
346             # A shorthand way to set a bunch of attributes by passing a hashref
347             # of their names=>values.
348             sub attrs {
349 0     0 0 0 my $self = shift;
350 0         0 my $attrs = shift;
351 0 0       0 if ($attrs) {
352 0         0 for my $key (keys %$attrs) {
353 0         0 (my $method = $key) =~ s/^-//;
354 0         0 $self->$method($attrs->{$key});
355             }
356             }
357 0         0 return $self;
358             }
359              
360             # Replace the instance's prog(), opt(), and args() vectors all together.
361             # Without arguments, return the command as it currently looks either as
362             # a list or a string depending on context.
363             sub argv {
364 8     8 1 16 my $self = shift;
365 8 50       46 if (@_) {
366 8 50       29 $self->attrs(shift) if ref($_[0]) eq 'HASH';
367 8         24 $self->{AV_PROG} = [];
368 8         22 $self->{AV_OPTS}{''} = [];
369 8         23 $self->{AV_ARGS} = [];
370 8 50       48 $self->prog(shift) if @_;
371 8 50       28 $self->attrs(shift) if ref($_[0]) eq 'HASH';
372 8 100       30 $self->opts(@{shift @_}) if ref $_[0] eq 'ARRAY';
  2         21  
373 8 100       44 $self->args(@_) if @_;
374 8         14 return $self;
375             } else {
376 0         0 my @cmd = ($self->prog, $self->opts, $self->args);
377 0 0       0 if (wantarray) {
378 0         0 return @cmd;
379             } else {
380 0         0 return "@cmd";
381             }
382             }
383             }
384             *cmd = \&argv; # backward compatibility
385              
386             # Set or get the 'prog' part of the command line.
387             sub prog {
388 10     10 1 36 my $self = shift;
389 10 100       39 if (@_) {
    50          
390 9 50       53 my @prg = ref $_[0] ? @{$_[0]} : @_;
  0         0  
391 9         18 @{$self->{AV_PROG}} = @prg;
  9         31  
392             } elsif (!defined(wantarray)) {
393 0         0 @{$self->{AV_PROG}} = ();
  0         0  
394             }
395 10 100       30 if (@_) {
396 9         23 return $self;
397             } else {
398 1 50       11 return wantarray ? @{$self->{AV_PROG}} : ${$self->{AV_PROG}}[0];
  1         18  
  0         0  
399             }
400             }
401              
402             # Set or get the 'args' part of the command line.
403             sub args {
404 8     8 1 19 my $self = shift;
405 8 100       418 if (@_) {
    50          
406 6 50       87 my @args = ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_;
  0         0  
407 6         12 @{$self->{AV_ARGS}} = @args;
  6         634  
408             } elsif (!defined(wantarray)) {
409 0         0 @{$self->{AV_ARGS}} = ();
  0         0  
410             }
411 8 100       21 if (@_) {
412 6         128 return $self;
413             } else {
414 2         5 return @{$self->{AV_ARGS}};
  2         79  
415             }
416             }
417              
418             # Generates the parse(), opts(), and flag() method families. During
419             # construction this is used to generate the methods for the anonymous
420             # option set; it can be used explicitly to generate parseXX(), optsXX(),
421             # and argsXX() for optset 'XX'.
422             sub optset {
423 10     10 1 24 my $self = shift;
424 10         53 for (@_) {
425 11         76 my $set = uc $_;
426 11 50       663 next if defined $self->{AV_OPTS}{$set};
427 11         65 $self->{AV_OPTS}{$set} = [];
428 11         92 $self->{AV_LKG}{$set} = {};
429 11         53 my($p_meth, $o_meth, $f_meth) = map { $_ . $set } qw(parse opts flag);
  33         151  
430 11         53 $self->{AV_DESC}{$set} = [];
431 1     1   6 no strict 'refs'; # needed to muck with symbol table
  1         2  
  1         3816  
432             *$p_meth = sub {
433 5     5   42 my $self = shift;
434 5   50     27 $self->{AV_DESC}{$set} ||= [];
435 5 50       18 if (@_) {
436 5 50       28 if (ref($_[0]) eq 'ARRAY') {
    50          
437 0         0 $self->{CFG}{$set} = shift;
438             } elsif (ref($_[0]) eq 'HASH') {
439 0         0 $self->warning("do not provide a linkage specifier");
440 0         0 shift;
441             }
442 5         8 @{$self->{AV_DESC}{$set}} = @_;
  5         28  
443 5         66 $self->factor($set,
444             $self->{AV_DESC}{$set}, $self->{AV_OPTS}{$set},
445             $self->{AV_ARGS}, $self->{CFG}{$set});
446 5 50       27 if (defined $self->{AV_OPTS}{$set}) {
447 5         9 my @parsedout = @{$self->{AV_OPTS}{$set}};
  5         24  
448             }
449             }
450 5         10 return @{$self->{AV_OPTS}{$set}};
  5         23  
451 11 100       188 } unless $Argv::{$p_meth};
452             *$o_meth = sub {
453 6     6   48 my $self = shift;
454 6   50     44 $self->{AV_OPTS}{$set} ||= [];
455 6 100 66     93 if (@_ || !defined(wantarray)) {
456 2         4 @{$self->{AV_OPTS}{$set}} = @_;
  2         6  
457             }
458 6 100       34 return @_ ? $self : @{$self->{AV_OPTS}{$set}};
  4         98  
459 11 100       90 } unless $Argv::{$o_meth};
460             *$f_meth = sub {
461 0     0   0 my $self = shift;
462 0 0       0 if (@_ > 1) {
463 0         0 while(my($key, $val) = splice(@_, 0, 2)) {
464 0         0 $self->{AV_LKG}{$set}{$key} = $val;
465             }
466             } else {
467 0         0 my $key = shift;
468 0         0 return $self->{AV_LKG}{$set}{$key};
469             }
470 11 100       139 } unless $Argv::{$f_meth};
471             }
472 10         18 return keys %{$self->{AV_DESC}}; # this is the set of known optsets.
  10         72  
473             }
474              
475             # Not generally used except internally; not documented. First arg
476             # is an option set name followed by bunch of array-refs: a pointer
477             # to a list of Getopt::Long-style option descs, a ref to be filled
478             # in with a list of found options, another containing the input
479             # args and to be filled in with the leftovers, and an optional
480             # one containing Getopt::Long-style config options.
481             sub factor {
482 5     5 0 11 my $self = shift;
483 5         28 my($pset, $r_desc, $r_opts, $r_args, $r_cfg) = @_;
484 5         12 my @vgra;
485             {
486 5         8 local @ARGV = @$r_args;
  5         31  
487 5 50 33     433 if ($r_desc && @$r_desc) {
488 5         4533 require Getopt::Long;
489             # Need this version so Configure() returns prev state.
490 5         35317 Getopt::Long->VERSION(2.23);
491 5 50 33     244 if ($r_cfg && @$r_cfg) {
492 0         0 my $prev = Getopt::Long::Configure(@$r_cfg);
493 0         0 GetOptions($self->{AV_LKG}{$pset}, @$r_desc);
494 0         0 Getopt::Long::Configure($prev);
495             } else {
496 5         27 local $Getopt::Long::passthrough = 1;
497 5         22 local $Getopt::Long::autoabbrev = 1;
498 5 50       34 local $Getopt::Long::debug = 1 if $self->dbglevel == 5;
499 5         39 GetOptions($self->{AV_LKG}{$pset}, @$r_desc);
500             }
501             }
502 5         27 @vgra = @ARGV;
503             }
504 5         9 my(@opts, @args);
505 5         15 for (reverse @$r_args) {
506 21 100 100     110 if (@vgra && $vgra[$#vgra] eq $_) {
507 11         36 unshift(@args, pop (@vgra));
508             } else {
509 10         28 unshift(@opts, $_);
510             }
511             }
512 5 50       26 @$r_opts = @opts if $r_opts;
513 5         16 @$r_args = @args;
514 5         18 return @opts;
515             }
516              
517             # Extract and return any of the specified options from object.
518             sub extract {
519 0     0 1 0 my $self = shift;
520 0         0 my $set = shift;
521 0 0       0 $self->optset($set) unless defined $self->{AV_LKG}{$set};
522 0         0 my $p_meth = 'parse' . $set;
523 0         0 my $o_meth = 'opts' . $set;
524 0         0 $self->$p_meth(@_);
525 0         0 my @extracts = $self->$o_meth();
526 0         0 return @extracts;
527             }
528              
529             sub argpathnorm {
530 10     10 0 150 my $self = shift;
531 10         41 my $norm = $self->inpathnorm;
532 10 50 33     38 return unless $norm && !ref($norm);
533 0         0 if (CYGWIN) { #for the cygwin shell
534             s%\\%\\\\%g for @_;
535             }
536 0         0 return unless MSWIN;
537 0         0 for my $word (@_) {
538             # If requested, change / for \ in Windows file paths.
539             # This is necessarily an inexact science.
540 0         0 my @fragments = split ' ', $word;
541 0         0 for (@fragments) {
542 0 0       0 if (m%^"?/%) {
543 0 0       0 if (m%(.*/\w+):(.+)%) {
544             # If it looks like an option specifying a path (/opt:path),
545             # normalize only the path part.
546 0         0 my($opt, $path) = ($1, $2);
547 0         0 $path =~ s%/%\\%g;
548 0         0 $_ = "$opt:$path";
549             } else {
550             # If it contains a slash (any kind) after the initial one
551             # treat it as a full path. This is where you get into
552             # ambiguity with combined options (e.g. /E/I/Q/S) which
553             # could technically be a path. So that's just not allowed
554             # when path-norming.
555 0         0 my $slashes = tr/\/\\//;
556 0 0       0 s%/%\\%g if $slashes > 1;
557             }
558             } else {
559 0         0 s%/%\\%g;
560             }
561             }
562 0         0 $word = "@fragments";
563             }
564             }
565              
566             # Quotes @_ in place against shell expansion. Usually called via autoquote attr
567             sub quote {
568 1     1 1 2 my $self = shift;
569 1         10 for (grep {defined} @_) {
  2         9  
570             # Hack - allow user to exempt any arg from quoting by prefixing '^'.
571 2 50       10 next if s%^\^%%;
572             # Special case - turn internal newlines back to literal \n on Win32
573 2         4 s%\n%\\n%gs if MSWIN;
574             # If arg is already quoted with '': on Unix it's safe, leave alone.
575             # On Windows, replace the single quotes with escaped double quotes.
576 2 50       17 if (m%^'(.*)'$%s) {
    50          
577 0         0 $_ = qq(\\"$1\\") if MSWIN;
578 0         0 next;
579             } elsif (m%^".*"$%s) {
580 0         0 $_ = qq(\\"$_\\") if MSWIN || CYGWIN;
581 0         0 next;
582             }
583             # Skip if contains no special chars.
584 2         3 if (MSWIN) {
585             # On windows globbing is not handled by the shell so we
586             # let '*' go by.
587             next unless m%[^-=:_."\w\\/*]% || tr%\n%%;
588             } else {
589 2 50 33     58 next unless m%[^-=:_."\w\\/]% || m%\\n% || tr%\n%%;
      33        
590             }
591             # Special case - leave things that look like redirections alone.
592 0 0       0 next if /^\d?(?:<{1,2})|(?:>{1,2})/;
593             # This is a hack to support MKS-built perl 5.004. Don't know
594             # if the problem is with MKS builds or 5.004 per se.
595 0         0 next if MSWIN && $] < 5.005;
596             # Now quote embedded quotes ...
597 0         0 $_ =~ s%(\\*)"%$1$1\\"%g;
598             # quote a trailing \ so it won't quote the quote (!) ...
599 0         0 s%\\{1}$%\\\\%;
600             # and last the entire string.
601 0         0 $_ = qq("$_");
602             }
603 1         4 return $self;
604             }
605              
606             # Submits @_ to Perl's glob() function. Usually invoked via autoglob attr.
607             sub glob {
608 1     1 1 13 my $self = shift;
609 1 50       35 my @orig = @_ ? @_ : $self->args;
610 1 50       5 if (! @orig) {
611 0         0 $self->warning("no arguments to glob");
612 0         0 return 0;
613             }
614 1         5 my @globbed;
615 1         3 for (@orig) {
616 1 50       62 if (/^'(.*)'$/) { # allow '' to escape globbing
    50          
617 0         0 push(@globbed, $1);
618             } elsif (/[*?]/) {
619 1         4950 push(@globbed, glob)
620             } else {
621 0         0 push(@globbed, $_)
622             }
623             }
624 1 50       9 if (defined wantarray) {
625 0         0 return @globbed;
626             } else {
627 1         10 $self->args(@globbed);
628             }
629             }
630              
631             # Internal. Takes a list of optset names, returns a list of options.
632             sub _sets2opts {
633 11     11   17 my $self = shift;
634 11         16 my(@sets, @opts);
635 11 100       48 if (! @_) {
    100          
    50          
636 8         12 @sets = keys %{$self->dfltsets};
  8         47  
637             } elsif ($_[0] eq '-') {
638 2         6 @sets = ();
639             } elsif ($_[0] eq '+') {
640 0         0 @sets = $self->optset;
641             } else {
642 1         4 my %known = map {$_ => 1} $self->optset;
  1         11  
643 1 50       3 for (@_) { $self->warning("Unknown optset '$_'\n") if !$known{$_} }
  1         8  
644 1         5 @sets = @_;
645             }
646 11         60 for my $set (@sets) {
647 9 100 100     167 next unless $self->{AV_OPTS}{$set} && @{$self->{AV_OPTS}{$set}};
  8         55  
648 2         9 push(@opts, @{$self->{AV_OPTS}{$set}});
  2         10  
649             }
650 11         290 return @opts;
651             }
652              
653             # Internal, collects data for use by 'summary' method.
654             sub _addstats {
655 0     0   0 my $self = shift;
656 0         0 my($prg, $argcnt) = @_;
657 0   0     0 my $stats = $Argv::Summary->{$prg} || [0, 0];
658 0         0 $$stats[0]++;
659 0         0 $$stats[1] += $argcnt;
660 0         0 $Argv::Summary->{$prg} = $stats;
661             }
662              
663             # Handles ->autofail operations. If given a scalar, exit with the value
664             # of that scalar on failure unless the scalar == 0, in which case
665             # don't exit. If given a ref to a scalar, increment the scalar for
666             # each failure. If given a code ref, call that subroutine. An array ref
667             # is assumed to contain a code ref followed by parameters for the sub.
668             sub fail {
669 2     2 0 8 my($self, $specific) = @_;
670 2         32 my $general = $self->autofail;
671 2 100 66     58 if (my $val = $specific || $general) {
672 1 50       18 if (ref($val) eq 'CODE') {
    50          
    0          
    0          
    0          
673 0         0 &$val($self);
674             } elsif (ref($val) eq 'ARRAY') {
675 1         14 my @arr = @$val;
676 1         7 my $func = shift(@arr);
677 1         57 &$func(@arr);
678             } elsif (ref($val) eq 'SCALAR') {
679 0         0 $$val++;
680             } elsif ($val !~ /^\d*$/) {
681 0         0 die $val;
682             } elsif ($val) {
683 0         0 exit $val;
684             }
685             }
686 2         61 return $self;
687             }
688              
689             # Convert lines to UNIX (/) format iff they represent file pathnames.
690             sub unixpath {
691 0     0 0 0 my $self = shift;
692 0         0 for (@_) {
693 0         0 chomp(my $chomped = $_);
694 0 0       0 s%\\%/%g if -e $chomped;
695             }
696             }
697              
698             # A no-op except it prints the current state of the object to stderr.
699             sub objdump {
700 0     0 1 0 my $self = shift;
701 0   0     0 (my $obj = shift || 'argv') =~ s%^\$%%;
702 0         0 require Data::Dumper;
703 0         0 print STDERR Data::Dumper->new([$self], [$obj])->Dumpxs;
704 0         0 return $self;
705             }
706              
707             sub readonly {
708 2     2 1 6 my $self = shift;
709 1     1   11 no strict 'refs';
  1         1  
  1         1509  
710 2 50       22 if (@_) {
711 0         0 $self->{AV_READONLY} = shift;
712 0         0 return $self;
713             } else {
714 2 50       16 if (exists($self->{AV_READONLY})) {
715 0         0 return $self->{AV_READONLY}; # instance
716             } else {
717 2         7 my $class = ref $self;
718 2 50 33     45 if ($class && exists($class->{AV_READONLY})) {
719 0         0 return $class->{AV_READONLY}; # class
720             } else {
721 2         67 return 'no';
722             }
723             }
724             }
725             }
726              
727             sub _read_only {
728 2     2   23 my $self = shift;
729 2         23 return $self->readonly =~ /^y/i;
730             }
731              
732             # Hidden method for printing debug output.
733             sub _dbg {
734 4     4   19 my $self = shift;
735 4         64 my($level, $prefix, $fh, @txt) = @_;
736 4         42 my @tmp = @txt;
737 4 50 33     56 for (@tmp) { $_ = qq("$_") if /\s/ && !/^"/ }
  8         66  
738              
739             # Print all EV's that were added to or modified from the real env.
740 4         22 my $envp = $self->envp;
741 4 50       17 if ($envp) {
742 0         0 for (sort keys %$envp) {
743 0 0 0     0 next if $ENV{$_} && $ENV{$_} eq $envp->{$_};
744 0         0 print $fh "+ [\$$_=", $envp->{$_}, "]\n";
745             }
746             }
747              
748 4 50       16 $self->objdump if $level >= 3;
749 4         25 my($ifd, $ofd, $efd) = ($self->stdin, $self->stdout, $self->stderr);
750 4 50       53 if ($ifd !~ m%^[\d-]*$%) {
    50          
751 0         0 $ifd =~ s%/%\\%g if MSWIN;
752 0         0 push(@tmp, $ifd);
753             } elsif ($ifd < 0) {
754 0         0 push(@tmp, "<$NUL");
755             }
756 4 50       93 if ($ofd !~ m%^[\d-]*$%) {
    100          
    50          
757 0         0 $ofd =~ s%/%\\%g if MSWIN;
758 0         0 push(@tmp, $ofd);
759             } elsif ($ofd <= 0) {
760 1         8 push(@tmp, "1>$NUL");
761             } elsif ($ofd != 1) {
762 0         0 push(@tmp, "1>&$ofd");
763             }
764 4 50       106 if ($efd !~ m%^[\d-]*$%) {
    50          
    50          
765 0         0 $efd =~ s%/%\\%g if MSWIN;
766 0         0 push(@tmp, "2$efd");
767             } elsif ($efd <= 0) {
768 0         0 push(@tmp, "2>$NUL");
769             } elsif ($efd != 2) {
770 0         0 push(@tmp, "2>&$efd");
771             }
772 4         521 print $fh "$prefix @tmp\n";
773             }
774              
775             # Attempt to derive the value of ARG_MAX (the maximum command-line
776             # length) for the current platform. Windows isn't really POSIX and
777             # in my tests POSIX::ARG_MAX() usually throws an exception.
778             # Therefore, on Windows we catch the exception and set the value
779             # to 32767. I don't know what the actual limit is but 32K seems to
780             # work whereas 64K fails and I haven't tried to narrow that range
781             # (actually a bit of subsequent testing showed 48000 to work and
782             # 50000 to fail, but I still prefer to depend on a round number).
783             # On other platforms, if ARG_MAX is missing we use _POSIX_ARG_MAX
784             # (4096) # as the default (that being the smallest value of ARG_MAX
785             # allowed by the POSIX standard).
786             {
787             my($_argmax, $_pathmax);
788             sub _arg_max {
789 1     1   23 require Config;
790 1 50       5 if (!defined($_argmax)) {
791 1         6 $_argmax = MSWIN ? 32767 : 4096;
792 1         8 eval { require POSIX; $_argmax = POSIX::ARG_MAX(); };
  1         1269  
  1         8717  
793             # The terminating NULL of argv.
794 1         945 $_argmax -= $Config::Config{ptrsize};
795             }
796 1         3196 return $_argmax;
797             }
798             sub _path_max {
799 2 100   2   7 if (!defined($_pathmax)) {
800 1         2 $_pathmax = MSWIN ? 260 : 1024;
801 1         4 eval { require POSIX; $_pathmax = POSIX::PATH_MAX(); };
  1         5  
  1         5  
802             }
803 2         5 return $_pathmax;
804             }
805             }
806              
807             # Determine the size of the environment block for subtraction
808             # from the calculated value of ARG_MAX. We allow for an equals
809             # sign and terminating null in each EV, plus the pointer
810             # within the environ array that references it.
811             # Note: Windows limits do not appear to include the environment block.
812             sub _env_size {
813 1     1   11 require Config;
814 1         2 my $envlen = 0;
815 1         12 my $ptrsize = $Config::Config{ptrsize};
816 1         22 for my $ev (keys %ENV) {
817 19         21 $envlen += length($ev);
818 19 100       46 $envlen += length($ENV{$ev}) if $ENV{$ev};
819 19         33 $envlen += 2 + $ptrsize;
820             }
821             # Need one more pointer's worth for the terminating NULL in 'environ'.
822 1         6 return $envlen + $ptrsize;
823             }
824              
825             # In the case where the user wants to do qxargs-style chunking by
826             # buffer length rather than argument count, we need to keep pushing
827             # args onto said buffer till we run out of room.
828             sub _chunk_by_length {
829 0     0   0 require Config;
830 0         0 my ($args, $max) = @_;
831 0         0 my @chunk = ();
832 0         0 my $chunklen = 0;
833 0         0 my $extra = $Config::Config{ptrsize} + 1;
834 0         0 while (grep {defined} @{$args}) {
  0         0  
  0         0  
835             # Reached max length?
836 0 0       0 if (($chunklen + length(${$args}[0]) + $extra) >= $max) {
  0         0  
837             # Always send at least one chunk no matter what.
838 0 0       0 push(@chunk, shift(@{$args})) unless @chunk;
  0         0  
839 0         0 last;
840             } else {
841 0         0 $chunklen += length(${$args}[0]) + $extra;
  0         0  
842 0         0 push(@chunk, shift(@{$args}));
  0         0  
843             }
844             }
845             #printf STDERR "CHUNK: $chunklen (MAX=$max, LEFT=%d)\n", scalar(@{$args});
846 0         0 return @chunk;
847             }
848              
849             # Wrapper around Perl's exec(). Strawberry Perl 5.12 warns...
850 1     1   7 { no warnings 'redefine';
  1         3  
  1         6767  
851             sub exec {
852 1 50 33 1 1 35 $class->new(@_)->exec if !ref($_[0]) || ref($_[0]) eq 'HASH';
853 1         3 my $self = shift;
854 1 50 33     14 if ((ref($self) ne $class) && $self->ipc_childsafe) {
855 0   0     0 exit($self->system(@_) || $self->ipc_childsafe->finish);
856             } elsif (MSWIN && $self->execwait) {
857             exit($self->system(@_) >> 8);
858             } else {
859 1         6 my $envp = $self->envp;
860 1         10 my $dbg = $self->dbglevel;
861 1         27 my @cmd = (@{$self->{AV_PROG}},
  1         11  
862 1         8 $self->_sets2opts(@_), @{$self->{AV_ARGS}});
863 1 50 33     15 if ($self->noexec && !$self->_read_only) {
864 1         18 $self->_dbg($dbg, '-', \*STDERR, @cmd);
865             } else {
866 0         0 my($ifd, $ofd, $efd) = ($self->stdin, $self->stdout, $self->stderr);
867 0 0       0 $self->_dbg($dbg, '+', \*STDERR, @cmd) if $dbg;
868 0         0 open(_I, '<&STDIN');
869 0         0 open(_O, '>&STDOUT');
870 0         0 open(_E, '>&STDERR');
871 0 0       0 if ($ifd !~ m%^[\d-]*$%) {
    0          
872 0 0       0 open(STDIN, $ifd) || warn "$ifd: $!";
873             } elsif ($ifd < 0) {
874 0 0       0 open(STDIN, "<$NUL") || warn "STDIN: $!";
875             } else {
876 0 0       0 warn "Warning: illegal value '$ifd' for stdin" if $ifd > 0;
877             }
878 0 0 0     0 if ($ofd !~ m%^[\d-]*$% && !$self->quiet) {
    0 0        
    0          
    0          
879 0 0       0 open(STDOUT, $ofd) || warn "$ofd: $!";
880             } elsif ($ofd <= 0 || $self->quiet) {
881 0 0       0 open(STDOUT, ">$NUL") || warn "STDOUT: $!";
882             } elsif ($ofd == 2) {
883 0 0       0 open(STDOUT, '>&STDERR') || warn "Can't dup stdout";
884             } elsif ($ofd != 1) {
885 0         0 warn "Warning: illegal value '$ofd' for stdout";
886             }
887 0 0       0 if ($efd !~ m%^[\d-]*$%) {
    0          
    0          
    0          
888 0 0       0 open(STDERR, $efd) || warn "$efd: $!";
889             } elsif ($efd <= 0) {
890 0 0       0 open(STDERR, ">$NUL") || warn "STDERR: $!";
891             } elsif ($efd == 1) {
892 0 0       0 open(STDERR, '>&STDOUT') || warn "Can't dup stderr";
893             } elsif ($efd > 2) {
894 0         0 warn "Warning: illegal value '$efd' for stderr";
895             }
896 0         0 my $rc;
897 0 0       0 if ($envp) {
898 0         0 local %ENV = %$envp;
899 0         0 $rc = exec(@cmd);
900             } else {
901 0         0 $rc = exec(@cmd);
902             }
903             # Shouldn't get here but defensive programming and all that ...
904 0 0       0 if ($rc) {
905 0         0 my $error = "$!";
906 0         0 open(STDIN, '<&_I'); close(_I);
  0         0  
907 0         0 open(STDOUT, '>&_O'); close(_O);
  0         0  
908 0         0 open(STDERR, '>&_E'); close(_E);
  0         0  
909 0         0 die "$0: $cmd[0]: $error\n";
910             }
911             }
912             }
913             }}
914              
915             sub lastresults {
916 2     2 1 21 my $self = shift;
917 2 50       169 if (defined(wantarray)) {
918 0         0 my @qxarr = @{$self->{AV_LASTRESULTS}};
  0         0  
919 0         0 my $rc = shift @qxarr;
920 0 0       0 if (wantarray) {
921 0         0 return @qxarr;
922             } else {
923 0         0 return $rc;
924             }
925             } else {
926 2         44 $self->{AV_LASTRESULTS} = \@_;
927             }
928             }
929              
930             # Internal - service method for system/exec to call into IPC::ChildSafe.
931             sub _ipccmd {
932 0     0   0 my $self = shift;
933 0         0 my $cmd = shift;
934             # Throw out the prog name since it's already running
935 0 0       0 if (@_) {
936 0         0 $cmd = "@_";
937             } else {
938 0         0 $cmd =~ s/^\w+\s*//;
939             }
940             # Hack - there's an "impedance mismatch" between instance
941             # methods in this class and the class methods in
942             # IPC::ChildSafe, so we toggle the attrs for every cmd.
943 0         0 my $csobj = $self->ipc_childsafe;
944 0         0 $csobj->dbglevel($self->dbglevel);
945 0 0 0     0 $csobj->noexec($self->noexec) if $self->noexec && !$self->_read_only;
946 0         0 my %results = $csobj->cmd($cmd);
947 0         0 return %results;
948             }
949              
950             # Wrapper around Perl's system().
951             sub system {
952 9 50 33 9 1 352 return $class->new(@_)->system if !ref($_[0]) || ref($_[0]) eq 'HASH';
953 9         12 my $self = shift;
954 9         50 my $envp = $self->envp;
955 9         17 my $rc = 0;
956 9         78 my($ifd, $ofd, $efd) = ($self->stdin, $self->stdout, $self->stderr);
957 9 50       36 $self->args($self->glob) if $self->autoglob;
958 9         11 my @prog = @{$self->{AV_PROG}};
  9         34  
959 9         75 my @opts = $self->_sets2opts(@_);
960 9         16 my @args = @{$self->{AV_ARGS}};
  9         39  
961 9 50 33     45 my $childsafe = ((ref($self) ne $class) &&
962             $self->ipc_childsafe && !$self->mustexec) ? 1 : 0;
963              
964             # These potentially modify their arguments in place.
965 9         81 $self->argpathnorm(@prog, @args);
966 9 50 33     26 $self->quote(@prog, @opts, @args)
967             if (((MSWIN && (@prog + @opts + @args) > 1) || $childsafe) &&
968             $self->autoquote);
969 9         152 my @cmd = (@prog, @opts, @args);
970 9         37 my $dbg = $self->dbglevel;
971 9 50       20 if ($childsafe) {
972 0 0       0 $self->_addstats("@prog", scalar @args) if $Argv::Summary;
973 0 0       0 $self->warning("cannot change \%ENV of child process") if $envp;
974 0 0       0 $self->warning("cannot close stdin of child process") if $ifd;
975 0         0 my %results = $self->_ipccmd(@cmd);
976 0         0 $? = $rc = ($results{status} << 8);
977 0 0       0 if ($self->quiet) {
    0          
    0          
978             # say nothing
979             } elsif ($ofd !~ m%^[\d-]*$%) {
980 0 0       0 if (open(OFD, $ofd)) {
981 0 0       0 print OFD @{$results{stdout}} if @{$results{stdout}};
  0         0  
  0         0  
982 0         0 close OFD;
983             } else {
984 0         0 warn "$ofd: $!";
985             }
986             } elsif ($ofd == 2) {
987 0 0       0 print STDERR @{$results{stdout}} if @{$results{stdout}};
  0         0  
  0         0  
988             } else {
989 0 0       0 warn "Warning: illegal value '$ofd' for stdout" if $ofd > 2;
990 0 0       0 print STDOUT @{$results{stdout}} if @{$results{stdout}};
  0         0  
  0         0  
991             }
992 0 0       0 if ($efd == 1) {
    0          
993 0 0       0 print STDOUT @{$results{stderr}} if @{$results{stderr}};
  0         0  
  0         0  
994             } elsif ($efd !~ m%^[\d-]*$%) {
995 0 0       0 if (open(EFD, $efd)) {
996 0 0       0 print EFD @{$results{stderr}} if @{$results{stderr}};
  0         0  
  0         0  
997 0         0 close EFD;
998             } else {
999 0         0 warn "$efd: $!";
1000             }
1001             } else {
1002 0 0       0 warn "Warning: illegal value '$efd' for stderr" if $efd > 2;
1003 0 0       0 print STDERR @{$results{stderr}} if @{$results{stderr}};
  0         0  
  0         0  
1004             }
1005             } else {
1006             # Reset to defaults in dbg mode (what's this for?)
1007 9 50 33     72 ($ofd, $efd) = (1, 2) if defined($dbg) && $dbg > 2;
1008 9 100 66     33 if ($self->noexec && !$self->_read_only) {
1009 1         19 $self->_dbg($dbg, '-', \*STDERR, @cmd);
1010 1         8 return 0;
1011             }
1012 8         378 open(_I, '<&STDIN');
1013 8         114 open(_O, '>&STDOUT');
1014 8         93 open(_E, '>&STDERR');
1015              
1016 8 50       356 if ($ifd !~ m%^[\d-]*$%) {
    50          
1017 0 0       0 open(STDIN, $ifd) || warn "$ifd: $!";
1018             } elsif ($ifd < 0) {
1019 0 0       0 open(STDIN, "<$NUL") || warn "STDIN: $!";
1020             } else {
1021 8 50       23 warn "Warning: illegal value '$ifd' for stdin" if $ifd > 0;
1022             }
1023              
1024 8 50 33     103 if ($ofd !~ m%^[\d-]*$% && !$self->quiet) {
    100 66        
    50          
    50          
1025 0 0       0 open(STDOUT, $ofd) || warn "$ofd: $!";
1026             } elsif ($ofd <= 0 || $self->quiet) {
1027 4 50       247 open(STDOUT, ">$NUL") || warn "STDOUT: $!";
1028             } elsif ($ofd == 2) {
1029 0 0       0 open(STDOUT, '>&STDERR') || warn "Can't dup stdout";
1030             } elsif ($ofd != 1) {
1031 0         0 warn "Warning: illegal value '$ofd' for stdout";
1032             }
1033              
1034 8 50       86 if ($efd !~ m%^[\d-]*$%) {
    100          
    50          
    50          
1035 0 0       0 open(STDERR, $efd) || warn "$efd: $!";
1036             } elsif ($efd <= 0) {
1037 2 50       120 open(STDERR, ">$NUL") || warn "STDERR: $!";
1038             } elsif ($efd == 1) {
1039 0 0       0 open(STDERR, '>&STDOUT') || warn "Can't dup stderr";
1040             } elsif ($efd > 2) {
1041 0         0 warn "Warning: illegal value '$efd' for stderr";
1042             }
1043              
1044 8         50 my $limit = $self->syxargs;
1045 8 50 33     24 if ($limit && @args) {
1046 0 0       0 if ($limit == -1) {
1047 0         0 $limit = -_arg_max();
1048 0         0 $limit += _env_size() if !MSWIN;
1049             # There's no shell used in list-form system() ...
1050 0         0 $limit += _path_max(); # for @prog
1051 0         0 $limit += length("@opts");
1052             }
1053 0 0       0 while (my @chunk = $limit > 0 ?
1054             splice(@args, 0, $limit) :
1055             _chunk_by_length(\@args, abs($limit))) {
1056 0 0       0 $self->_addstats("@prog", scalar @chunk) if $Argv::Summary;
1057 0         0 @cmd = (@prog, @opts, @chunk);
1058 0 0       0 $self->_dbg($dbg, '+', \*_E, @cmd) if $dbg;
1059 0 0       0 if ($envp) {
1060 0         0 local %ENV = %$envp;
1061 0         0 $rc |= system @cmd;
1062             } else {
1063 0         0 $rc |= system @cmd;
1064             }
1065             }
1066             } else {
1067 8 50       20 $self->_addstats("@prog", scalar @args) if $Argv::Summary;
1068 8 100       37 $self->_dbg($dbg, '+', \*_E, @cmd) if $dbg;
1069 8 50       318 if ($envp) {
1070 0         0 local %ENV = %$envp;
1071 0         0 $rc = system @cmd;
1072             } else {
1073 8         611974 $rc = system @cmd;
1074             }
1075             }
1076 8         917 open(STDIN, '<&_I'); close(_I);
  8         82  
1077 8         333 open(STDOUT, '>&_O'); close(_O);
  8         102  
1078 8         173 open(STDERR, '>&_E'); close(_E);
  8         1539  
1079             }
1080 8 50       108 print STDERR "+ (\$? == $?)\n" if $dbg > 1;
1081 8 100       117 if ($?) {
1082 2         102 $self->lastresults($?>>8, ());
1083 2         92 $self->fail($self->syfail);
1084             }
1085 8         1065 return $rc;
1086             }
1087              
1088             # Wrapper around Perl's qx(), aka backquotes.
1089             sub qx {
1090 1 50 33 1 1 47 return $class->new(@_)->qx if !ref($_[0]) || ref($_[0]) eq 'HASH';
1091 1         5 my $self = shift;
1092 1         23 my $envp = $self->envp;
1093 1         9 my @prog = @{$self->{AV_PROG}};
  1         10  
1094 1         24 my @opts = $self->_sets2opts(@_);
1095 1         5 my @args = @{$self->{AV_ARGS}};
  1         7  
1096 1 50 33     14 my $childsafe = ((ref($self) ne $class) &&
1097             $self->ipc_childsafe && !$self->mustexec) ? 1 : 0;
1098              
1099             # These potentially modify their arguments in place.
1100 1         1 @args = $self->glob(@args)
1101             if MSWIN && $self->autoglob && $childsafe;
1102 1         12 $self->argpathnorm(@prog, @args);
1103 1 50 33     26 $self->quote(@prog, @opts, @args)
      33        
1104             if (((@prog + @opts + @args) > 1 || $childsafe) && $self->autoquote);
1105              
1106 1         6 my @cmd = (@prog, @opts, @args);
1107 1         5 my @data;
1108 1         1 my $dbg = 0;
1109 1         2 my $rc = 0;
1110 1         13 my($ifd, $ofd, $efd) = ($self->stdin, $self->stdout, $self->stderr);
1111 1   33     68 my $noexec = $self->noexec && !$self->_read_only;
1112 1 50       6 if ($childsafe) {
1113 0 0       0 $self->_addstats("@prog", scalar @args) if $Argv::Summary;
1114 0 0       0 $self->warning("cannot change \%ENV of child process") if $envp;
1115 0 0       0 $self->warning("cannot close stdin of child process") if $ifd;
1116 0 0       0 if ($noexec) {
1117 0         0 $self->_dbg($dbg, '-', \*STDERR, @cmd);
1118             } else {
1119 0         0 my %results = $self->_ipccmd(@cmd);
1120 0 0       0 if ($ofd <= 0) {
    0          
    0          
1121             # ignore the results
1122             } elsif ($ofd == 1) {
1123 0         0 push(@data, @{$results{stdout}});
  0         0  
1124             } elsif ($ofd == 2) {
1125 0         0 print STDERR @{$results{stdout}};
  0         0  
1126             } else {
1127 0         0 warn "Warning: illegal value '$ofd' for stdout";
1128             }
1129 0 0       0 if ($efd == 1) {
1130 0         0 push(@data, @{$results{stderr}});
  0         0  
1131             } else {
1132 0 0       0 print STDERR @{$results{stderr}} if $efd;
  0         0  
1133 0 0       0 warn "Warning: illegal value '$efd' for stderr" if $efd > 2;
1134             }
1135 0         0 $? = $rc = $results{status} << 8;
1136             }
1137             } else {
1138 1         4 $dbg = $self->dbglevel;
1139             # Reset to defaults in dbg mode (what's this for?)
1140 1 50 33     11 ($ofd, $efd) = (1, 2) if defined($dbg) && $dbg > 2;
1141 1         11 my $limit = $self->qxargs;
1142 1 50 33     26 if ($limit && @args) {
1143 1 50       5 if ($limit == -1) {
1144 1         10 $limit = -_arg_max();
1145 1         161 $limit += _env_size() if !MSWIN;
1146 1         6 $limit += _path_max(); # for the shell
1147 1         3 $limit += length('-c');
1148 1         4 $limit += _path_max(); # for @prog
1149 1         5 $limit += length("@opts");
1150             }
1151 1 50       13 while (my @chunk = $limit > 0 ?
1152             splice(@args, 0, $limit) :
1153             _chunk_by_length(\@args, abs($limit))) {
1154 1 50       6 $self->_addstats("@prog", scalar @chunk) if $Argv::Summary;
1155 1         6 @cmd = (@prog, @opts, @chunk);
1156 1 50       4 if ($noexec) {
1157 0         0 $self->_dbg($dbg, '-', \*STDERR, @cmd);
1158             } else {
1159 1 50       7 $self->_dbg($dbg, '+', \*STDERR, @cmd) if $dbg;
1160 1         12 $self->_qx_stderr(\@cmd, $efd);
1161 1         5 $self->_qx_stdout(\@cmd, $ofd);
1162 1 50       4 if ($envp) {
1163 0         0 local %ENV = %$envp;
1164 0         0 push(@data, qx(@cmd));
1165             } else {
1166 1         623152 push(@data, qx(@cmd));
1167             }
1168 1   33     84 $rc ||= $?;
1169             }
1170             }
1171             } else {
1172 0 0       0 $self->_addstats("@prog", scalar @args) if $Argv::Summary;
1173 0 0       0 if ($noexec) {
1174 0         0 $self->_dbg($dbg, '-', \*STDERR, @cmd);
1175             } else {
1176 0 0       0 $self->_dbg($dbg, '+', \*STDERR, @cmd) if $dbg;
1177 0         0 $self->_qx_stderr(\@cmd, $efd);
1178 0         0 $self->_qx_stdout(\@cmd, $ofd);
1179 0 0       0 if ($envp) {
1180 0         0 local %ENV = %$envp;
1181 0         0 @data = qx(@cmd);
1182             } else {
1183 0         0 @data = qx(@cmd);
1184             }
1185 0   0     0 $rc ||= $?;
1186             }
1187             }
1188 1 50 33     24 $? = $rc if $rc && ! $?;
1189             }
1190 1 50       7 print STDERR "+ (\$? == $?)\n" if $dbg > 1;
1191 1 50       18 if ($?) {
1192 0         0 $self->lastresults($?>>8, @data);
1193 0         0 $self->fail($self->qxfail);
1194             }
1195 1         6 $self->unixpath(@data) if MSWIN && $self->outpathnorm;
1196 1 50       15 if (wantarray) {
1197 1 50 33     24 print STDERR map {"+ <- $_"} @data if @data && $dbg >= 2;
  0         0  
1198 1 50       26 chomp(@data) if $self->autochomp;
1199 1         81 return @data;
1200             } else {
1201 0           my $data = join('', @data);
1202 0 0 0       print STDERR "+ <- $data" if @data && $dbg >= 2;
1203 0 0         chomp($data) if $self->autochomp;
1204 0           return $data;
1205             }
1206             }
1207             # Can't override qx() in main package so we export an alias instead.
1208             *qv = \&qx;
1209              
1210             sub pipe {
1211 0 0 0 0 1   return $class->new(@_)->pipe if !ref($_[0]) || ref($_[0]) eq 'HASH';
1212              
1213 0           my $self = shift;
1214              
1215 0           my $cb = $self->pipecb;
1216 0 0         $self->error("No callback supplied") unless ref($cb) eq 'CODE';
1217              
1218 0           my ($pipe, $pid) = $self->readpipe(@_);
1219 0           my $line;
1220 0           my $abort = 0;
1221 0           while($line = <$pipe>) {
1222 0 0         chomp($line) if $self->autochomp;
1223 0           my $keepGoing = &$cb($line);
1224 0 0         if (!$keepGoing) {
1225 0 0         if ($self->_read_only) {
1226 0           $abort = 1;
1227 0           last;
1228             }
1229 0           $self->warning("Not abortable unless readonly - continuing!");
1230             }
1231             }
1232 0           if (MSWIN && $abort) {
1233             # This is somewhat ugly, but due to perl impl details as well as
1234             # the fact that Windows does not have the proper counterpart to
1235             # SIGPIPE, we'll have to 'help' things along...
1236             #
1237             Argv::Win32Utils::killProcessTree($self, $pid);
1238             }
1239 0           my $rc = close($pipe);
1240 0 0         $self->fail($self->qxfail) if !$rc;
1241 0           return $rc;
1242             }
1243              
1244             # Wrapper around Perl's "open(FOO, ' |')" operator.
1245             sub readpipe {
1246 0 0 0 0 0   return $class->new(@_)->readpipe if !ref($_[0]) || ref($_[0]) eq 'HASH';
1247 0           my $self = shift;
1248 0           my $envp = $self->envp;
1249 0           my @prog = @{$self->{AV_PROG}};
  0            
1250 0           my @opts = $self->_sets2opts(@_);
1251 0           my @args = @{$self->{AV_ARGS}};
  0            
1252              
1253             # These potentially modify their arguments in place.
1254 0           $self->argpathnorm(@prog, @args);
1255 0 0 0       $self->quote(@prog, @opts, @args)
1256             if (((@prog + @opts + @args) > 1) && $self->autoquote);
1257              
1258 0           my @cmd = (@prog, @opts, @args);
1259 0           my $dbg = 0;
1260 0           my($ifd, $ofd, $efd) = ($self->stdin, $self->stdout, $self->stderr);
1261 0   0       my $noexec = $self->noexec && !$self->_read_only;
1262 0           $dbg = $self->dbglevel;
1263 0 0         $self->_addstats("@prog", scalar @args) if $Argv::Summary;
1264 0 0         if ($noexec) {
1265 0           $self->_dbg($dbg, '-', \*STDERR, @cmd, '|');
1266             } else {
1267 0           my $handle;
1268 0 0         $self->_dbg($dbg, '+', \*STDERR, @cmd, '|') if $dbg;
1269 0           $self->_qx_stderr(\@cmd, $efd);
1270 0           $self->_qx_stdout(\@cmd, $ofd);
1271 0           my $rc;
1272 0 0         if ($envp) {
1273 0           local %ENV = %$envp;
1274 0           $rc = open($handle, "@cmd |");
1275             } else {
1276 0           $rc = open($handle, "@cmd |");
1277             }
1278 0 0 0       $self->fail($self->qxfail) if !$rc || !defined($handle);
1279 0           my $oldfh = select($handle); $| = 1; select($oldfh);
  0            
  0            
1280 0 0         return wantarray ? ($handle, $rc) : $handle;
1281             }
1282             }
1283              
1284             # Internal - provide a warning with std format and caller's context.
1285             sub warning {
1286 0     0 0   my $self = shift;
1287 0           (my $prog = $0) =~ s%.*[/\\]%%;
1288 1     1   23 no strict 'refs';
  1         2  
  1         142  
1289 0   0       carp('Warning: ', ${$self->{AV_PROG}}[-1] || $prog, ': ', @_);
1290             }
1291              
1292             # Internal - provide a fatal error with std format and caller's context.
1293             sub error {
1294 0     0 0   my $self = shift;
1295 0           (my $prog = $0) =~ s%.*[/\\]%%;
1296 1     1   5 no strict 'refs';
  1         14  
  1         829  
1297 0   0       croak('Error: ', ${$self->{AV_PROG}}[-1] || $prog, ': ', @_);
1298             }
1299              
1300             # Hack this thing in here to help with *&#$ Windows. We want to hide it
1301             # as much as possible in the hope that a better way may be found
1302             # someday. Thus it's implemented as an "inner class" rather than
1303             # a separate file.
1304             {
1305             package Argv::Win32Utils;
1306              
1307             # Preload this to avoid INIT block failure in Win32::API::Type
1308             # (but it may not be installed at all, which is ok).
1309             eval "require Win32::API";
1310              
1311             # For internal use only - attempt to kill the process tree stemming from
1312             # the given pid.
1313             # Attempts several ways using various packages that may or may not be
1314             # present.
1315             sub killProcessTree {
1316 0     0     my $argv = shift;
1317 0           my $pid = shift;
1318              
1319             # Undocumented way to turn this off in case it causes big problems...
1320 0 0         return 0 if $ENV{ARGV_WIN32UTILS_SKIP_KILLPROCESSTREE};
1321              
1322 0           require Win32::Process;
1323            
1324 0           my ($implDesc, $impl) = __findImpl($argv);
1325 0 0         print STDERR "Using $implDesc...\n" if $argv->dbglevel > 1;
1326 0           &$impl($argv, $pid);
1327            
1328 0           return 0;
1329             }
1330              
1331             # For internal use only - attempt to kill a single process
1332             sub killProcess {
1333 0     0     my $argv = shift;
1334 0           my $pid = shift;
1335              
1336 0 0         print STDERR "Killing $pid...\n" if $argv->dbglevel > 1;
1337 0           return Win32::Process::KillProcess($pid, 0);
1338             }
1339              
1340             # Implementation using Win32::Process::Info
1341             # This pkg can give us a (pruned) pid tree with the expected
1342             # layout right away.
1343             sub __win32_process_info {
1344 0     0     my $argv = shift;
1345 0           my $pid = shift;
1346              
1347 0           my %pidTree = new Win32::Process::Info->Subprocesses($pid);
1348 0           __deepKill($argv, $pid, \%pidTree);
1349            
1350 0           return 0;
1351             }
1352              
1353             # Implementation using Win32::ToolHelp
1354             # this pkg gives a different view - rework into a pid tree
1355             # by 1) enter all pids as keys, and then 2) add their children.
1356             sub __win32_toolhelp {
1357 0     0     my $argv = shift;
1358 0           my $pid = shift;
1359              
1360 0           my %pidTree;
1361 0           my @allProcesses = Win32::ToolHelp::GetProcesses();
1362 0           $pidTree{$_->[1]} = [] foreach (@allProcesses);
1363 0           push(@{$pidTree{$_->[5]}}, $_->[1]) foreach (@allProcesses);
  0            
1364 0           __deepKill($argv, $pid, \%pidTree);
1365              
1366 0           return 0;
1367             }
1368              
1369             # Kill processes depth first by following the tree.
1370             sub __deepKill {
1371 0     0     my $argv = shift;
1372 0           my $pid = shift;
1373 0           my $pidTree = shift;
1374            
1375             # give a parent an opportunity to terminate by itself
1376             # which is likely when their child died
1377             #
1378 0           foreach my $childPid (@{$pidTree->{$pid}}) {
  0            
1379 0           __deepKill($argv, $childPid, $pidTree);
1380             }
1381 0           killProcess($argv, $pid);
1382             }
1383              
1384             # Dynamically find an implementation that can figure out
1385             # the process tree and kill it.
1386             # Fall back to just kill the root pid (which may just be enough).
1387             sub __findImpl {
1388 0     0     my $argv = shift;
1389            
1390             # begin with a list to ensure a preferred search order
1391             # but put the list in a hash for easy lookup
1392             #
1393 0           my @implList = (
1394             "Win32::ToolHelp", \&__win32_toolhelp,
1395             "Win32::Process::Info", \&__win32_process_info,
1396             );
1397 0           my %implHash = @implList;
1398 0           foreach my $implName (@implList) {
1399 0           eval "use $implName";
1400 0 0         return ("$implName (tree capable)", $implHash{$implName}) unless $@;
1401             }
1402            
1403             # no luck, use fallback
1404 0           my @helpers = keys(%implHash);
1405 0           $argv->warning("No process tree helper found - install any of these packages: [@helpers]");
1406 0           return ("Win32::Process (not tree capable)", \&killProcess);
1407             }
1408              
1409             1;
1410             }
1411              
1412             1;
1413              
1414             __END__