Front page | perl.perl5.porters |
Postings from April 2007
RE: [PATCH] Fix kill(0, $pid) on Windows
From: Jan Dubois
April 19, 2007 10:04
RE: [PATCH] Fix kill(0, $pid) on Windows
Message ID: 019601c782a4$bb819e70$3284db50$@com
On Thu, 19 Apr 2007, Steve Hay wrote:
> Jan Dubois wrote:
> I get the same result as you using your test program, but I still have
> two problems or misunderstandings.
Sorry about that, my explanations have been somewhat incomplete.
Note that Perl really only supports 3 different signals on Windows when
you send them to an external process and not a forked pseudo-process:
SIGINT, SIGBREAK and SIGKILL. SIGTERM is mapped to SIGBREAK, and I
think everything else is mapped to SIGKILL.
SIGKILL is implemented by calling TerminateProcess().
SIGINT and SIGBREAK are sent using GenerateConsoleControlEvent().
This later function is restricted to signaling processes in the same
console as the caller.
win32/win32.c(mykill) implements the kill(-$sig, $pid) functionality
internally by walking the parent/child relations in the process tree.
It does not know about process groups. It does not implement the
$pid==0 case specifically.
Therefore kill($sig,0) will not do anything for signals except SIGINT
and SIGBREAK (and signals mapped to them, like SIGTERM).
GenerateConsoleCtrlEvent() itself implements the $pid==0 case by
sending the signal to all processes running in the same console as
> Firstly, what I was trying (and which still doesn't work) is to start a
> perl.exe in one command prompt and note its PID, e.g.
> >perl -le "print $$; sleep 60"
> and then try to kill it using a perl.exe in another command prompt:
> perl -e "kill 15, 2508"
> I expected that to kill the first perl.exe (PID 2508), but it doesn't.
> Trying to kill the cmd.exe parent of PID 2508 instead (like your program
> does) also doesn't work.
It doesn't work because it is running in a different console. You need
to start the process with system(1, ...) or Win32::Process to be able
to send it SIGINT or SIGBREAK signals. Note that SIGINT doesn't work
either unless the child process re-enables Ctrl-C processing because
Perl uses CREATE_NEW_CONSOLE_GROUP in the CreateProcess() call.
> Of course, your program is different in that the perl.exe (and its
> parent cmd.exe) being killed is a child of the perl.exe that is trying
> to kill it, whereas I'm playing with two separate process trees. Is this
> expected behaviour?
It is not the parent/child relationship, but the fact that they are running
in the same console. I did not expect this limitation, but I do understand
> Secondly, if I change the "kill 15, $pid" in your program to "kill 15,
> undef" instead then I was expecting the whole process tree to be killed,
> including the perl.exe that is issuing the kill(), as per your comment
> quoted at the very top of this email.
> However, I still find that only the cmd.exe and its child perl.exe get
> killed, and the top-level perl.exe that issued the kill() hangs around
> for another 5 seconds until it says "done" and exits. This doesn't seem
> to be what you suggested would happen, unless I've misunderstood you.
This behavior is implemented by GenerateConsoleCtrlEvent(). I would have
expected that it would also generate the event in the calling process,
but it looks like it doesn't.
I'm still at a loss about what we should be doing about all this. Should
we document the whole situation (in perlport, with a link from perlfunc?).
Or should we undo the kill(-$sig, $pid) functionality and move it into
I have not been able to find any documentation on how we could determine
the processes belonging to a console-specific process group.
Starting with Windows XP there is GetConsoleProcessList().
I haven't tried it, but from the documentation it looks like it will provide
a list of all processes attached to the current console. It doesn't give
us a list of processes inside our own console process group. We could
use this function to implement kill(9, 0) to work on the same set of
processes as kill(15, 0). I guess this might be useful sometimes, but
muddies the situation even further.