xpra icon
Bug tracker and wiki

Ticket #2264: ctrl_c.patch

File ctrl_c.patch, 6.5 KB (added by totaamwin32, 19 months ago)

Patch for winsup/cygwin/...

  • ChangeLog.MSYS

    RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/ChangeLog.MSYS,v
    retrieving revision 1.86
    diff -u -r1.86 ChangeLog.MSYS
     
    112006.12.29  Howard Chu <highlandsun@users.sf.net>
    22
     3        * exceptions.cc (sig_handle): Create a thread in the execed process
     4        for propagating SIGINT/SIGTERM/SIGQUIT/SIGHUP.
     5        * spawn.cc (spawn_guts): Setup hooks for above in the execed process
     6        if it's not an MSYS app.
     7        * sigproc.h: New typedefs to support above change.
     8
     92006.12.29  Howard Chu <highlandsun@users.sf.net>
     10
    311        * exceptions.cc (ctrl_c_handler): Handle CTRL_LOGOFF_EVENT too,
    412        since that's sent during a Shutdown. Resolves Tracker #1174106.
    513
  • exceptions.cc

    RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/exceptions.cc,v
    retrieving revision 1.6
    diff -u -r1.6 exceptions.cc
     
    955955sig_handle (int sig)
    956956{
    957957  int rc = 0;
     958  extern char *pExecedHook;
    958959
    959960  sigproc_printf ("signal %d", sig);
    960961
     
    997998  OutputDebugString (sigmsg);
    998999#endif
    9991000
     1001/* This is the value the MSVC RT uses for SIGBREAK. MSVC doesn't define
     1002 * SIGQUIT so we turn it into SIGBREAK, as that seems to be the intent
     1003 * of the signal. MSVC also sends SIGBREAK to NT Services in response
     1004 * to CTRL_LOGOFF_EVENTs, which we would consider SIGHUP. Since MSVC
     1005 * doesn't define SIGHUP we translate SIGHUP to SIGBREAK as well.
     1006 */
     1007#ifndef SIGBREAK
     1008#define SIGBREAK 21
     1009#endif
     1010
     1011  if (pExecedHook && (sig == SIGINT || sig == SIGTERM || sig == SIGQUIT
     1012        || sig == SIGHUP )) {
     1013      extern HANDLE hExeced;
     1014      SIZE_T nbytes;
     1015      HANDLE hRemThread;
     1016      int rsig;
     1017      rsig = (sig == SIGQUIT || sig == SIGHUP) ? SIGBREAK : sig;
     1018      WriteProcessMemory(hExeced,pExecedHook,&rsig,sizeof(rsig),
     1019        &nbytes);
     1020      hRemThread = CreateRemoteThread(hExeced,NULL,0,
     1021        (LPTHREAD_START_ROUTINE)(pExecedHook+sizeof(remote_info1)), pExecedHook, 0, &nbytes);
     1022      if (hRemThread) {
     1023        WaitForSingleObject(hRemThread,INFINITE);
     1024        CloseHandle(hRemThread);
     1025        goto done;
     1026      }
     1027  }
     1028
    10001029  if (handler == (void *) SIG_DFL)
    10011030    {
    10021031      if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH)
  • sigproc.h

    RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/sigproc.h,v
    retrieving revision 1.3
    diff -u -r1.3 sigproc.h
     
    3434  HANDLE thread_ev;
    3535} waitq;
    3636
     37typedef HMODULE (GetModH_t)(LPCTSTR name);
     38typedef FARPROC (GetProc_t)(HMODULE hmod, LPCSTR name);
     39typedef int (raise_t)(int sig);
     40
     41typedef struct remote_info1 {
     42  int sig;
     43  raise_t *raise;
     44} remote_info1;
     45
     46typedef struct remote_info {
     47  int sig;
     48  raise_t *raise;
     49  GetModH_t *getModH;
     50  GetProc_t *getProc;
     51  char rname[16];
     52  char names[12][16];
     53} remote_info;
     54
    3755struct sigthread
    3856{
    3957  DWORD id;
  • spawn.cc

    RCS file: /cvsroot/mingw/msys/rt/src/winsup/cygwin/spawn.cc,v
    retrieving revision 1.27
    diff -u -r1.27 spawn.cc
     
    4747};
    4848
    4949HANDLE hExeced;
     50char *pExecedHook;
    5051
    5152/* Add .exe to PROG if not already present and see if that exists.
    5253   If not, return PROG (converted from posix to win32 rules if necessary).
     
    305306  return 1;
    306307}
    307308
     309/* Stuff to support propagating signals to native Win32 apps:
     310 * Try to find an MSVC runtime DLL attached to the target process.
     311 * If found, look for the raise() entry point. Use that to forward
     312 * signals that we receive. If we don't find it, cleanup and do
     313 * no special signal handling for the target.
     314 */
     315static remote_info my_rmi = {
     316  0, NULL, NULL, NULL,
     317  "raise",
     318  { "msvcr80.dll", "msvcr80d.dll",
     319    "msvcr71.dll", "msvcr71d.dll",
     320    "msvcr70.dll", "msvcr70d.dll",
     321    "msvcrt.dll", "msvcrtd.dll" }
     322};
     323
     324static DWORD
     325remote_hook (remote_info1 *rmi)
     326{
     327  rmi->raise (rmi->sig);
     328  return 0;
     329}
     330
     331static DWORD
     332remote_setup (remote_info *rmi)
     333{
     334  int i;
     335  HMODULE hm;
     336
     337  for (i = 0; rmi->names[i][0]; i++)
     338    {
     339      hm = rmi->getModH (rmi->names[i]);
     340      if (hm)
     341        {
     342          rmi->raise = (raise_t *) rmi->getProc (hm, rmi->rname);
     343          if (rmi->raise)
     344            break;
     345        }
     346    }
     347  return 0;
     348}
     349
     350static void
     351kill_hook (HANDLE hProc)
     352{
     353  SIZE_T funcSize = (char *) kill_hook - (char *) remote_setup;
     354  SIZE_T fullSize = sizeof (remote_info) + funcSize;
     355  SIZE_T nbytes;
     356  HMODULE hkernel;
     357  HANDLE hRemThread;
     358  char *mHook = (char *) VirtualAllocEx (hProc, NULL, fullSize,
     359    MEM_COMMIT, PAGE_READWRITE);
     360  if (mHook)
     361    {
     362      hkernel = GetModuleHandle ("kernel32.dll");
     363      my_rmi.getModH = (GetModH_t *)GetProcAddress(hkernel, "GetModuleHandleA");
     364      my_rmi.getProc = (GetProc_t *)GetProcAddress(hkernel, "GetProcAddress");
     365      WriteProcessMemory (hProc, mHook, &my_rmi, sizeof(my_rmi), &nbytes);
     366      WriteProcessMemory (hProc, mHook+sizeof(my_rmi), remote_setup,
     367        funcSize, &nbytes);
     368      hRemThread = CreateRemoteThread (hProc, NULL, 0,
     369        (LPTHREAD_START_ROUTINE) (mHook+sizeof(my_rmi)), mHook, 0, &nbytes);
     370      if (hRemThread)
     371        {
     372          WaitForSingleObject(hRemThread,INFINITE);
     373          CloseHandle(hRemThread);
     374          ReadProcessMemory(hProc,mHook+sizeof(int),&my_rmi.raise,
     375            sizeof(my_rmi.raise), &nbytes);
     376          if (my_rmi.raise)
     377            {
     378              funcSize = (char *) remote_setup - (char *) remote_hook;
     379              WriteProcessMemory (hProc, mHook+sizeof(remote_info1),
     380                remote_hook, funcSize, &nbytes);
     381            }
     382          else
     383            {
     384              VirtualFreeEx( hProc, mHook, 0, MEM_RELEASE);
     385              mHook = NULL;
     386            }
     387        }
     388      pExecedHook = mHook;
     389    }
     390}
     391
    308392static int __stdcall
    309393spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
    310394            const char *const envp[], int mode)
     
    795879         primarily for strace. */
    796880      strace.execing = 1;
    797881      hExeced = pi.hProcess;
     882      if (!ismsysdep)
     883        kill_hook(hExeced);
    798884      strcpy (myself->progname, real_path);
    799885      close_all_files ();
    800886    }