E-Bitch has asked for the wisdom of the Perl Monks concerning the following question:

So, after a brief respite, I've returned, refreshed.

And, unfortunately, as usual, with problems:

I have this program, sort of a wrapper, if you will, written in Perl, that scans a directory for PostScript files, and for each one found, asks the user weather or not to convert it to a .PDF file, using the underlying unix / adobe distill command. Well, our version of distill is waaaay out of date, and certain PostScript level files cause distill to hang (I believe level 1, but for some reason, 2 & || 3 dont). Is there a way, other than having the user Control-C out of the program, change the name of the file, and rerun the program, to detect how long the distill command has taken, or if it has a problem (there is no error produced, just a hanging sensation.)?

If there is, I'd like to implement it, and halt the distill process, inform the user of the error, and go on about our merry business...



Thanks in advance,

E-Bitch
_________________________________________
E-Bitch
Tempora Mutantur Nos et Mutamur in Illis
"The Times are Changed Even as We are Changed in Them"

Replies are listed 'Best First'.
Re: Perl Timers and command-line processes
by grep (Monsignor) on Jan 17, 2002 at 04:11 UTC
    Since you are on *nix, I would recommend alarm and $SIG{ALRM}.

    Straight from perldoc:
    eval { local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required alarm $timeout; $nread = sysread SOCKET, $buffer, $size; alarm 0; };

    You can stick your PDF stuff in the sysread line.

    CAVEAT: This is not portable to M$ Win32

    grep
    grep> cd pub
    grep> more beer
Re: Perl Timers and command-line processes
by kschwab (Vicar) on Jan 17, 2002 at 04:10 UTC
    Something like the following might work (untested, caveat emptor):
    #!/usr/bin/perl -w use strict; use POSIX qw(:sys_wait_h); my $TIMEOUT=180;# or whatever my $start=time; if (my $pid = fork) { #parent while (1) { if (waitpid($pid,WNOHANG) == -1) { # child is done exit; } if ( time > ($start + $TIMEOUT)) { # time has expired, kill the child # this is probably too simplistic, # as the child could ignore the SIGTERM kill(15,$pid); exit; } sleep(1);# avoid the tight loop } } else { # child exec('/some/program'); }
Re: Perl Timers and command-line processes (boo)
by boo_radley (Parson) on Jan 17, 2002 at 03:58 UTC
    depending on your system, you can use Win32::Process and arbitrarily kill things after a given period of time. Whether or not this eats memory is up for debate.
    If you're on the other type of system, some magic with ps should get you started.
Re: Perl Timers and command-line processes
by perrin (Chancellor) on Jan 17, 2002 at 04:13 UTC
    You can use an alarm for this.