Re: Ctrl-Break handler?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Ctrl-Break handler?

Howard Chu
following up to a 3 year old thread...
http://sourceforge.net/mailarchive/message.php?msg_id=4112786

Here's a patch that basically does what I want. It works for my
programs, anyway. What it does:
   In spawn, if we're exec'ing a native binary, create the process with
a new process group, and record the group ID (which is the same as the
process ID).
   In sig_handle(), if we receive a terminating signal and have an
exec'd process and its group ID, generate a Ctrl-Break event for that
group. Keeping the process in its own group limits which processes get
affected.

There's a downside of course: if the process creates subprocesses of its
own and doesn't also put them in separate process groups, they will all
be affected as well. Too bad there's no clean ways to control just a
single process.

--
  -- Howard Chu
  Chief Architect, Symas Corp.  http://www.symas.com
  Director, Highland Sun        http://highlandsun.com/hyc
  OpenLDAP Core Team            http://www.openldap.org/project/


Index: exceptions.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/exceptions.cc,v
retrieving revision 1.5
diff -u -r1.5 exceptions.cc
--- exceptions.cc 13 Jun 2003 18:38:42 -0000 1.5
+++ exceptions.cc 27 Dec 2006 22:09:05 -0000
@@ -958,6 +958,7 @@
 sig_handle (int sig)
 {
   int rc = 0;
+  extern DWORD dExecedId;
 
   sigproc_printf ("signal %d", sig);
 
@@ -1053,6 +1054,10 @@
       if (!try_to_debug ())
  stackdump (c.Ebp, 1, 1);
       sig |= 0x80;
+    } else if ( sig != SIGKILL && dExecedId )
+    {
+      GenerateConsoleCtrlEvent( 1, dExecedId );
+      goto done;
     }
   sigproc_printf ("signal %d, about to call do_exit", sig);
   signal_exit (sig);
Index: spawn.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/spawn.cc,v
retrieving revision 1.27
diff -u -r1.27 spawn.cc
--- spawn.cc 26 Jul 2006 15:01:37 -0000 1.27
+++ spawn.cc 27 Dec 2006 22:09:05 -0000
@@ -47,6 +47,7 @@
 };
 
 HANDLE hExeced;
+DWORD dExecedId;
 
 /* Add .exe to PROG if not already present and see if that exists.
    If not, return PROG (converted from posix to win32 rules if necessary).
@@ -617,6 +618,11 @@
     flags |= DETACHED_PROCESS;
   if (mode != _P_OVERLAY)
     flags |= CREATE_SUSPENDED;
+  else if (!ismsysdep)
+    flags |= CREATE_NEW_PROCESS_GROUP;
+  /* We use a new process group for native binaries so that we can
+   * use GenerateConsoleCtrlEvent to send them terminate signals.
+   */
 
   /* Some file types (currently only sockets) need extra effort in the
      parent after CreateProcess and before copying the datastructures
@@ -795,6 +801,8 @@
  primarily for strace. */
       strace.execing = 1;
       hExeced = pi.hProcess;
+      if (!ismsysdep)
+        dExecedId = pi.dwProcessId;
       strcpy (myself->progname, real_path);
       close_all_files ();
     }

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mingw-msys mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-msys
Reply | Threaded
Open this post in threaded view
|

Re: Ctrl-Break handler?

Howard Chu
Howard Chu wrote:
> following up to a 3 year old thread...
> http://sourceforge.net/mailarchive/message.php?msg_id=4112786
>
> Here's a patch that basically does what I want.
This is an additional patch for the 2nd half of the previous thread -
shutting down the system actually generates a LOGOFF event, so that
needs to be handled as well.

--
  -- Howard Chu
  Chief Architect, Symas Corp.  http://www.symas.com
  Director, Highland Sun        http://highlandsun.com/hyc
  OpenLDAP Core Team            http://www.openldap.org/project/


