Subject: | FYI: XS code which fails to run with IO::Callback: Win32::Job |
The docs say "Fails to inter-operate with some library modules that read or write filehandles from within XS code. I am aware of the following specific cases, please let me know if you run into any others" so here's another one: Win32::Job
Testcase below (stripped down version of the script I was working on). Call it as perl test.pl 1 and it the command will exit with an error. Call it as perl test.pl 0 and a file test.out will be created and everything is fine.
use strict;
use warnings;
use 5.010;
use Win32::Job;
use IO::Callback;
use IO::File;
sub main {
my $use_ioc = $_[0] // 1;
my $stdxxx = sub {
my($type) = @_;
if ($use_ioc) {
return IO::Callback->new('>', sub {
my($data, $type) = @_;
$data =~ tr/\r//d;
$data =~ s/^/$type /gm;
return print($data) or IO::Callback::Error;
}, $type);
}
else {
return IO::File->new('test.' . $type, 'w');
}
};
my $stdout = $stdxxx->('out') or die $!;
my $stderr = $stdxxx->('err') or die $!;
$stdout->print("bar\n");
my $exe = "cmd.exe";
my $job = Win32::Job->new or die "Failed to create job: $^E";
say "Running " . join(' ', $exe);
my $pid = $job->spawn(
$exe,
join(' ', $exe, qw(/c "echo foo")),
{
no_window => 1,
stdin => 'nul',
stdout => $stdout,
stderr => $stderr,
},
) or die "Failed to spawn job: $^E";
$job->watch(
sub {
say ".";
return 0;
},
1,
) or die "Killed";
my $status = $job->status;
my $result = $status->{$pid}->{'exitcode'};
say $result;
return $result;
}
$| = 1;
exit main() // 0;
__END__