Skip Menu |

This queue is for tickets about the IPC-Cmd CPAN distribution.

Report information
The Basics
Id: 46288
Status: resolved
Priority: 0/
Queue: IPC-Cmd

People
Owner: Nobody in particular
Requestors: cberry [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.44
Fixed in: (no value)



Subject: [PATCH] Add argument quoting for run() on VMS
By default, command-line arguments are case-levelled on VMS. The standard way to preserve case is to quote the arguments. The attached patch does that. This gets some CPANPLUS::Dist tests passing that otherwise fail because they do something like: $ perl -M1000000 -e1 syntax error at -e line 0, near "use 1000000 ( " Execution of -e aborted due to compilation errors. %SYSTEM-F-ABORT, abort when what they mean to be doing is: $ perl "-M1000000" "-e1" Perl v1000000.0.0 required--this is only v5.11.0, stopped. BEGIN failed--compilation aborted. %SYSTEM-F-ABORT, abort
Subject: ipc_cmd_run.patch
--- lib/IPC/Cmd.pm;-0 2009-05-04 08:04:09 -0500 +++ lib/IPC/Cmd.pm 2009-05-16 06:46:21 -0500 @@ -345,6 +345,8 @@ sub run { return; }; + $cmd = _quote_args_vms( $cmd ) if IS_VMS; + ### strip any empty elements from $cmd if present $cmd = [ grep { length && defined } @$cmd ] if ref $cmd; @@ -745,6 +747,40 @@ sub _system_run { } } +# Command-line arguments (but not the command itself) must be quoted +# to ensure case preservation. Borrowed from Module::Build with adaptations. + +sub _quote_args_vms { + # Returns a command string with proper quoting so that the subprocess + # sees this same list of args, or if we get a single arg that is an + # array reference, quote the elements of it (except for the first) + # and return the reference. + my @args = @_; + my $got_arrayref = (scalar(@args) == 1 + && UNIVERSAL::isa($args[0], 'ARRAY')) + ? 1 + : 0; + + @args = split(/\s+/, $args[0]) unless $got_arrayref || scalar(@args) > 1; + + my $cmd = $got_arrayref ? shift @{$args[0]} : shift @args; + + # Do not quote qualifiers that begin with '/' or previously quoted args. + map { if (/^[^\/\"]/) { + $_ =~ s/\"/""/g; # escape C<"> by doubling + $_ = q(").$_.q("); + } + } + ($got_arrayref ? @{$args[0]} + : @args + ); + + $got_arrayref ? unshift(@{$args[0]}, $cmd) : unshift(@args, $cmd); + + return $got_arrayref ? $args[0] + : join(' ', @args); +} + ### XXX this is cribbed STRAIGHT from M::B 0.30 here: ### http://search.cpan.org/src/KWILLIAMS/Module-Build-0.30/lib/Module/Build/Platform/Windows.pm:split_like_shell
Thanks; applied, released as 0.46 & submitted to blead. Cheers,