Index: exceptions.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/exceptions.cc,v
retrieving revision 1.5
diff -u -r1.5 exceptions.cc
--- exceptions.cc 13 Jun 2003 18:38:42 -0000 1.5
+++ exceptions.cc 27 Dec 2006 23:44:55 -0000
@@ -901,7 +901,10 @@
 ctrl_c_handler (DWORD type)
 {
   if (type == CTRL_LOGOFF_EVENT)
-    return TRUE;
+    {
+      sig_send (NULL, SIGHUP);
+      return FALSE;
+    }
 
   /* Return FALSE to prevent an "End task" dialog box from appearing
      for each Cygwin process window that's open when the computer

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mingw-msys mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-msys
Reply | Threaded
Open this post in threaded view
|

Re: Ctrl-Break handler?

Howard Chu
Howard Chu wrote:
> Howard Chu wrote:
>> following up to a 3 year old thread...
>> http://sourceforge.net/mailarchive/message.php?msg_id=4112786
>>
>> Here's a patch that basically does what I want.
Figures. After posting that, I found this other thread...
http://sourceforge.net/mailarchive/message.php?msg_id=13570280

That patch does almost the same thing as mine. However, it goes too far
- there's nothing gained by modifying the MinGW runtime here.
Microsoft's MSVCRT already installs a handler, so that it's own signal()
function works. IMO the MinGW runtime portion of that patch should be
ignored. Also, the MSYS patch is too specific; it only handles SIGINT.
Since there's no way to tell the target process what kind of signal
came, and all we can do is tell it that we want it to terminate, it
should just act on all signals whose action resolves to "terminate."
That's what my patch does. And it works as desired, without needing to
relink any existing programs...

--
  -- Howard Chu
  Chief Architect, Symas Corp.  http://www.symas.com
  Director, Highland Sun        http://highlandsun.com/hyc
  OpenLDAP Core Team            http://www.openldap.org/project/


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mingw-msys mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-msys
Reply | Threaded
Open this post in threaded view
|

Re: Ctrl-Break handler?

Earnie Boyd
In reply to this post by Howard Chu
Quoting Howard Chu <[hidden email]>:

> following up to a 3 year old thread...
> http://sourceforge.net/mailarchive/message.php?msg_id=4112786
>
> Here's a patch that basically does what I want. It works for my
> programs, anyway. What it does:

Please submit patches to the patch tracker
http://sourceforge.net/tracker/?group_id=2435&atid=302435 and not the
list so it will not be forgotten.  And please add a ChangeLog entry at
the top of the diff file.  See the existing ChangeLog.MSYS file for
samples of what a ChangeLog entry is to look like.

Earnie Boyd
--
Please post responsibly:
* Use text posts instead of html; many list members just trash mail with html.
* Do not use multipart mime to send both text and html versions.
* Do not top post replies; post inline with the parts you are responding to.
* Trim the post replies; remove irrelevant information from the quoted
article.
* Original posters:
  ** Provide small complete examples of the problem.
  ** Provide the full command that produced errors.
  ** Provide the versions of the software used.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mingw-msys mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-msys
Reply | Threaded
Open this post in threaded view
|

Re: Ctrl-Break handler?

Howard Chu
In reply to this post by Howard Chu
Not content to leave well enough alone, here's yet another approach.
It's far uglier, and requires NT/2000/XP (I.e., no Win95/98/ME).

This code assumes that the target program has been linked with an MSVC
CRT DLL. If it can find one of these DLLs attached to the target, then
it will find the raise() entry point in the DLL, and use that to send
signals to the target. One advantage of this approach is that it will
work even if the target program doesn't use a Console.  The obvious
disadvantage is that it's pretty invasive. If there's no MSVCRT, then it
does nothing.

Food for thought. It works, but I'm not sure it was worth the effort.

--
  -- Howard Chu
  Chief Architect, Symas Corp.  http://www.symas.com
  Director, Highland Sun        http://highlandsun.com/hyc
  OpenLDAP Core Team            http://www.openldap.org/project/


Index: exceptions.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/exceptions.cc,v
retrieving revision 1.5
diff -u -r1.5 exceptions.cc
--- exceptions.cc 13 Jun 2003 18:38:42 -0000 1.5
+++ exceptions.cc 28 Dec 2006 07:45:10 -0000
@@ -901,7 +901,10 @@
 ctrl_c_handler (DWORD type)
 {
   if (type == CTRL_LOGOFF_EVENT)
-    return TRUE;
+    {
+      sig_send (NULL, SIGHUP);
+      return FALSE;
+    }
 
   /* Return FALSE to prevent an "End task" dialog box from appearing
      for each Cygwin process window that's open when the computer
@@ -958,6 +961,7 @@
 sig_handle (int sig)
 {
   int rc = 0;
+  extern char *pExecedHook;
 
   sigproc_printf ("signal %d", sig);
 
@@ -1000,6 +1004,28 @@
   OutputDebugString (sigmsg);
 #endif
 
+#ifndef SIGBREAK
+#define SIGBREAK 21
+#endif
+
+  if (pExecedHook && (sig == SIGINT || sig == SIGTERM || sig == SIGQUIT
+ || sig == SIGHUP )) {
+      extern HANDLE hExeced;
+      SIZE_T nbytes;
+      HANDLE hRemThread;
+      int rsig;
+      rsig = (sig == SIGQUIT || sig == SIGHUP) ? SIGBREAK : sig;
+      WriteProcessMemory(hExeced,pExecedHook,&rsig,sizeof(rsig),
+ &nbytes);
+      hRemThread = CreateRemoteThread(hExeced,NULL,0,
+ (LPTHREAD_START_ROUTINE)(pExecedHook+sizeof(remote_info1)), pExecedHook, 0, &nbytes);
+      if (hRemThread) {
+ WaitForSingleObject(hRemThread,INFINITE);
+        CloseHandle(hRemThread);
+        goto done;
+      }
+  }
+
   if (handler == (void *) SIG_DFL)
     {
       if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH)
Index: sigproc.h
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/sigproc.h,v
retrieving revision 1.3
diff -u -r1.3 sigproc.h
--- sigproc.h 31 Oct 2002 14:32:21 -0000 1.3
+++ sigproc.h 28 Dec 2006 07:45:10 -0000
@@ -34,6 +34,24 @@
   HANDLE thread_ev;
 } waitq;
 
+typedef HMODULE (GetModH_t)(LPCTSTR name);
+typedef FARPROC (GetProc_t)(HMODULE hmod, LPCSTR name);
+typedef int (raise_t)(int sig);
+
+typedef struct remote_info1 {
+ int sig;
+ raise_t *raise;
+} remote_info1;
+
+typedef struct remote_info {
+ int sig;
+ raise_t *raise;
+ GetModH_t *getModH;
+ GetProc_t *getProc;
+ char rname[16];
+ char names[12][16];
+} remote_info;
+
 struct sigthread
 {
   DWORD id;
Index: spawn.cc
===================================================================
RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/spawn.cc,v
retrieving revision 1.27
diff -u -r1.27 spawn.cc
--- spawn.cc 26 Jul 2006 15:01:37 -0000 1.27
+++ spawn.cc 28 Dec 2006 07:45:10 -0000
@@ -47,6 +47,7 @@
 };
 
 HANDLE hExeced;
+char *pExecedHook;
 
 /* Add .exe to PROG if not already present and see if that exists.
    If not, return PROG (converted from posix to win32 rules if necessary).
@@ -305,6 +306,76 @@
   return 1;
 }
 
+static remote_info my_rmi = {
+ 0, NULL, NULL, NULL,
+ "raise",
+ { "msvcr80.dll", "msvcr80d.dll",
+  "msvcr71.dll", "msvcr71d.dll",
+  "msvcr70.dll", "msvcr70d.dll",
+  "msvcrt.dll", "msvcrtd.dll" }
+};
+
+static DWORD
+remote_hook(remote_info1 *rmi)
+{
+ rmi->raise(rmi->sig);
+ return 0;
+}
+
+static DWORD
+remote_setup(remote_info *rmi)
+{
+ int i;
+ HMODULE hm;
+
+ for (i=0;rmi->names[i][0];i++) {
+ hm = rmi->getModH(rmi->names[i]);
+ if ( hm ) {
+ rmi->raise = (raise_t *)rmi->getProc(hm, rmi->rname);
+ if (rmi->raise)
+ break;
+ }
+ }
+ return 0;
+}
+
+static void
+kill_hook(HANDLE hProc)
+{
+  SIZE_T funcSize = (char *)kill_hook - (char *)remote_setup;
+  SIZE_T fullSize = sizeof(remote_info) + funcSize;
+  SIZE_T nbytes;
+  HMODULE hkernel;
+  HANDLE hRemThread;
+  char *mHook = (char *)VirtualAllocEx(hProc, NULL, fullSize,
+ MEM_COMMIT, PAGE_READWRITE);
+  if (mHook) {
+     hkernel = GetModuleHandle("kernel32.dll");
+     my_rmi.getModH = (GetModH_t *)GetProcAddress(hkernel, "GetModuleHandleA");
+     my_rmi.getProc = (GetProc_t *)GetProcAddress(hkernel, "GetProcAddress");
+     WriteProcessMemory(hProc,mHook,&my_rmi,sizeof(my_rmi), &nbytes);
+     WriteProcessMemory(hProc,mHook+sizeof(my_rmi),remote_setup,
+ funcSize, &nbytes);
+     hRemThread = CreateRemoteThread(hProc,NULL,0,
+ (LPTHREAD_START_ROUTINE)(mHook+sizeof(my_rmi)), mHook, 0, &nbytes);
+      if (hRemThread) {
+ WaitForSingleObject(hRemThread,INFINITE);
+        CloseHandle(hRemThread);
+ ReadProcessMemory(hProc,mHook+sizeof(int),&my_rmi.raise,
+  sizeof(my_rmi.raise), &nbytes);
+ if (my_rmi.raise) {
+  funcSize = (char *)remote_setup - (char *)remote_hook;
+  WriteProcessMemory(hProc,mHook+sizeof(remote_info1),
+    remote_hook, funcSize, &nbytes);
+ } else {
+    VirtualFreeEx(hProc,mHook,0,MEM_RELEASE);
+            mHook = NULL;
+        }
+     }
+     pExecedHook = mHook;
+  }
+}
+
 static int __stdcall
 spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
     const char *const envp[], int mode)
@@ -795,6 +866,8 @@
  primarily for strace. */
       strace.execing = 1;
       hExeced = pi.hProcess;
+      if (!ismsysdep)
+        kill_hook(hExeced);
       strcpy (myself->progname, real_path);
       close_all_files ();
     }

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mingw-msys mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-msys
Reply | Threaded
Open this post in threaded view
|

