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 (($stiff = 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 écriture) ! : $open_in = open ($fh_in, '>', $file_in) or die "myFork => parent => 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 en 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_out)); # 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_err)); 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 => child => 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 écriture) ! : $open_out = open ($fh_out, '>', $file_out) or die "myFork => child => 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; } }