From owner-ntemacs-users@trout Thu May 8 07:38:01 1997 X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil] [nil "Thu" " 8" "May" "1997" "14:58:08" "+0100" "Andrew Innes" "andrewi@harlequin.co.uk" nil "90" "Re: sub-processes and sending Ctrl-C vs. Ctrl-Break" "^From:" nil nil "5" nil nil nil nil] nil) Received: from joker.cs.washington.edu (joker.cs.washington.edu [128.95.1.42]) by june.cs.washington.edu (8.8.5+CS/7.2ju) with SMTP id HAA07710 for ; Thu, 8 May 1997 07:38:01 -0700 Received: from trout.cs.washington.edu (trout.cs.washington.edu [128.95.1.178]) by joker.cs.washington.edu (8.6.12/7.2ws+) with ESMTP id HAA39113 for ; Thu, 8 May 1997 07:38:00 -0700 Received: from june.cs.washington.edu (june.cs.washington.edu [128.95.1.4]) by trout.cs.washington.edu (8.8.5+CS/7.2ws+) with ESMTP id GAA10889 for ; Thu, 8 May 1997 06:58:54 -0700 (PDT) Received: from holly.cam.harlequin.co.uk (holly.cam.harlequin.co.uk [193.128.4.58]) by june.cs.washington.edu (8.8.5+CS/7.2ju) with ESMTP id GAA05288 for ; Thu, 8 May 1997 06:58:51 -0700 Received: from propos.long.harlequin.co.uk (propos.long.harlequin.co.uk [193.128.93.50]) by holly.cam.harlequin.co.uk (8.8.4/8.7.3) with ESMTP id OAA02400; Thu, 8 May 1997 14:58:40 +0100 (BST) Received: from elan.long.harlequin.co.uk (elan.long.harlequin.co.uk [193.128.93.78]) by propos.long.harlequin.co.uk (8.8.4/8.6.12) with SMTP id OAA24534; Thu, 8 May 1997 14:58:08 +0100 (BST) Message-Id: <199705081358.OAA24534@propos.long.harlequin.co.uk> In-reply-to: <33717540.132F@webspan.net> (message from Todd Sabin on Thu, 08 May 1997 02:40:00 -0400) From: Andrew Innes To: tas@webspan.net CC: ntemacs-users@cs.washington.edu Subject: Re: sub-processes and sending Ctrl-C vs. Ctrl-Break Date: Thu, 8 May 1997 14:58:08 +0100 (BST) On Thu, 08 May 1997 02:40:00 -0400, Todd Sabin said: >So I looked into this a little today; specifically trying to figure out >why Ctrl-Break gets through, but Ctrl-C doesn't. I tested by creating >a subshell (MKS sh.exe), and running cat.exe (also MKS) with no >parameters. cat tried to read from stdin, and just waited. I then >sent C-c C-c. Here's what I was able to determine: > >1. In general the calling sequence goes something like this: > o Emacs calls GenerateConsoleCtrlEvent () > o this goes through to CsrSS and is dispatched to a routine named > SrvGenerateConsoleCtrlEvent (in winsrv.dll) > o some more stuff happens here which determines which processes > are to receive the event > o for each process that should receive the event > o a thread is created in the target process which eventually > makes its way to a routine named CtrlRoutine (in kernel32) > o CtrlRoutine does the work of walking the CtrlHandlerList > and invoking the registered handlers. > o the created thread exits > >2. When sending a Ctrl-Break, everything happens as described above and > all the child processes get the Event. > >3. When sending a Ctrl-C, everything happens _almost_ as described above, > except that when the processing reaches CtrlRoutine, a check is made > whether the event is a Ctrl-C [actually the check is always made; > it's just true now], and if it is, then a test is made against a flag > in the process's parameters memory block [see below]. If this flag > is set, then the event is just ignored and CtrlRoutine returns > without running down the CtrlHandlerList. If the flag is not set, it > proceeds as with Ctrl-Break. > >4. What I'm calling the process parameter memory block is the block of > memory starting at 0x20000. Of course, the real way the address is found > is with > mov eax, dword ptr fs:[00000018h] ; get the teb > mov eax, dword ptr [eax+30h] ; get the peb > mov eax, dword ptr [eax+10h] ; get the thing I'm talking about > but it's always at 0x20000, as fas as I can tell. Anyway, the flag > is a dword at offset 14h (or 0x20014). If this flag is 0, then the Ctrl-C > will get through, otherwise it won't. > >5. The flag at 0x20014 gets set during CreateProcess based on whether the > CREATE_NEW_PROCESS_GROUP flag was passed. I.e., if the flag was > passed, then the flag is set to one. If the flag is not set, then > the 0x20014 flag _might_ be inherited by subprocesses; I'm not sure > about this. I do know that my MKS sh.exe had its flag set, and it > was creating subprocesses which also had it set, but I don't know if > sh.exe was passing the CREATE_NEW_PROCESS_GROUP flag or not when it > was calling CreateProcess. This analysis corresponds to the documentation of CreateProcess and SetConsoleCtrlHandler. That is, the "Ignore_Ctrl_C" flag (as set by SetConsoleCtrlHandler) is inherited by child processes, unless CREATE_NEW_PROCESS_GROUP is specified in which case the flag is forced on in the child process. In the release version of 19.34, Emacs uses the CREATE_NEW_PROCESS_GROUP flag, and consequently sends a CTRL_BREAK_EVENT instead of CTRL_C_EVENT to fake SIGINT. This normally works under NT, but has no effect under Windows 95 (at least when using command.com as the shell program). In the updated version of 19.34 on the ftp site (known informally as 19.34.2), I changed things so that Emacs now uses the CREATE_NEW_CONSOLE flag instead of CREATE_NEW_PROCESS_GROUP. Emacs leaves its own Ignore_Ctrl_C flag turned off (it decides at runtime whether to ignore such events) so child processes will by default receive Ctrl-C events as well. To fake SIGINT, Emacs now has to find the window handle of the console allocated for the child process and use keybd_event to emulate the effect of the user actually typing Ctrl-C. This works on both NT and Windows 95. To fake SIGKILL, Emacs now posts a WM_CLOSE message to the console window, which on NT causes CTRL_CLOSE_EVENT to be sent to all applications sharing that console, resulting in a clean orderly shutdown of the whole process group. This is an improvement on the original method of calling TerminateProcess on the child (which doesn't kill grandchildren and doesn't allow the child to shutdown cleanly). Unfortunately Windows 95 doesn't fully implement the CTRL_CLOSE_EVENT handling for console programs (instead it provides a completely different mechanism for DOS programs which roughly corresponds to this), so on Win95 the faked SIGKILL is effectively ignored. I've done some testing though, and it looks like it will be possible to arrange for WM_CLOSE to cause a reasonably orderly shutdown by using helper programs to load a DOS TSR program in the child's VM. AndrewI