Re: Ctrl-Break handler?

Earnie Boyd
Quoting Howard Chu <[hidden email]>:

> Not content to leave well enough alone, here's yet another approach.
> It's far uglier, and requires NT/2000/XP (I.e., no Win95/98/ME).
>
> This code assumes that the target program has been linked with an
> MSVC CRT DLL. If it can find one of these DLLs attached to the
> target, then it will find the raise() entry point in the DLL, and use
> that to send signals to the target. One advantage of this approach is
> that it will work even if the target program doesn't use a Console.  
> The obvious disadvantage is that it's pretty invasive. If there's no
> MSVCRT, then it does nothing.
>
> Food for thought. It works, but I'm not sure it was worth the effort.
>

I like it but not for 1.0.11.  Perhaps 1.0.12.  I need to spend some
time marking the 1.0.11 release in CVS, I'll try to get that done early
next year (oh, that's right, that is next week; Happy New Year everyone
;).  Again, please use the patch tracker and supply ChangeLog entries.

Earnie Boyd
--
Please post responsibly:
* Use text posts instead of html; many list members just trash mail with html.
* Do not use multipart mime to send both text and html versions.
* Do not top post replies; post inline with the parts you are responding to.
* Trim the post replies; remove irrelevant information from the quoted
article.
* Original posters:
  ** Provide small complete examples of the problem.
  ** Provide the full command that produced errors.
  ** Provide the versions of the software used.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Mingw-msys mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-msys