Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

[Resolved] how to exec() with my filehandles !

by snfever (Novice)
on May 21, 2010 at 18:42 UTC ( #841119=perlquestion: print w/ replies, xml ) Need Help??
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; } }

Comment on [Resolved] how to exec() with my filehandles !
Download Code
Re: how to exec() with my filehandles !
by superfrink (Curate) on May 21, 2010 at 19:10 UTC
    I think you might be looking to change STDIN, STDOUT, STDERR so they point to the files you have opened. See How do I dup() a filehandle in Perl?.
    Update: Sorry, I didn't actually read the code, just the description. It looks like you've already read about duplicating filehandles.
Re: how to exec() with my filehandles !
by ikegami (Pope) on May 21, 2010 at 20:48 UTC

    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

    That describes IPC::Open3's open3 almost exactly. Here's a simple wrapper that provides the desired interface:

    use IPC::Open3 qw( open3 ); sub create_child { my $pid = open3( local *TO_CHLD, local *FR_CHLD, local *FR_CHLD_ERR, @_ ); return ( $pid, *TO_CHLD, *FR_CHLD, *FR_CHLD_ERR ); }
Re: how to exec() with my filehandles !
by JavaFan (Canon) on May 21, 2010 at 20:59 UTC
    Call me confused, but the only "exec" I find in your program is in part of a string literal.

    Assuming a POSIX system (and probably other Unix systems even if they aren't fully POSIX compliant, it may even hold for some non-Unix systems), filehandles are inherited by the execed process - unless they were marked "close on exec".

    But one should realize that file handles are just numbers (well, this is Unix kernel stuff; Unix kernels are written in C; in C, everything is a number (or sequences of numbers); so it's not a surprise file handles are numbers). If your execed process is a Perl program, you'll have to dup a file handle (see perlopentut).

    However, given the lack of an exec in your code, I don't really know what your question is.

      Yes sorry, i put a "system" function in my sub, but it's "exec"
      Code updated!
      thanks !

      I will also try open3, thanks !
        OK, i'm testing the short code (with open3) and it's working perfectly !
        I need to go to CPAN more :)
        Thanks everybody !

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://841119]
Approved by superfrink
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (9)
As of 2014-10-22 15:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (119 votes), past polls