in reply to Re: Re: Re: Re: Passing function to a function using \&<function name> method
in thread Passing function to a function using \&<function name> method

Do you know how I can find out more about the timeout not working when I use the `<system command>` method?

You might want to look at your local (ActiveState?) perl documentation about the alarm function. Perhaps it's not implemented, or partially implemented? Or Google. Don't know what else to tell you.

Do you know what makes this method playing with fire?

Using symbolic references is generally considered a bit risky, unless you really know what you are doing, because (among other reasons) you can cause some very hard to find bugs when you start using them. Do a Super Search for 'symbolic references' (or 'refs', etc.) to find out what other Monks have to say about them. Here is a recent thread about them, to get you started: variables names used to define variables. Basically, they can be a handy feature, but only if you're careful, and there is frequently a better way to do things.

--
edan (formerly known as 3dan)

  • Comment on Re: Re: Re: Re: Re: Passing function to a function using \&<function name> method

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Passing function to a function using \&<function name> method
by rich_d_thomas (Sexton) on Feb 22, 2004 at 12:21 UTC
    Hi edan,

    Thanks for this information, it is very useful.

    What I have realised is that I would like to take my system call functionality further.

    At the moment, the way I have coded it is that the PERL script can gain control back when it has launched an external program/command or script with the system(<command>) or `<command>` method in the event of a timeout.

    What I would like to do now is if the timeout is reached, I kill off the process that was launched.

    I realised that I would need the PID and am not sure if it would be available from these methods. If the PID is not available from the above methods, what other method can I use to kill off an external program/command or script that PERL has launched once a timeout has reached? Would it be something like a spawn method or something like that?

    If there is a Unix only solution to this, then I would still be interested. I mainly to initial testing on Windows, then move onto Red Hat Linux for proper testing and implementation.

    Thanks,

    Richard Thomas.

      You'll probably want to use fork/exec for this. You'll probably find the perlipc pod useful. Here's a small, very lightly tested example to get you going. Good luck!

      #!/usr/bin/perl -l use strict; use warnings; spawn(5, "/tmp/cmd.pl"); sub spawn { my ($timeout, @cmd) = @_; defined( my $child_pid = fork ) or die "fork: $!"; if ($child_pid) { # parent eval { local $SIG{ALRM} = sub { timeout($child_pid); }; alarm $timeout; waitpid $child_pid, 0; alarm 0; }; if ($@) { print "oops: $@"; } } else { # child exec @cmd or die "exec: $!"; } } sub timeout { my ($pid) = @_; kill 'TERM' => $pid; waitpid $pid, 0; die "reaped $pid\n"; }
      --
      edan (formerly known as 3dan)

        Hi edan,

        Thanks very much for this example code, I have taken it, adapted it a bit and it works exactly how I wanted.

        Thanks again,

        Richard Thomas.
        Hi edan,

        There is just one bit left of what I am trying to do.

        I would like to log the output of the command/program that exec is running.

        I have tried to do this using the >> redirection method as follows:

        $COMMANDLOG is a parameter to turn command logging off or on.
        $LOGNAME is the filename of the file to log to
        if ($COMMANDLOG eq "yes"){ my $LOGTEXT=sprintf("\$%s\n",$cmd); log_list($LOGTEXT); $cmd=sprintf("%s >> %s",$cmd,$LOGNAME); } exec($cmd) or die "exec: $!";
        What happens is that there are two processes running from the exec line and the kill will only kill of the parent of the two processes.

        If command logging is turned off, then there is only one process from the exec line.

        Please could yoe let me know what the best thing to do about this is.

        Thank you.

        Richard Thomas.