[EMAIL PROTECTED] wrote:

Thanks for replying zsdc. The $1,$2 thing makes perfect sense now.

As for the fork/exec thing, those pages are a little over my head.  I
don't understandhow process signals and pipes work.

The fork concept can be quite confusing at first, but it is actually quite simple, once you get used to it. Check out the output of this little program:


  #!/usr/bin/perl -w
  print "START\n";
  fork;
  print "END\n";
  sleep 1;

It prints:

START
END
END

"END" is printed twice because after the fork there are two processes doing exactly the same. sleep 1 is also called twice but it results in sleeping only 1 second, not 2 seconds, because both processes sleep at the same time. I think it nicely shows what fork() basically does.

If the fork were the first statement then the program would behave like it was always being run twice simultaneously. You can add "fork;" at the beginning of some simple program to see what I mean.

Now, if you want both incarnations of your program to know which one is which, you can check the value returned by the fork() function. The parent process gets the PID of the child, while the child gets 0. If fork returns undef it means that it couldn't fork at all.

The function exec() runs a command, just like system(), but it never returns, so you can use fork() and then have the child exec() another program, without the parent waiting for the child process to finish,
which is more or less equivalent to just using:


system 'some-program &';

in your code, but unfortunately it's not enough. More on that below.

Really, all I want the perl script to do is the equivalent of typing $myApp."
".$myOptions at the command line, sending its output to STDOUT.  This
script readsin all input files passed to it, determines which executable applies to
each, andlaunches that executable with that file as a parameter.  It may need to
launch 5 or 6processes, but I want it to gracefully exit when it's done launching and
not wait tillthose processes finish.  Does that make sense?  Is that even possible?

It is possible and it makes perfect sense, but it is not simple. First of all, you could run your processes with:


system 'other-program &';

and unlike:

system 'other-program';

with '&' your program won't wait for the other-program to finish, but the other-program process will die when your program (the parent process) finishes.

Of course you want your program to finish without killing the child processes in the process (pun definitely intended) and for that you need your child processes to create new sessions with setsid().

You can take a look at Proc::Daemon module on CPAN, but it's not exactly what you need, mostly because it redirects STDOUT to /dev/null, while you want your processes to write to STDOUT (by the way, are you sure about that? it can result in a total mess printed on your terminal) but still you may want to read its source to see how it works:
http://search.cpan.org/src/EHOOD/Proc-Daemon-0.03/Daemon.pm


Try writing a subroutine like this and use it instead of system() to run your processes:

  use POSIX 'setsid';
  sub forkrun ($) {
      my $cmd = pop;
      defined(my $pid = fork) or die "$0: fork: $!\n";
      unless ($pid) {
          setsid or die "$0: setsid: $!\n";
          exec $cmd;
      }
      return $pid;
  }

If you don't like the garbage printed on the terminal, then insert this lines just before the call to exec:

  open STDIN,  '<', '/dev/null';
  open STDOUT, '>', '/dev/null';
  open STDERR, '>', '/dev/null';

Is that what you need?

--
ZSDC Perl and Systems Security Consulting



--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to