Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

open3() usage, need assist

Status
Not open for further replies.

1yura1

Programmer
Feb 7, 2003
36
0
0
UA
Hello,

Does anybody can assist me with open3()?
It is require correct STDIN, STDOUT, STDERR, exit code, child process's manipulation, correct zombies cleanup, disable child(s) buzz

Thanks in advance for your time and help.

Best Regards
 
open3() is not a perl function, do you have a perl question or an operating system question?

- Kevin, perl coder unexceptional!
 
Hello,

Yes, I'm using IPC::Open3.
I wrote such code to be able to run different commands, pass them need data into STDIN, and store their STDOUT and STDERR. and exam various exit codes:

sub _run {
my $cmd = shift; # CMD to execute as plain string
my $input = shift; # CMD STDIN data

$cmd_timeout = 1000; # Default commant exucution timeuot

my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd);
my($rc, $exit_value, $signal_num, $dumped_core, $waitpid);
$exit_value = -1;
$signal_num = 0;

print CMD_IN $input if( defined($input) );
close(CMD_IN);

if( $pid > 0 ) {
#wait before finished
my $patience = time() + $twait;
my ($child);
$? = 0;
# Wait up to the timeout
# And clean off the zombie
do {
$child = waitpid(-1, WNOHANG);
$rc = $?;
$exit_value = WEXITSTATUS($rc);
$signal_num = WIFSIGNALED($rc);
select(undef, undef, undef, 0.1);
} while time() < $patience && $child != $pid;
if( $exit_value == -1 ) {
#timeout - kill task and set error flag.
warn "Killing $pid because off wait timeout\n";
kill("KILL", $pid);
}
}
# get zombies
while(waitpid(-1, WNOHANG)>0) {
;
}
my $selector = IO::Select->new();

# collect STDOUT and STDERR
$selector->add(*CMD_ERR, *CMD_OUT);
my @stdout = ();
my @stderr = ();
while(my @ready = $selector->can_read()){
foreach my $fh (@ready){
if(fileno($fh) == fileno(CMD_ERR)){
push(@stderr, <CMD_ERR>);
}
else{
push(@stdout, <CMD_OUT>);
}
$selector->remove($fh) if eof($fh)
}
}

close(CMD_OUT);
close(CMD_ERR);

if( $pid <= 0 || $exit_value != 0 ){
warn "\nCMD: $cmd\nSTDERR: @stderr\nSTDOUT: @stdout\nSTATUS: $rc\nEXITSTATUS: $exit_value\nSIGNALED: $signal_num\nPID: $pid\n";
}
return($exit_value, \@stdout, \@stderr);
}

The code failes to execute the command like:
rpm -q quota

Am I doing something wrong?

Thanks.
 
There's a lot of code in there. When you say that it fails, what do you mean? The command doesn't execute at all? You can't write to/read from its input/output streams? The fork fails? You'll have to give more details about what's happening.
 
Hello,

No the command axecutes fine, but error exit code (-1 or 255) is returned... But there is no reaseon for such ending...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top