Subject: | IPC::Run causes Perl to silently abort |
This problem has been tested on Solaris 8 and Fedora Core 3 Linux with Perl 5.8.6 and IPC::Run 0.78 and 0.79.
I'm using IPC::Run to feed input to and gather the output from a command called "vxprint". Whenever vxprint detects a problem with its input, it aborts and emits a message on STDERR. I would expect that IPC::Run's run function would be able to deal with this and return the status and STDERR of the program that aborted. Instead, the entire perl script aborts under certain conditions outlined below without any indication that an error has occurred. I've even placed an eval { } wrapper around the call to run, with identical results.
First, here's an example of what happens when vxprint is invoked from the shell with bad input data:
$ cat /tmp/vxconfigtest.bad | vxprint -g rootdg -D - \
Show quoted text
> -e 'sd && sd_plex.pl_volume = "rootvol"' -F'%name %da_name'
VxVM vxprint ERROR V-5-1-326 unknown user name, context: user=dimwit
But if I run the same command from the script below, here's what happens:
On Solaris 8:
- with IPCRUNDEBUG unset: Runs fine - output is as expected
- with IPCRUNDEBUG set to 1 or 2: Also runs fine
- with IPCRUNDEBUG set to 3 or 4: Perl simply exits silently when the run subroutine is entered
On Linux:
- Perl exits silently under all circumstances
Here's the script:
=============================vxprint test script ===============================================
use FileHandle;
use IPC::Run qw(run);
my $fh = FileHandle->new("/tmp/vxconfigtest.bad");
my $vxconfig = do { local $/; <$fh>; };
$fh->close;
my $out = vxprint(vxconfig => $vxconfig,
query => 'sd && sd_plex.pl_volume = "rootvol"',
fields => '%name %daname');
print "vxprint output: $out\n";
#
# vxprint: Provides interface to vxprint command
# Args: dgname => <dgname to work on>
# vxconfig => <scalar containing output of vxprint -m to use instead
# of vxconfigd>
# query => <query string (no leading -e)>
# fields => <fields string (no leading -F)>
# Returns: Output of specified fields
#
# Example of use:
# $out = vxprint(vxconfig => $vxconfig1,
# query => 'sd && sd_plex.pl_volume = "rootvol"',
# fields => '%name %daname');
sub vxprint {
my (%args) = @_;
my ($dgname,$vxconfig,$query,$fields);
my (@dg_arg,@e_arg,@f_arg,@D_arg,@cmd);
my ($stdout,$stderr);
if (exists $args{dgname}) {
@dg_arg = ('-g', "$args{dgname}");
}
if (exists $args{vxconfig}) {
@D_arg = ('-D', '-');
$vxconfig = $args{vxconfig};
}
if (exists $args{query}) {
@e_arg = ('-e', $args{query});
}
if (exists $args{fields}) {
@f_arg = ('-F', $args{fields});
}
@cmd = ( '/usr/sbin/vxprint', @dg_arg, @D_arg, @e_arg, @f_arg );
#
# TODO: Need to return error code if vxprint produces one
#
if ($vxconfig) {
run \@cmd, \$vxconfig, \$stdout, \$stderr;
} else {
# Note use of ref to undef for STDIN var
run \@cmd, \undef, \$stdout, \$stderr;
}
my ($status) = $? >> 8;
if ($status == 0) {
return $stdout;
} else {
print "vxprint returned an error code of $status\n";
print "And reported this problem:\n$stderr\n";
return; # undef
}
}
=============================vxprint test script ===============================================
I'm attaching the run of that script with IPCRUNDEBUG=2 and IPCRUNDEBUG=4 on Solaris, and with IPCRUNDEBUG=4 on Linux for comparison. Let me know if you need to see a truss/strace of vxprint's run from the shell on either platform so that you can tell what it's really doing that causes IPC::Run to act this way.
Message body is not shown because it is too large.