http://www.perlmonks.org?node_id=841119

snfever has asked for the wisdom of the Perl Monks concerning the following question:

Hello everybody, (Sorry i'm french !, i'm not speaking english very well !)
If i post here, this is because i want to make a sub which execute some file (or a perl sub), and returns a 4 elements list : the child pid, the in, out and stderr filehandles the function generates
I begin to code that but i want to know how to tell exec to use my filehandles instead of STDIN, STDOUT and STDERR...

here is my code, which i continue to work in :

thanks in advance

Update: i'm looking this url : No inherited file handles with tie() and exec() which is maybe a part of the solution !

sub myFork($$;$) { my ($param_dir, $param_cmd, $param_opt) = @_; return unless (ref($param_cmd) =~ /^ARRAY$/i || ref($param_cmd)); my %options = %$param_opt if ref($param_opt) =~ /HASH/i; local *STDIN, local *STDOUT, local *STDERR; local $SIG{CLD} = local $SIG{CHLD} = sub { my $stiff; while (($sti +ff = waitpid(-1, POSIX::WNOHANG())) > 0) { }; }; local $! = 0; my $fh_in, my $fh_out, my $fh_err, my $fh_log; my $pif = sprintf("%08d",int(rand(100000000))); my $file_in = "/tmp/fh_in_${pif}_$$.avms"; my $file_out = "/tmp/fh_out_${pif}_$$.avms"; my $file_err = "/tmp/fh_err_${pif}_$$.avms"; my $pid; die "myFork => fork" unless defined ($pid = fork); # Partie PARENT : if ($pid) { my $open_in, my $open_out, my $open_err; # Création du fichier TEMPORAIRE d'entrée ( ou l'ouvre en écri +ture) ! : $open_in = open ($fh_in, '>', $file_in) or die "myFork => pare +nt => open => in"; if ($open_in) { my $old_fh = select($fh_in); $| = 1; select($old_fh); } # Puis du fichier TEMPORAIRE de sortie (on tente de l'ouvrir e +n lecture) : my $ind = 0; while ($ind <= 15) { $open_out = open ($fh_out, '<', $file_out); last if $open_out; $ind++; select(undef,undef,undef,0.1 * $ind); } die "myFork => parent => open => out" unless (defined($open_ou +t)); # Puis du fichier TEMPORAIRE des erreurs (on tente de l'ouvrir + en lecture) : $ind = 0; while ($ind <= 15) { $open_err = open ($fh_err, '<', $file_err); last if $open_err; $ind++; select(undef,undef,undef,0.1 * $ind); } die "myFork => parent => open => err" unless (defined($open_er +r)); return ($fh_in,$fh_out,$fh_err,$fh_log); } else # Partie ENFANT : { my $LOOP = 1; local $SIG{TERM} = local $SIG{INT} = sub { $LOOP = 0; }; my $fh_in, my $fh_out, my $fh_err, my $fh_log; my $open_in, my $open_out, my $open_err; # Création du fichier TEMPORAIRE des erreurs ( ou l'ouvre en é +criture) ! : $open_err = open ($fh_err, '>', $file_err) or die "myFork => c +hild => open => err"; if ($open_err) { close STDERR; open(STDERR, '>&' . CORE::fileno($fh_err)) or die "myFork +=> child => open => stderr"; my $old_fh = select($fh_err); $| = 1; select(*STDERR); $| += 1; select($old_fh); } # Création du fichier TEMPORAIRE de sortie ( ou l'ouvre en écr +iture) ! : $open_out = open ($fh_out, '>', $file_out) or die "myFork => c +hild => open => out"; if ($open_out) { my $old_fh = select($fh_out); $| = 1; select($old_fh); close STDOUT; open(STDOUT, '>&' . CORE::fileno($fh_out)) or die "myFork +=> child => open => stdout"; $old_fh = select(*STDOUT); $| = 1; select($old_fh); } # Création du fichier TEMPORAIRE d'entrée (on ouvre en lecture +) : $ind=0; while ($ind <= 15) { $open_in = open ($fh_in, '<', $file_in); last if $open_in; $ind++; select(undef,undef,undef,0.1 * $ind); } unless (defined($open_in)) { die "myFork => child => open => in"; } else { close STDIN; open(STDIN, '<&' . CORE::fileno($fh_in)); } # Lancement ! : # On attend la création de $file_in, $file_out et $file_err : $ind = 0; while ($ind <= 15) { last if (-r $file_in && -w $file_out && -w $file_err); $ind++; select(undef,undef,undef,0.1 * $ind); } print "__START__\n"; chdir ($param_dir) or die "myFork => chdir"; exec (@{$param_cmd}); # Not system ! die "myFork => exec"; exit; } }