http://www.perlmonks.org?node_id=232140


in reply to Re: Ways and means of killing Win32 processes
in thread Ways and means of killing Win32 processes

A few clarifications

NORMALLY: Smedge2 --executes--> Render.exe MY-WRAPPED VERSION: Smedge2 --executes--> RenderWrap.pl --executes--> Render.exe

The problem being that when smedge2 decides that it should abort a job, it kills the process it executed, this would be fine if there was only one process (NORMALLY) , but MY-WRAPPED has smedge executing the wrapper, sadly when smedge kills 'RenderWrap.pl', the children of 'RenderWrap.pl' do not die. Moreover, no amount of signal trapping will catch the kill issued by smedge. Indeed it seems very similar to the Taskmanager->EndProcess.

Now the code, some of which is show below , does work when given a SIGINT from the commandline - ie
C:\wrappers\RenderWrap.pl -some args * - output etc * ^C In cleanup.
And so the child process is killed.
#!/usr/bin/perl -w $|++; open ( LOG , '>>c:\temp\wrapper.log' ); # debug print LOG "#"x40, $/; print LOG "PID : $$" , $/; print LOG join (',' , @ARGV) , $/; my $mayabatch = 'mayabatch'; $SIG{TERM}=\&cleanup; $SIG{KILL}=\&cleanup; $SIG{INT}=\&cleanup; $SIG{ABRT}=\&cleanup; $SIG{BREAK}=\&cleanup; $SIG{STOP}=\&cleanup; $SIG{QUIT}=\&cleanup; my %o; $o{-file} = shift @ARGV; my @args = @ARGV; while ( @args ) { my $arg = shift @args; if ($arg =~ /-ses/) { $o{-s} = shift @args; $o{-e} = shift @args; $o{-b} = shift @args; } elsif ( $arg =~ /^-/ ) { $o{$arg}=shift @args; } else { warn "Unhandled arg $arg \n"; } } # blah blah, operations on args to wrap # neatly. # my $child = open ( RENDER , "$command |" ) or die "Screaming $!$?\n"; while (<RENDER>) { print }; print "Child exit status was $?" , $/; exit $?; sub cleanup { warn "In cleanup. \n"; kill "HUP" , $child; }

I can't believe it's not psellchecked

Replies are listed 'Best First'.
Re: Re: Re: Ways and means of killing Win32 processes
by BrowserUk (Patriarch) on Feb 03, 2003 at 06:44 UTC

    I did think that you might be able to get around this problem by forking the wrapper process into two and then have the parent process exec the wrapped executable. The thought was that the exec'd executable would run under the original process id, and the child process would know that id and so, be able to monitor it. Smedge would kill the parent and leave the child alone to do its clean-up job.

    Unfortunately this doesn't work (under AS anyway). Firstly the exec'd process runs under a new pid not that of the process it replaces. Secondly, the pseudo nature of forked processes under AS, means that when the exec occurs the parent dies, and it takes the child process (thread in reality) with it.

    Reading perlfork I came across this

    exec() Calling exec() within a pseudo-process actually spawns the requested e +xecutable in a separate process and waits for it to complete before e +xiting with the same exit status as that process. This means that the + process ID reported within the running executable will be different +from what the earlier Perl fork() might have returned. Similarly, any + process manipulation functions applied to the ID returned by fork() +will affect the waiting pseudo-process that called exec(), not the re +al process it is waiting for after the exec().

    Which if I have interpreted it correctly, should mean that you could do something like.

    1. Smedge starts wrapper.pl
    2. wrapper.pl uses system to start a second copy of the script (in another instance of perl) and passes the process ID of the first to it via the command line. The second copy sits and monitor the presence of the first using some mechanism perhaps kill with an arg of 0 (zero) to check of the first is still in existance or $proc = Win32::Process::Open($orig_pid) to get a handle to the original process and $proc->wait(); to wait for it's demise.
    3. The first copy of wrapper.pl then execs the wrapped executable and, if the above description is correct, the original process should then sit and wait until the exec'd executable dies or is otherwise terminated. This would be monitored by the second copy.

    Not a 'nice' mechanism, but it might work.

    The reason for my doubt of the veracity of the above statement from perlfork is that I was unable, in a quick test, to verify it. However, I have come to trust the docs and doubt myself in these situations until I have proven (or had proved) otherwise.


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.