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

Dear all,

I have an external process that I want no control over once it's started running. Looking at exec() it sounds like the parent process actual exits once it's started exec(), is this true?

My problem lies in the fact that I have a web application that awaits a return value before loading a new page. The return value in itself is meaningless, but because it's XML-RPC, a return nevertheless is requested, especially as I'd like to see if the XML-RPC is working.

Thus I have this sub-function using a SOAP::Lite XML-RPC daemon:

sub go{ shift if UNIVERSAL::isa($_[0] => __PACKAGE__); FORK: { if ($child = fork) { }elsif (defined $child) { my $exec = "/usr/local/bin/monster -i$id $filePath$file &"; qx/$exec/; }elsif ($! == EAGAIN) { sleep 5; redo FORK; }else { die "Can't fork: $!\n"; } } return 0; #just to say 'done'. }
Thanks

Sam Seaver

Replies are listed 'Best First'.
Re: Running external process WHILE exiting/returning
by pzbagel (Chaplain) on Jun 05, 2003 at 20:14 UTC

    I think you are mixing exec and fork terminology. First off, in your question you talk about the "parent process" of the exec. That's not how it works. When you fork, a child process is created which is identical to the parent. It is upto your script, through evaluating the return value of the fork(0 for child, pid of child for parent, and undef for failure), to figure out which you are and act according. In the case of exec, the process which performs the exec literally gets overwritten by the program specified in the exec. It comes to a dead stop , it does not continue to run, it will not run "exit" or "return" because it ceases to exist.

    Now onto your code. In your code it is a little clearer that you are trying to do a fork and exec. You need to split up your code a little differently:

    FORK: { $child=fork; if(defined($child)) { if($child = 0) { my $exec = "/usr/local/bin/monster -i$id $filePath$file &"; qx/$exec/; } } elsif ($! == EAGAIN) { sleep 5; redo FORK; } else { die "Can't fork: $!\n"; } } return 0;

    Notice that if $child is defined you check if you are in fact the child process and then you do the exec. If you happen to be the parent process you drop through the if and end up at the return statement, although you could put that in as an else clause of the if ($child=0) statement.

    Check out perlipc for more info about fork and exec.

    HTH

    Addendum - I noticed you are using the qx() quoting characters. These are equivalent to backticks(``) in perl and do not do the same thing as exec. You should probably change qx to an exec call instead to get it to do what you want.

      Thanks!

      I was confused about fork I have to admit, and I believed that if I did this:

      if($child = fork){ return 0; }elsif(defined $child){...}
      then the child process would never be reached.

      Your solution worked, but i can't help wondering, seeing how I'm a bit dumb with forks, would the above code work in the same way?

      BTW, not to be picky, but you missed an equal sign in

      if($child = 0){
      :-P

      cheers

      S

Re: Running external process WHILE exiting/returning
by Missing Words (Scribe) on Jun 05, 2003 at 19:26 UTC

    The exec fucntion does exit perl and executes the external command, never comming back to perl. If you need to exectute a command, evalute its return value, and then go back to perl then you probably want to use the system function:

    see "perldoc -f system" for the details