What's the point of the eval here? It's hiding all open3 exceptions. Might be nice to see the
error that the program doesn't exist, for example:
# start the command
$pid = eval { open3( $in, $out, $err, @cmd ); };
return ( $pid, $in, $out, $err );
It's hiding it because it's called within another eval:
my ( $pid, $in, $out, $err ) = eval { $_spawn->(@cmd); };