aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlain Schneble2016-10-08 16:52:40 +0300
committerEli Zaretskii2016-10-08 16:52:40 +0300
commitf3eedc7e68d0e8b97425b72d691593d06639df88 (patch)
tree8382915bdc2da6b10293e2c86c8b1306e6567373 /src
parent67d14c8222c05ac20229f71a2cf40eb9e3efa053 (diff)
downloademacs-f3eedc7e68d0e8b97425b72d691593d06639df88.tar.gz
emacs-f3eedc7e68d0e8b97425b72d691593d06639df88.zip
Support SIGTRAP in kill emulation on Windows
* src/w32proc.c (sys_kill): Translate SIGTRAP signal into a call to 'DebugBreakProcess' to cause a breakpoint exception to occur in the specified process. On Windows versions prior to Windows XP that do not support 'DebugBreakProcess' return -1 and set errno to ENOTSUP (as opposed to EINVAL before this change). * src/w32proc.c: Add typedef for 'DebugBreakProcess' function pointer and global variable to track state of run-time dynamic linking of this function. * etc/NEWS: Add entry to document that 'signal-process' now supports SIGTRAP.
Diffstat (limited to 'src')
-rw-r--r--src/w32.c2
-rw-r--r--src/w32proc.c52
2 files changed, 51 insertions, 3 deletions
diff --git a/src/w32.c b/src/w32.c
index f9110853799..517e286eaa9 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -334,6 +334,7 @@ static BOOL g_b_init_set_named_security_info_a;
334static BOOL g_b_init_get_adapters_info; 334static BOOL g_b_init_get_adapters_info;
335 335
336BOOL g_b_init_compare_string_w; 336BOOL g_b_init_compare_string_w;
337BOOL g_b_init_debug_break_process;
337 338
338/* 339/*
339 BEGIN: Wrapper functions around OpenProcessToken 340 BEGIN: Wrapper functions around OpenProcessToken
@@ -9657,6 +9658,7 @@ globals_of_w32 (void)
9657 g_b_init_set_named_security_info_a = 0; 9658 g_b_init_set_named_security_info_a = 0;
9658 g_b_init_get_adapters_info = 0; 9659 g_b_init_get_adapters_info = 0;
9659 g_b_init_compare_string_w = 0; 9660 g_b_init_compare_string_w = 0;
9661 g_b_init_debug_break_process = 0;
9660 num_of_processors = 0; 9662 num_of_processors = 0;
9661 /* The following sets a handler for shutdown notifications for 9663 /* The following sets a handler for shutdown notifications for
9662 console apps. This actually applies to Emacs in both console and 9664 console apps. This actually applies to Emacs in both console and
diff --git a/src/w32proc.c b/src/w32proc.c
index aef4e44d73a..189034c4e2d 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -69,6 +69,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
69 + (filedata).file_base)) 69 + (filedata).file_base))
70 70
71extern BOOL g_b_init_compare_string_w; 71extern BOOL g_b_init_compare_string_w;
72extern BOOL g_b_init_debug_break_process;
73
72int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, 74int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
73 struct timespec *, void *); 75 struct timespec *, void *);
74 76
@@ -2497,6 +2499,9 @@ find_child_console (HWND hwnd, LPARAM arg)
2497 return TRUE; 2499 return TRUE;
2498} 2500}
2499 2501
2502typedef BOOL (WINAPI * DebugBreakProcess_Proc) (
2503 HANDLE hProcess);
2504
2500/* Emulate 'kill', but only for other processes. */ 2505/* Emulate 'kill', but only for other processes. */
2501int 2506int
2502sys_kill (pid_t pid, int sig) 2507sys_kill (pid_t pid, int sig)
@@ -2510,9 +2515,9 @@ sys_kill (pid_t pid, int sig)
2510 if (pid < 0) 2515 if (pid < 0)
2511 pid = -pid; 2516 pid = -pid;
2512 2517
2513 /* Only handle signals that will result in the process dying */ 2518 /* Only handle signals that can be mapped to a similar behavior on Windows */
2514 if (sig != 0 2519 if (sig != 0
2515 && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) 2520 && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP && sig != SIGTRAP)
2516 { 2521 {
2517 errno = EINVAL; 2522 errno = EINVAL;
2518 return -1; 2523 return -1;
@@ -2555,7 +2560,11 @@ sys_kill (pid_t pid, int sig)
2555 close the selected frame, which does not necessarily 2560 close the selected frame, which does not necessarily
2556 terminates Emacs. But then we are not supposed to call 2561 terminates Emacs. But then we are not supposed to call
2557 sys_kill with our own PID. */ 2562 sys_kill with our own PID. */
2558 proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid); 2563
2564 DWORD desiredAccess =
2565 (sig == SIGTRAP) ? PROCESS_ALL_ACCESS : PROCESS_TERMINATE;
2566
2567 proc_hand = OpenProcess (desiredAccess, 0, pid);
2559 if (proc_hand == NULL) 2568 if (proc_hand == NULL)
2560 { 2569 {
2561 errno = EPERM; 2570 errno = EPERM;
@@ -2651,6 +2660,43 @@ sys_kill (pid_t pid, int sig)
2651 rc = -1; 2660 rc = -1;
2652 } 2661 }
2653 } 2662 }
2663 else if (sig == SIGTRAP)
2664 {
2665 static DebugBreakProcess_Proc s_pfn_Debug_Break_Process = NULL;
2666
2667 if (g_b_init_debug_break_process == 0)
2668 {
2669 g_b_init_debug_break_process = 1;
2670 s_pfn_Debug_Break_Process = (DebugBreakProcess_Proc)
2671 GetProcAddress (GetModuleHandle ("kernel32.dll"),
2672 "DebugBreakProcess");
2673 }
2674
2675 if (s_pfn_Debug_Break_Process == NULL)
2676 {
2677 errno = ENOTSUP;
2678 rc = -1;
2679 }
2680 else if (!s_pfn_Debug_Break_Process (proc_hand))
2681 {
2682 DWORD err = GetLastError ();
2683
2684 DebPrint (("sys_kill.DebugBreakProcess return %d "
2685 "for pid %lu\n", err, pid));
2686
2687 switch (err)
2688 {
2689 case ERROR_ACCESS_DENIED:
2690 errno = EPERM;
2691 break;
2692 default:
2693 errno = EINVAL;
2694 break;
2695 }
2696
2697 rc = -1;
2698 }
2699 }
2654 else 2700 else
2655 { 2701 {
2656 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd) 2702 if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)