summaryrefslogtreecommitdiff
path: root/src/w32proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32proc.c')
-rw-r--r--src/w32proc.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index 4a6f7862801..6f3a6e0efca 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -22,6 +22,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
Adapted from alarm.c by Tim Fleehart
*/
+#define DEFER_MS_W32_H
+#include <config.h>
+
#include <mingw_time.h>
#include <stdio.h>
#include <stdlib.h>
@@ -35,8 +38,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <mbstring.h>
#include <locale.h>
-/* must include CRT headers *before* config.h */
-#include <config.h>
+/* Include CRT headers *before* ms-w32.h. */
+#include <ms-w32.h>
#undef signal
#undef wait
@@ -45,11 +48,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#undef kill
#include <windows.h>
-#if defined(__GNUC__) && !defined(__MINGW64__)
-/* This definition is missing from mingw.org headers, but not MinGW64
- headers. */
-extern BOOL WINAPI IsValidLocale (LCID, DWORD);
-#endif
#ifdef HAVE_LANGINFO_CODESET
#include <nl_types.h>
@@ -70,6 +68,12 @@ extern BOOL WINAPI IsValidLocale (LCID, DWORD);
+ ((DWORD_PTR)(var) - (section)->VirtualAddress) \
+ (filedata).file_base))
+extern BOOL g_b_init_compare_string_w;
+extern BOOL g_b_init_debug_break_process;
+
+int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
+ const struct timespec *, const sigset_t *);
+
/* Signal handlers...SIG_DFL == 0 so this is initialized correctly. */
static signal_handler sig_handlers[NSIG];
@@ -87,9 +91,9 @@ sys_signal (int sig, signal_handler handler)
/* SIGCHLD is needed for supporting subprocesses, see sys_kill
below. SIGALRM and SIGPROF are used by setitimer. All the
others are the only ones supported by the MS runtime. */
- if (!(sig == SIGCHLD || sig == SIGSEGV || sig == SIGILL
+ if (!(sig == SIGINT || sig == SIGSEGV || sig == SIGILL
|| sig == SIGFPE || sig == SIGABRT || sig == SIGTERM
- || sig == SIGALRM || sig == SIGPROF))
+ || sig == SIGCHLD || sig == SIGALRM || sig == SIGPROF))
{
errno = EINVAL;
return SIG_ERR;
@@ -225,7 +229,7 @@ sigismember (const sigset_t *set, int signo)
errno = EINVAL;
return -1;
}
- if (signo > sizeof (*set) * BITS_PER_CHAR)
+ if (signo > sizeof (*set) * CHAR_BIT)
emacs_abort ();
return (*set & (1U << signo)) != 0;
@@ -845,8 +849,8 @@ alarm (int seconds)
stream is terminated, terminates the reader thread as part of
deleting the child_process object.
- The sys_select function emulates the Posix 'pselect' function; it
- is needed because the Windows 'select' function supports only
+ The sys_select function emulates the Posix 'pselect' functionality;
+ it is needed because the Windows 'select' function supports only
network sockets, while Emacs expects 'pselect' to work for any file
descriptor, including pipes and serial streams.
@@ -1728,7 +1732,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
are not expanded if we run the program directly without a shell.
Some extra whitespace characters need quoting in Cygwin/MSYS programs,
so this list is conditionally modified below. */
- char *sepchars = " \t*?";
+ const char *sepchars = " \t*?";
/* This is for native w32 apps; modified below for Cygwin/MSUS apps. */
char escape_char = '\\';
char cmdname_a[MAX_PATH];
@@ -2092,7 +2096,7 @@ extern int proc_buffered_char[];
int
sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
- struct timespec *timeout, void *ignored)
+ const struct timespec *timeout, const sigset_t *ignored)
{
SELECT_TYPE orfds, owfds;
DWORD timeout_ms, start_time;
@@ -2495,6 +2499,9 @@ find_child_console (HWND hwnd, LPARAM arg)
return TRUE;
}
+typedef BOOL (WINAPI * DebugBreakProcess_Proc) (
+ HANDLE hProcess);
+
/* Emulate 'kill', but only for other processes. */
int
sys_kill (pid_t pid, int sig)
@@ -2508,9 +2515,9 @@ sys_kill (pid_t pid, int sig)
if (pid < 0)
pid = -pid;
- /* Only handle signals that will result in the process dying */
+ /* Only handle signals that can be mapped to a similar behavior on Windows */
if (sig != 0
- && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
+ && sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP && sig != SIGTRAP)
{
errno = EINVAL;
return -1;
@@ -2553,7 +2560,11 @@ sys_kill (pid_t pid, int sig)
close the selected frame, which does not necessarily
terminates Emacs. But then we are not supposed to call
sys_kill with our own PID. */
- proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid);
+
+ DWORD desiredAccess =
+ (sig == SIGTRAP) ? PROCESS_ALL_ACCESS : PROCESS_TERMINATE;
+
+ proc_hand = OpenProcess (desiredAccess, 0, pid);
if (proc_hand == NULL)
{
errno = EPERM;
@@ -2649,6 +2660,43 @@ sys_kill (pid_t pid, int sig)
rc = -1;
}
}
+ else if (sig == SIGTRAP)
+ {
+ static DebugBreakProcess_Proc s_pfn_Debug_Break_Process = NULL;
+
+ if (g_b_init_debug_break_process == 0)
+ {
+ g_b_init_debug_break_process = 1;
+ s_pfn_Debug_Break_Process = (DebugBreakProcess_Proc)
+ GetProcAddress (GetModuleHandle ("kernel32.dll"),
+ "DebugBreakProcess");
+ }
+
+ if (s_pfn_Debug_Break_Process == NULL)
+ {
+ errno = ENOTSUP;
+ rc = -1;
+ }
+ else if (!s_pfn_Debug_Break_Process (proc_hand))
+ {
+ DWORD err = GetLastError ();
+
+ DebPrint (("sys_kill.DebugBreakProcess return %d "
+ "for pid %lu\n", err, pid));
+
+ switch (err)
+ {
+ case ERROR_ACCESS_DENIED:
+ errno = EPERM;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+
+ rc = -1;
+ }
+ }
else
{
if (NILP (Vw32_start_process_share_console) && cp && cp->hwnd)
@@ -2815,7 +2863,6 @@ set_process_dir (char * dir)
/* From w32.c */
extern HANDLE winsock_lib;
extern BOOL term_winsock (void);
-extern BOOL init_winsock (int load_now);
DEFUN ("w32-has-winsock", Fw32_has_winsock, Sw32_has_winsock, 0, 1, 0,
doc: /* Test for presence of the Windows socket library `winsock'.
@@ -3522,7 +3569,6 @@ w32_compare_strings (const char *s1, const char *s2, char *locname,
LCID lcid = GetThreadLocale ();
wchar_t *string1_w, *string2_w;
int val, needed;
- extern BOOL g_b_init_compare_string_w;
static CompareStringW_Proc pCompareStringW;
DWORD flags = 0;