Commit ef79fbba authored by Geoff Voelker's avatar Geoff Voelker

(w32_executable_type): Properly cast dos_header when

making size comparison.
(sys_spawnve): Update comments.
(sys_select): Ignore children dead children with pending input.
Delay sending SIGCHLD until all output has been read.
(sys_kill): Sleep to allow focus change events to propagate.
Use TerminateProcess on Win95.
(int_from_hex, enum_locale_fn, Fw32_get_valid_locale_ids):
New functions.
(Vw32_valid_locale_ids): New variable.
(Fw32_set_current_locale): Send message to input thread.
(syms_of_ntproc): defsubr Sw32_get_valid_locale_ids.
parent c8869655
......@@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA.
#include "systime.h"
#include "syswait.h"
#include "process.h"
#include "w32term.h"
/* Control whether spawnve quotes arguments as necessary to ensure
correct parsing by child process. Because not all uses of spawnve
......@@ -606,7 +607,7 @@ w32_executable_type (char * filename, int * is_dos_app, int * is_cygnus_app)
nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
if (nt_header > dos_header + executable.size)
if ((char *) nt_header > (char *) dos_header + executable.size)
/* Some dos headers (pkunzip) have bogus e_lfanew fields. */
*is_dos_app = TRUE;
......@@ -736,7 +737,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
unixtodos_filename (cmdname);
argv[0] = cmdname;
/* Determine whether program is a 16-bit DOS executable, or a Win32
/* Determine whether program is a 16-bit DOS executable, or a w32
executable that is implicitly linked to the Cygnus dll (implying it
was compiled with the Cygnus GNU toolchain and hence relies on
cygwin.dll to parse the command line - we use this to decide how to
......@@ -771,7 +772,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
exactly, so we treat quotes at the beginning and end of arguments
as embedded quotes.
The Win32 GNU-based library from Cygnus doubles quotes to escape
The w32 GNU-based library from Cygnus doubles quotes to escape
them, while MSVC uses backslash for escaping. (Actually the MSVC
startup code does attempt to recognise doubled quotes and accept
them, but gets it wrong and ends up requiring three quotes to get a
......@@ -1109,8 +1110,17 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
/* Unable to find something to wait on for this fd, skip */
/* Note that this is not a fatal error, and can in fact
happen in unusual circumstances. Specifically, if
sys_spawnve fails, eg. because the program doesn't
exist, and debug-on-error is t so Fsignal invokes a
nested input loop, then the process output pipe is
still included in input_wait_mask with no child_proc
associated with it. (It is removed when the debugger
exits the nested input loop and the error is thrown.) */
DebPrint (("sys_select: fd %ld is invalid! ignoring\n", i));
abort ();
......@@ -1119,8 +1129,14 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
/* Add handles of child processes. */
nc = 0;
for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
/* some child_procs might be sockets; ignore them */
if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess)
/* Some child_procs might be sockets; ignore them. Also some
children may have died already, but we haven't finished reading
the process output; ignore them too. */
if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
&& (cp->fd < 0
|| (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0
|| (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)
wait_hnd[nh + nc] = cp->procinfo.hProcess;
cps[nc] = cp;
......@@ -1176,9 +1192,16 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
if (active >= nh)
cp = cps[active - nh];
/* We cannot always signal SIGCHLD immediately; if we have not
finished reading the process output, we must delay sending
SIGCHLD until we do. */
if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_AT_EOF) == 0)
fd_info[cp->fd].flags |= FILE_SEND_SIGCHLD;
/* SIG_DFL for SIGCHLD is ignore */
if (sig_handlers[SIGCHLD] != SIG_DFL
&& sig_handlers[SIGCHLD] != SIG_IGN)
else if (sig_handlers[SIGCHLD] != SIG_DFL &&
sig_handlers[SIGCHLD] != SIG_IGN)
DebPrint (("select calling SIGCHLD handler for pid %d\n",
......@@ -1314,6 +1337,10 @@ sys_kill (int pid, int sig)
keybd_event (vk_break_code, break_scan_code, KEYEVENTF_KEYUP, 0);
keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
/* Sleep for a bit to give time for Emacs frame to respond
to focus change events (if Emacs was active app). */
Sleep (10);
SetForegroundWindow (foreground_window);
......@@ -1349,7 +1376,24 @@ sys_kill (int pid, int sig)
Could try to invoke DestroyVM through CallVxD.
#if 0
/* On Win95, posting WM_QUIT causes the 16-bit subsystem
to hang when cmdproxy is used in conjunction with for an interactive shell. Posting
WM_CLOSE pops up a dialog that, when Yes is selected,
does the same thing. TerminateProcess is also less
than ideal in that subprocesses tend to stick around
until the machine is shutdown, but at least it
doesn't freeze the 16-bit subsystem. */
PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
if (!TerminateProcess (proc_hand, 0xff))
DebPrint (("sys_kill.TerminateProcess returned %d "
"for pid %lu\n", GetLastError (), pid));
errno = EINVAL;
rc = -1;
......@@ -1696,6 +1740,48 @@ human-readable form.")
return make_number (GetThreadLocale ());
DWORD int_from_hex (char * s)
DWORD val = 0;
static char hex[] = "0123456789abcdefABCDEF";
char * p;
while (*s && (p = strchr(hex, *s)) != NULL)
unsigned digit = p - hex;
if (digit > 15)
digit -= 6;
val = val * 16 + digit;
return val;
/* We need to build a global list, since the EnumSystemLocale callback
function isn't given a context pointer. */
Lisp_Object Vw32_valid_locale_ids;
BOOL CALLBACK enum_locale_fn (LPTSTR localeNum)
DWORD id = int_from_hex (localeNum);
Vw32_valid_locale_ids = Fcons (make_number (id), Vw32_valid_locale_ids);
return TRUE;
DEFUN ("w32-get-valid-locale-ids", Fw32_get_valid_locale_ids, Sw32_get_valid_locale_ids, 0, 0, 0,
"Return list of all valid Windows locale ids.\n\
Each id is a numerical value; use `w32-get-locale-info' to convert to a\n\
human-readable form.")
Vw32_valid_locale_ids = Qnil;
EnumSystemLocales (enum_locale_fn, LCID_SUPPORTED);
Vw32_valid_locale_ids = Fnreverse (Vw32_valid_locale_ids);
return Vw32_valid_locale_ids;
DEFUN ("w32-get-default-locale-id", Fw32_get_default_locale_id, Sw32_get_default_locale_id, 0, 1, 0,
"Return Windows locale id for default locale setting.\n\
......@@ -1726,6 +1812,11 @@ If successful, the new locale id is returned, otherwise nil.")
if (!SetThreadLocale (XINT (lcid)))
return Qnil;
/* Need to set input thread locale if present. */
if (dwWindowsThreadId)
/* Reply is not needed. */
PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
return make_number (GetThreadLocale ());
......@@ -1745,6 +1836,7 @@ syms_of_ntproc ()
defsubr (&Sw32_get_locale_info);
defsubr (&Sw32_get_current_locale_id);
defsubr (&Sw32_get_default_locale_id);
defsubr (&Sw32_get_valid_locale_ids);
defsubr (&Sw32_set_current_locale);
DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args,
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment