Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Redirecting stdout/stderr to pipe

by liverpole (Monsignor)
on Sep 19, 2005 at 13:07 UTC ( #493147=note: print w/replies, xml ) Need Help??


in reply to Redirecting stdout/stderr to pipe

Can you provide some of the code you've tried?  (If it's very large, try carving it down to the salient functionality).  The purpose of supplying this information is threefold -- first, it shows what you've tried or haven't tried; second, you may have a bug, or missed some subtle point which someone else can identify, and third, it gives those who might respond a starting point for thinking about a solution.

Replies are listed 'Best First'.
Re^2: Redirecting stdout/stderr to pipe
by 0xbeef (Hermit) on Sep 19, 2005 at 14:57 UTC
    Ok, here is the code snippet. In a perl nutshell, the parent forks a child which does the actual o/s command, and the parent continues to monitor the child's duration and output size.

    The child will redirect its output to the pipes and exec(). The parent _needs_ to acquire the child's stdout and stderr as fast as possible, and be able to handle (kill) a child running for longer than X time or larger than Y size.

    pipe READOUT,WRITEOUT; pipe READERR,WRITEERR; $g_pid = fork(); if ( $g_pid < 0 ) { # Error die "Error: fork failed with error $g_pid: $!."; $rc = 1; } elsif ( $g_pid == 0 ) { # Child close(READOUT); close(READERR); close(STDOUT); open(STDOUT,">&WRITEOUT"); close(STDERR); open(STDERR,">&WRITEERR"); close(STDIN); open(STDIN,"</dev/null"); exec($$cmdref); exit(1); } else { # Parent $g_did_run++; $g_pids{$g_pid} = 1; close(WRITEOUT); close(WRITEERR); if ( $g_timeout > 0 ) { $g_stop = 0; alarm $g_timeout; } my $r_in = ""; my $w_in = ""; vec($r_in,fileno(READOUT),1) = 1; vec($r_in,fileno(READERR),1) = 1; vec($w_in,fileno(STDOUT),1) = 1; my $e_in = $r_in | $w_in; my ($r_out,$w_out,$e_out); my $cnt=0; my $eof_e = 0; my $eof_o = 0; while (1) { my ($nfound,$timeleft) = select($r_out=$r_in,undef,$e_out=$e_ +in,1); prog_log(20,sprintf("run_cmd: select returned time [%d] found + [$nfound] timeleft [$timeleft] r_out [%s] r_err [%s] e_out [%s] e_er +r [%s]\n", time, vec($r_out,fileno(READOUT),1)?'y':'n', vec($r_out,fileno(READERR),1)?'y':'n', vec($e_out,fileno(READOUT),1)?'y':'n', vec($e_out,fileno(READERR),1)?'y':'n')); if ( vec($r_out,fileno(READERR),1) and !vec($e_out,fileno(REA +DERR),1) ) { if ( eof(READERR) ) { $eof_e = 1; } else { my $line = <READERR>; chomp $line; push @$errref, $line; } } if ( vec($r_out,fileno(READOUT),1) and ! vec($e_out,fileno(RE +ADOUT),1) ) { if ( eof(READOUT) ) { $eof_o = 1; } else { my $line = <READOUT>; chomp $line; push @$outref, $line; } } last if ( $eof_e and $eof_o ); last if ( $g_stop ); } if ( $g_stop ) { # Indicator for select loop to break $rc = 2; } else { my $loglvl = 5; my $t_pid = waitpid($g_pid,0); if ( $t_pid < 0 ) { $rc = 3; } elsif ( $t_pid == 0 ) { # Process no terminated yet! $loglvl = 1; $rc = 4; } elsif ( $t_pid == $g_pid ) { $rc = $?; } else { # Not possible! $loglvl = 1; $rc = 5; } close(READOUT); close(READERR); delete $g_pids{$g_pid}; prog_log($loglvl,"run_cmd: waitpid($g_pid) returned $t_pid - +rc $rc."); }

    Thanks in advance!
    -0xbeef

      Minor nit-pick that probably doesn't answer your immediate problem: "fork()" does not return a negative number; failure is indicated by returning undef. So your initial "if" condition should be:
      if ( ! defined( $g_pid ))
      Apart from that, you seem to be using variables with global scope for flow-control, and you didn't show how/whether these were initialized ($g_stop, $g_timeout). So it's hard to guess whether it's a problem that $g_stop is never assigned a value within the "while(1)" loop. Also, you didn't include whatever code you have (if any) that actually handles the event generated by "alarm()". Could that be relevant?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://493147]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2022-10-01 14:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (126 votes). Check out past polls.

    Notices?