aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker1998-04-17 05:10:29 +0000
committerGeoff Voelker1998-04-17 05:10:29 +0000
commitef79fbba2fb79df89a0ec9476981e7eb996d4f7d (patch)
tree5d677036fba60360d80eed8a572a91749e425f2a /src
parentc88696553221c2e8df18c16b64d7f9e405128d2b (diff)
downloademacs-ef79fbba2fb79df89a0ec9476981e7eb996d4f7d.tar.gz
emacs-ef79fbba2fb79df89a0ec9476981e7eb996d4f7d.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/w32proc.c108
1 files changed, 100 insertions, 8 deletions
diff --git a/src/w32proc.c b/src/w32proc.c
index f01b34daa55..1acae25a9f5 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -45,6 +45,7 @@ Boston, MA 02111-1307, USA.
45#include "systime.h" 45#include "systime.h"
46#include "syswait.h" 46#include "syswait.h"
47#include "process.h" 47#include "process.h"
48#include "w32term.h"
48 49
49/* Control whether spawnve quotes arguments as necessary to ensure 50/* Control whether spawnve quotes arguments as necessary to ensure
50 correct parsing by child process. Because not all uses of spawnve 51 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)
606 607
607 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew); 608 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
608 609
609 if (nt_header > dos_header + executable.size) 610 if ((char *) nt_header > (char *) dos_header + executable.size)
610 { 611 {
611 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */ 612 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
612 *is_dos_app = TRUE; 613 *is_dos_app = TRUE;
@@ -736,7 +737,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
736 unixtodos_filename (cmdname); 737 unixtodos_filename (cmdname);
737 argv[0] = cmdname; 738 argv[0] = cmdname;
738 739
739 /* Determine whether program is a 16-bit DOS executable, or a Win32 740 /* Determine whether program is a 16-bit DOS executable, or a w32
740 executable that is implicitly linked to the Cygnus dll (implying it 741 executable that is implicitly linked to the Cygnus dll (implying it
741 was compiled with the Cygnus GNU toolchain and hence relies on 742 was compiled with the Cygnus GNU toolchain and hence relies on
742 cygwin.dll to parse the command line - we use this to decide how to 743 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)
771 exactly, so we treat quotes at the beginning and end of arguments 772 exactly, so we treat quotes at the beginning and end of arguments
772 as embedded quotes. 773 as embedded quotes.
773 774
774 The Win32 GNU-based library from Cygnus doubles quotes to escape 775 The w32 GNU-based library from Cygnus doubles quotes to escape
775 them, while MSVC uses backslash for escaping. (Actually the MSVC 776 them, while MSVC uses backslash for escaping. (Actually the MSVC
776 startup code does attempt to recognise doubled quotes and accept 777 startup code does attempt to recognise doubled quotes and accept
777 them, but gets it wrong and ends up requiring three quotes to get a 778 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,
1109 else 1110 else
1110 { 1111 {
1111 /* Unable to find something to wait on for this fd, skip */ 1112 /* Unable to find something to wait on for this fd, skip */
1113
1114 /* Note that this is not a fatal error, and can in fact
1115 happen in unusual circumstances. Specifically, if
1116 sys_spawnve fails, eg. because the program doesn't
1117 exist, and debug-on-error is t so Fsignal invokes a
1118 nested input loop, then the process output pipe is
1119 still included in input_wait_mask with no child_proc
1120 associated with it. (It is removed when the debugger
1121 exits the nested input loop and the error is thrown.) */
1122
1112 DebPrint (("sys_select: fd %ld is invalid! ignoring\n", i)); 1123 DebPrint (("sys_select: fd %ld is invalid! ignoring\n", i));
1113 abort ();
1114 } 1124 }
1115 } 1125 }
1116 } 1126 }
@@ -1119,8 +1129,14 @@ count_children:
1119 /* Add handles of child processes. */ 1129 /* Add handles of child processes. */
1120 nc = 0; 1130 nc = 0;
1121 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--) 1131 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
1122 /* some child_procs might be sockets; ignore them */ 1132 /* Some child_procs might be sockets; ignore them. Also some
1123 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess) 1133 children may have died already, but we haven't finished reading
1134 the process output; ignore them too. */
1135 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess
1136 && (cp->fd < 0
1137 || (fd_info[cp->fd].flags & FILE_SEND_SIGCHLD) == 0
1138 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)
1139 )
1124 { 1140 {
1125 wait_hnd[nh + nc] = cp->procinfo.hProcess; 1141 wait_hnd[nh + nc] = cp->procinfo.hProcess;
1126 cps[nc] = cp; 1142 cps[nc] = cp;
@@ -1176,9 +1192,16 @@ count_children:
1176 if (active >= nh) 1192 if (active >= nh)
1177 { 1193 {
1178 cp = cps[active - nh]; 1194 cp = cps[active - nh];
1195
1196 /* We cannot always signal SIGCHLD immediately; if we have not
1197 finished reading the process output, we must delay sending
1198 SIGCHLD until we do. */
1199
1200 if (cp->fd >= 0 && (fd_info[cp->fd].flags & FILE_AT_EOF) == 0)
1201 fd_info[cp->fd].flags |= FILE_SEND_SIGCHLD;
1179 /* SIG_DFL for SIGCHLD is ignore */ 1202 /* SIG_DFL for SIGCHLD is ignore */
1180 if (sig_handlers[SIGCHLD] != SIG_DFL 1203 else if (sig_handlers[SIGCHLD] != SIG_DFL &&
1181 && sig_handlers[SIGCHLD] != SIG_IGN) 1204 sig_handlers[SIGCHLD] != SIG_IGN)
1182 { 1205 {
1183#ifdef FULL_DEBUG 1206#ifdef FULL_DEBUG
1184 DebPrint (("select calling SIGCHLD handler for pid %d\n", 1207 DebPrint (("select calling SIGCHLD handler for pid %d\n",
@@ -1314,6 +1337,10 @@ sys_kill (int pid, int sig)
1314 keybd_event (vk_break_code, break_scan_code, KEYEVENTF_KEYUP, 0); 1337 keybd_event (vk_break_code, break_scan_code, KEYEVENTF_KEYUP, 0);
1315 keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0); 1338 keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
1316 1339
1340 /* Sleep for a bit to give time for Emacs frame to respond
1341 to focus change events (if Emacs was active app). */
1342 Sleep (10);
1343
1317 SetForegroundWindow (foreground_window); 1344 SetForegroundWindow (foreground_window);
1318 } 1345 }
1319 } 1346 }
@@ -1349,7 +1376,24 @@ sys_kill (int pid, int sig)
1349 Could try to invoke DestroyVM through CallVxD. 1376 Could try to invoke DestroyVM through CallVxD.
1350 1377
1351*/ 1378*/
1379#if 0
1380 /* On Win95, posting WM_QUIT causes the 16-bit subsystem
1381 to hang when cmdproxy is used in conjunction with
1382 command.com for an interactive shell. Posting
1383 WM_CLOSE pops up a dialog that, when Yes is selected,
1384 does the same thing. TerminateProcess is also less
1385 than ideal in that subprocesses tend to stick around
1386 until the machine is shutdown, but at least it
1387 doesn't freeze the 16-bit subsystem. */
1352 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0); 1388 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
1389#endif
1390 if (!TerminateProcess (proc_hand, 0xff))
1391 {
1392 DebPrint (("sys_kill.TerminateProcess returned %d "
1393 "for pid %lu\n", GetLastError (), pid));
1394 errno = EINVAL;
1395 rc = -1;
1396 }
1353 } 1397 }
1354 else 1398 else
1355#endif 1399#endif
@@ -1696,6 +1740,48 @@ human-readable form.")
1696 return make_number (GetThreadLocale ()); 1740 return make_number (GetThreadLocale ());
1697} 1741}
1698 1742
1743DWORD int_from_hex (char * s)
1744{
1745 DWORD val = 0;
1746 static char hex[] = "0123456789abcdefABCDEF";
1747 char * p;
1748
1749 while (*s && (p = strchr(hex, *s)) != NULL)
1750 {
1751 unsigned digit = p - hex;
1752 if (digit > 15)
1753 digit -= 6;
1754 val = val * 16 + digit;
1755 s++;
1756 }
1757 return val;
1758}
1759
1760/* We need to build a global list, since the EnumSystemLocale callback
1761 function isn't given a context pointer. */
1762Lisp_Object Vw32_valid_locale_ids;
1763
1764BOOL CALLBACK enum_locale_fn (LPTSTR localeNum)
1765{
1766 DWORD id = int_from_hex (localeNum);
1767 Vw32_valid_locale_ids = Fcons (make_number (id), Vw32_valid_locale_ids);
1768 return TRUE;
1769}
1770
1771DEFUN ("w32-get-valid-locale-ids", Fw32_get_valid_locale_ids, Sw32_get_valid_locale_ids, 0, 0, 0,
1772 "Return list of all valid Windows locale ids.\n\
1773Each id is a numerical value; use `w32-get-locale-info' to convert to a\n\
1774human-readable form.")
1775 ()
1776{
1777 Vw32_valid_locale_ids = Qnil;
1778
1779 EnumSystemLocales (enum_locale_fn, LCID_SUPPORTED);
1780
1781 Vw32_valid_locale_ids = Fnreverse (Vw32_valid_locale_ids);
1782 return Vw32_valid_locale_ids;
1783}
1784
1699 1785
1700DEFUN ("w32-get-default-locale-id", Fw32_get_default_locale_id, Sw32_get_default_locale_id, 0, 1, 0, 1786DEFUN ("w32-get-default-locale-id", Fw32_get_default_locale_id, Sw32_get_default_locale_id, 0, 1, 0,
1701 "Return Windows locale id for default locale setting.\n\ 1787 "Return Windows locale id for default locale setting.\n\
@@ -1726,6 +1812,11 @@ If successful, the new locale id is returned, otherwise nil.")
1726 if (!SetThreadLocale (XINT (lcid))) 1812 if (!SetThreadLocale (XINT (lcid)))
1727 return Qnil; 1813 return Qnil;
1728 1814
1815 /* Need to set input thread locale if present. */
1816 if (dwWindowsThreadId)
1817 /* Reply is not needed. */
1818 PostThreadMessage (dwWindowsThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
1819
1729 return make_number (GetThreadLocale ()); 1820 return make_number (GetThreadLocale ());
1730} 1821}
1731 1822
@@ -1745,6 +1836,7 @@ syms_of_ntproc ()
1745 defsubr (&Sw32_get_locale_info); 1836 defsubr (&Sw32_get_locale_info);
1746 defsubr (&Sw32_get_current_locale_id); 1837 defsubr (&Sw32_get_current_locale_id);
1747 defsubr (&Sw32_get_default_locale_id); 1838 defsubr (&Sw32_get_default_locale_id);
1839 defsubr (&Sw32_get_valid_locale_ids);
1748 defsubr (&Sw32_set_current_locale); 1840 defsubr (&Sw32_set_current_locale);
1749 1841
1750 DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args, 1842 DEFVAR_LISP ("w32-quote-process-args", &Vw32_quote_process_args,