Skip to content

Instantly share code, notes, and snippets.

@kentfredric
Created February 3, 2013 11:50
Show Gist options
  • Save kentfredric/4701480 to your computer and use it in GitHub Desktop.
Save kentfredric/4701480 to your computer and use it in GitHub Desktop.
use v5.14;
use strict;
use warnings;
use Win32::Job;
use File::Which qw( which );
sub _win32_escape_command_token {
my $token = shift;
my $dos_special_chars = '"<>|';
my $dc = quotemeta( $dos_special_chars );
#print "_ = $_\n";
#s:\/:\\:g; # forward to back slashes
if ( $token =~ qr{(\s|[$dc])} )
{
#print "in qr\n";
$token =~ s:":\\":g; # CMD: preserve double-quotes with backslash # TODO: change to $dos_escape ## no critic (ProhibitUnusualDelimiters)
$token =~ s:([\\]+)\\":($1 x 2).q{\\"}:eg; # double backslashes in front of any \" to preserve them when interpreted by DOS/CMD
$token = q{"}.$token.q{"}; # quote the final token
};
return $token;
}
sub _win32_escape_command {
return join q{ }, map { _win32_escape_command_token($_) } @_;
}
sub body {
my ( $reader, @command ) = @_;
my ( $pr, $pw);
pipe($pr,$pw);
my $pid = fork;
if ( not defined $pid ) {
die "Fork Failed";
}
if ( $pid ){
$_[0] = $pr;
return $pid;
}
my( $job ) = Win32::Job->new();
$job->spawn(
which($command[0]),
_win32_escape_command( @command ),
{
stdout => $pw,
stderr => $pw,
}
);
my $result = $job->run( -1 , 0 );
if ( not $result ) {
my $status = $job->status();
if( $job->status()->{exitcode} == 293 ){
die "Process used more than allotted time";
} else {
die $job->status()->{exitcode};
}
}
exit;
}
my $pid = body( my $reader ,'perl','-E', 'say "STDOUT Hi"; *STDERR->say("STDERR Hi")' );
for ( 0..20 ) { say $_; }
while(my $line = <$reader> ) {
local $/ = "\r\n";
chomp $line;
say ">> $line <<";
}
say "End Of Pipe";
waitpid $pid, 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment