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

All, I'm having some problems with a piece of code I wrote (attached below). I'm doing a system call which is executing a script and the script either returns 0 or 1 (running as a standalone script it works fine) but within a system call it's returning -1 (whether or not the script passed and/or failed). From what I read, -1 means the system called failed, but I know the script is being executing properly because I can see the output from the script. Thoughts ?
while (($new_sock, $c_addr) = $sock->accept()) { die "Can't fork: $!" unless defined ($pid = fork()); if ( $pid == 0 ) { # Child code $sock->close; my ($client_port, $c_ip) = sockaddr_in($c_addr); my $client_ipnum = inet_ntoa($c_ip); my $client_host = gethostbyaddr($c_ip, AF_INET); print "CHILD CODE [cpid::$$]: Connection from: $client_host [$cl +ient_ipnum ", $new_sock->peerport, "] \n\n"; while (defined($buf = <$new_sock>) ) { if ($buf =~ /^EXECUTE:(.*)/ ) { print $1, "\n"; system("/msg/spgear/tools/bin/perl $1") || die "Could not +run program: $1 -- $!\n"; my $rtn = $?; print $new_sock "RETURN CODE: $rtn", "\n"; } else { print "INVALID SYNTAX\n"; print $new_sock "INVALID SYNTAX\n"; } } exit 0; } else { # Parent code $new_sock->close; print "\nPARENT CODE [ppid::$$ cpid:$pid]\n"; } }
** Update ** Actually, one thing I left out was I am using $SIG{CHLD} at the top of my code so all children get cleaned up properly. I believe this could be what is causing the bad return code ??? Also, I read the comments about using the regexp in the system call and, while I do understand your statement, once this code is integrated into the rest of my code, there is no way the client can pass in a "bad comment" (like you suggested). Without going into details, the client will only have a set up known "scripts" which will be executed. But thanks for your feedback, it is definately something I will keep in mind.

Replies are listed 'Best First'.
Re: Wrong return code after a system call
by antirice (Priest) on Oct 23, 2003 at 20:47 UTC

    system returns the exit code of the executed system call. Since your system call is returning -1, a truth value, your code thinks everything went ok. Believe it or not, the only way your program would die is if the call executed properly and the called program exited with a 0 status (since default successful exit status is 0). Something like the following would probably be what you want:

    system("/msg/spgear/tools/bin/perl $1"); die "Could not run program: $1 -- $!$/" if $? == -1;

    That aside, you need to REALLY reconsider your regex pulling out your execute call. Someone could quite easily pass "EXECUTE:-e'0';rm -rf /" to your program. See the problem?

    Hope this helps.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

      That aside, you need to REALLY reconsider your regex pulling out your execute call. Someone could quite easily pass "EXECUTE:-e'0';rm -rf /" to your program. See the problem?
      Yes, I agree, he should most definetly sidestep the issue entirely (perldoc -f system and perldoc -f exec cover the details).

      MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
      I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
      ** The third rule of perl club is a statement of fact: pod is sexy.