- my @args = (
- $self->valgrind,
- $self->tool->args($self),
- @supp_args,
- $self->parser->args($self, $vwtr),
- $self->command->args($self),
- );
+ my @args = (
+ $self->valgrind,
+ $self->tool->args($self),
+ @supp_args,
+ $self->parser->args($self, $vwtr),
+ $self->command->args($self),
+ );
+
+ {
+ no warnings 'exec';
+ exec { $args[0] } @args;
+ }
+ $self->_croak("exec @args: $!");
+ };
+
+ print $ewtr $@;
+ close $ewtr;
+
+ POSIX::_exit(255);
+ }
+
+ local $@;
+ eval {
+ local $SIG{INT} = sub {
+ die 'valgrind analysis was interrupted';
+ };
+
+ close $vwtr or $self->_croak("close(\$vwtr): $!");
+ close $ewtr or $self->_croak("close(\$ewtr): $!");
+
+ SEL: {
+ my $sel = IO::Select->new($vrdr, $erdr);
+
+ my $child_err;
+ while (my @ready = $sel->can_read) {
+ last SEL if @ready == 1 and fileno $ready[0] == fileno $vrdr;
+
+ my $buf;
+ my $bytes_read = sysread $erdr, $buf, 4096;
+ if (not defined $bytes_read) {
+ $self->_croak("sysread(\$erdr): $!");
+ } elsif ($bytes_read) {
+ $sel->remove($vrdr) unless $child_err;
+ $child_err .= $buf;
+ } else {
+ $sel->remove($erdr);
+ die $child_err if $child_err;
+ }
+ }
+ }