1 /* Process support for Windows NT port of XEMACS.
2 Copyright (C) 1992, 1995 Free Software Foundation, Inc.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Drew Bliss Oct 14, 1993
22 Adapted from alarm.c by Tim Fleehart */
24 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
25 /* Synced with FSF Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
34 /* must include CRT headers *before* config.h */
35 /* #### I don't believe it - martin */
44 #include <sys/socket.h>
51 #include "ntheap.h" /* From 19.34.6 */
53 #include "syssignal.h"
58 /*#include "w32term.h"*/ /* From 19.34.6: sync in ? --marcpa */
60 /* #### I'm not going to play with shit. */
61 #pragma warning (disable:4013 4024 4090)
63 /* Control whether spawnve quotes arguments as necessary to ensure
64 correct parsing by child process. Because not all uses of spawnve
65 are careful about constructing argv arrays, we make this behavior
66 conditional (off by default). */
67 Lisp_Object Vwin32_quote_process_args;
69 /* Control whether create_child causes the process' window to be
70 hidden. The default is nil. */
71 Lisp_Object Vwin32_start_process_show_window;
73 /* Control whether create_child causes the process to inherit Emacs'
74 console window, or be given a new one of its own. The default is
75 nil, to allow multiple DOS programs to run on Win95. Having separate
76 consoles also allows Emacs to cleanly terminate process groups. */
77 Lisp_Object Vwin32_start_process_share_console;
79 /* Time to sleep before reading from a subprocess output pipe - this
80 avoids the inefficiency of frequently reading small amounts of data.
81 This is primarily necessary for handling DOS processes on Windows 95,
82 but is useful for Win32 processes on both Win95 and NT as well. */
83 Lisp_Object Vwin32_pipe_read_delay;
85 /* Control whether stat() attempts to generate fake but hopefully
86 "accurate" inode values, by hashing the absolute truenames of files.
87 This should detect aliasing between long and short names, but still
88 allows the possibility of hash collisions. */
89 Lisp_Object Vwin32_generate_fake_inodes;
91 Lisp_Object Qhigh, Qlow;
93 extern Lisp_Object Vlisp_EXEC_SUFFIXES;
98 void _DebPrint (const char *fmt, ...)
104 va_start (args, fmt);
105 vsprintf (buf, fmt, args);
107 OutputDebugString (buf);
111 /* sys_signal moved to nt.c. It's now called msw_signal... */
113 /* Defined in <process.h> which conflicts with the local copy */
116 /* Child process management list. */
117 int child_proc_count = 0;
118 child_process child_procs[ MAX_CHILDREN ];
119 child_process *dead_child = NULL;
121 DWORD WINAPI reader_thread (void *arg);
123 /* Determine if running on Windows 9x and not NT */
127 return GetVersion () & 0x80000000;
130 /* Find an unused process slot. */
137 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
138 if (!CHILD_ACTIVE (cp))
140 if (child_proc_count == MAX_CHILDREN)
142 cp = &child_procs[child_proc_count++];
148 if (cp->procinfo.hProcess)
149 CloseHandle(cp->procinfo.hProcess);
150 cp->procinfo.hProcess = NULL;
151 cp->status = STATUS_READ_ERROR;
153 /* use manual reset event so that select() will function properly */
154 cp->char_avail = CreateEvent (NULL, TRUE, FALSE, NULL);
157 cp->char_consumed = CreateEvent (NULL, FALSE, FALSE, NULL);
158 if (cp->char_consumed)
160 cp->thrd = CreateThread (NULL, 1024, reader_thread, cp, 0, &id);
170 delete_child (child_process *cp)
174 /* Should not be deleting a child that is still needed. */
175 for (i = 0; i < MAXDESC; i++)
176 if (fd_info[i].cp == cp)
179 if (!CHILD_ACTIVE (cp))
182 /* reap thread if necessary */
187 if (GetExitCodeThread (cp->thrd, &rc) && rc == STILL_ACTIVE)
189 /* let the thread exit cleanly if possible */
190 cp->status = STATUS_READ_ERROR;
191 SetEvent (cp->char_consumed);
192 if (WaitForSingleObject (cp->thrd, 1000) != WAIT_OBJECT_0)
194 DebPrint (("delete_child.WaitForSingleObject (thread) failed "
195 "with %lu for fd %ld\n", GetLastError (), cp->fd));
196 TerminateThread (cp->thrd, 0);
199 CloseHandle (cp->thrd);
204 CloseHandle (cp->char_avail);
205 cp->char_avail = NULL;
207 if (cp->char_consumed)
209 CloseHandle (cp->char_consumed);
210 cp->char_consumed = NULL;
213 /* update child_proc_count (highest numbered slot in use plus one) */
214 if (cp == child_procs + child_proc_count - 1)
216 for (i = child_proc_count-1; i >= 0; i--)
217 if (CHILD_ACTIVE (&child_procs[i]))
219 child_proc_count = i + 1;
224 child_proc_count = 0;
227 /* Find a child by pid. */
228 static child_process *
229 find_child_pid (DWORD pid)
233 for (cp = child_procs+(child_proc_count-1); cp >= child_procs; cp--)
234 if (CHILD_ACTIVE (cp) && pid == cp->pid)
239 /* Function to do blocking read of one byte, needed to implement
240 select. It is only allowed on sockets and pipes. */
242 _sys_read_ahead (int fd)
247 if (fd < 0 || fd >= MAXDESC)
248 return STATUS_READ_ERROR;
252 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
253 return STATUS_READ_ERROR;
255 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
256 || (fd_info[fd].flags & FILE_READ) == 0)
258 /* fd is not a pipe or socket */
262 cp->status = STATUS_READ_IN_PROGRESS;
264 if (fd_info[fd].flags & FILE_PIPE)
266 rc = _read (fd, &cp->chr, sizeof (char));
268 /* Give subprocess time to buffer some more output for us before
269 reporting that input is available; we need this because Win95
270 connects DOS programs to pipes by making the pipe appear to be
271 the normal console stdout - as a result most DOS programs will
272 write to stdout without buffering, ie. one character at a
273 time. Even some Win32 programs do this - "dir" in a command
274 shell on NT is very slow if we don't do this. */
277 int wait = XINT (Vwin32_pipe_read_delay);
283 /* Yield remainder of our time slice, effectively giving a
284 temporary priority boost to the child process. */
289 if (rc == sizeof (char))
290 cp->status = STATUS_READ_SUCCEEDED;
292 cp->status = STATUS_READ_FAILED;
297 /* Thread proc for child process and socket reader threads. Each thread
298 is normally blocked until woken by select() to check for input by
299 reading one char. When the read completes, char_avail is signalled
300 to wake up the select emulator and the thread blocks itself again. */
302 reader_thread (void *arg)
307 cp = (child_process *)arg;
309 /* <matts@tibco.com> - I think the test below is wrong - we don't
310 want to wait for someone to signal char_consumed, as we haven't
311 read anything for them to consume yet! */
315 WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
327 rc = _sys_read_ahead (cp->fd);
329 /* The name char_avail is a misnomer - it really just means the
330 read-ahead has completed, whether successfully or not. */
331 if (!SetEvent (cp->char_avail))
333 DebPrint (("reader_thread.SetEvent failed with %lu for fd %ld\n",
334 GetLastError (), cp->fd));
338 if (rc == STATUS_READ_ERROR)
340 /* We are finished, so clean up handles and set to NULL so
341 that CHILD_ACTIVE will see what is going on */
342 if (cp->char_avail) {
343 CloseHandle (cp->char_avail);
344 cp->char_avail = NULL;
347 CloseHandle (cp->thrd);
350 if (cp->char_consumed) {
351 CloseHandle(cp->char_consumed);
352 cp->char_consumed = NULL;
354 if (cp->procinfo.hProcess)
356 CloseHandle (cp->procinfo.hProcess);
357 cp->procinfo.hProcess=NULL;
362 /* If the read died, the child has died so let the thread die */
363 if (rc == STATUS_READ_FAILED)
366 /* Wait until our input is acknowledged before reading again */
367 if (WaitForSingleObject (cp->char_consumed, INFINITE) != WAIT_OBJECT_0)
369 DebPrint (("reader_thread.WaitForSingleObject failed with "
370 "%lu for fd %ld\n", GetLastError (), cp->fd));
374 /* We are finished, so clean up handles and set to NULL so that
375 CHILD_ACTIVE will see what is going on */
376 if (cp->char_avail) {
377 CloseHandle (cp->char_avail);
378 cp->char_avail = NULL;
381 CloseHandle (cp->thrd);
384 if (cp->char_consumed) {
385 CloseHandle(cp->char_consumed);
386 cp->char_consumed = NULL;
388 if (cp->procinfo.hProcess)
390 CloseHandle (cp->procinfo.hProcess);
391 cp->procinfo.hProcess=NULL;
397 /* To avoid Emacs changing directory, we just record here the directory
398 the new process should start in. This is set just before calling
399 sys_spawnve, and is not generally valid at any other time. */
400 static const char * process_dir;
403 create_child (const char *exe, char *cmdline, char *env,
404 int * pPid, child_process *cp)
407 SECURITY_ATTRIBUTES sec_attrs;
408 SECURITY_DESCRIPTOR sec_desc;
409 char dir[ MAXPATHLEN ];
411 if (cp == NULL) abort ();
414 start.cb = sizeof (start);
417 if (NILP (Vwin32_start_process_show_window))
418 start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
420 start.dwFlags = STARTF_USESTDHANDLES;
421 start.wShowWindow = SW_HIDE;
423 start.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
424 start.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
425 start.hStdError = GetStdHandle (STD_ERROR_HANDLE);
426 #endif /* HAVE_NTGUI */
428 /* Explicitly specify no security */
429 if (!InitializeSecurityDescriptor (&sec_desc, SECURITY_DESCRIPTOR_REVISION))
431 if (!SetSecurityDescriptorDacl (&sec_desc, TRUE, NULL, FALSE))
433 sec_attrs.nLength = sizeof (sec_attrs);
434 sec_attrs.lpSecurityDescriptor = &sec_desc;
435 sec_attrs.bInheritHandle = FALSE;
437 strcpy (dir, process_dir);
438 unixtodos_filename (dir);
440 if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE,
441 (!NILP (Vwin32_start_process_share_console)
442 ? CREATE_NEW_PROCESS_GROUP
443 : CREATE_NEW_CONSOLE),
445 &start, &cp->procinfo))
448 cp->pid = (int) cp->procinfo.dwProcessId;
450 CloseHandle (cp->procinfo.hThread);
451 CloseHandle (cp->procinfo.hProcess);
452 cp->procinfo.hThread=NULL;
453 cp->procinfo.hProcess=NULL;
455 /* pid must fit in a Lisp_Int */
463 DebPrint (("create_child.CreateProcess failed: %ld\n", GetLastError()););
468 /* Return pointer to section header for section containing the given
469 relative virtual address. */
470 static IMAGE_SECTION_HEADER *
471 rva_to_section (DWORD rva, IMAGE_NT_HEADERS * nt_header)
473 PIMAGE_SECTION_HEADER section;
476 section = IMAGE_FIRST_SECTION (nt_header);
478 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
480 if (rva >= section->VirtualAddress
481 && rva < section->VirtualAddress + section->SizeOfRawData)
490 win32_executable_type (const char * filename, int * is_dos_app, int * is_cygnus_app)
492 file_data executable;
495 /* Default values in case we can't tell for sure. */
497 *is_cygnus_app = FALSE;
499 if (!open_input_file (&executable, filename))
502 p = strrchr (filename, '.');
504 /* We can only identify DOS .com programs from the extension. */
505 if (p && stricmp (p, ".com") == 0)
507 else if (p && (stricmp (p, ".bat") == 0 ||
508 stricmp (p, ".cmd") == 0))
510 /* A DOS shell script - it appears that CreateProcess is happy to
511 accept this (somewhat surprisingly); presumably it looks at
512 COMSPEC to determine what executable to actually invoke.
513 Therefore, we have to do the same here as well. */
514 /* Actually, I think it uses the program association for that
515 extension, which is defined in the registry. */
516 p = egetenv ("COMSPEC");
518 win32_executable_type (p, is_dos_app, is_cygnus_app);
522 /* Look for DOS .exe signature - if found, we must also check that
523 it isn't really a 16- or 32-bit Windows exe, since both formats
524 start with a DOS program stub. Note that 16-bit Windows
525 executables use the OS/2 1.x format. */
528 /* mingw32 doesn't have enough headers to detect cygwin
529 apps, just do what we can. */
532 exe_header = (FILHDR*) executable.file_base;
533 if (exe_header->e_magic != DOSMAGIC)
536 if ((char*) exe_header->e_lfanew > (char*) executable.size)
538 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
541 else if (exe_header->nt_signature != NT_SIGNATURE)
546 IMAGE_DOS_HEADER * dos_header;
547 IMAGE_NT_HEADERS * nt_header;
549 dos_header = (PIMAGE_DOS_HEADER) executable.file_base;
550 if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
553 nt_header = (PIMAGE_NT_HEADERS) ((char*) dos_header + dos_header->e_lfanew);
555 if ((char*) nt_header > (char*) dos_header + executable.size)
557 /* Some dos headers (pkunzip) have bogus e_lfanew fields. */
560 else if (nt_header->Signature != IMAGE_NT_SIGNATURE &&
561 LOWORD (nt_header->Signature) != IMAGE_OS2_SIGNATURE)
565 else if (nt_header->Signature == IMAGE_NT_SIGNATURE)
567 /* Look for cygwin.dll in DLL import list. */
568 IMAGE_DATA_DIRECTORY import_dir =
569 nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
570 IMAGE_IMPORT_DESCRIPTOR * imports;
571 IMAGE_SECTION_HEADER * section;
573 section = rva_to_section (import_dir.VirtualAddress, nt_header);
574 imports = (IMAGE_IMPORT_DESCRIPTOR *) RVA_TO_PTR (import_dir.VirtualAddress,
575 section, executable);
577 for ( ; imports->Name; imports++)
579 char *dllname = (char*) RVA_TO_PTR (imports->Name, section, executable);
581 if (strcmp (dllname, "cygwin.dll") == 0)
583 *is_cygnus_app = TRUE;
592 close_file_data (&executable);
596 compare_env (const void *strp1, const void *strp2)
598 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2;
600 while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
602 if ((*str1) > (*str2))
604 else if ((*str1) < (*str2))
609 if (*str1 == '=' && *str2 == '=')
611 else if (*str1 == '=')
618 merge_and_sort_env (char **envp1, char **envp2, char **new_envp)
634 qsort (new_envp, num, sizeof (char*), compare_env);
639 /* When a new child process is created we need to register it in our list,
640 so intercept spawn requests. */
642 sys_spawnve (int mode, const char *cmdname,
643 const char * const *argv, const char *const *envp)
645 Lisp_Object program, full;
646 char *cmdline, *env, *parg, **targ;
650 int is_dos_app, is_cygnus_app;
652 char escape_char = 0;
653 /* We pass our process ID to our children by setting up an environment
654 variable in their environment. */
655 char ppid_env_var_buffer[64];
656 char *extra_env[] = {ppid_env_var_buffer, NULL};
659 /* We don't care about the other modes */
660 if (mode != _P_NOWAIT)
666 /* Handle executable names without an executable suffix. */
667 program = make_string (cmdname, strlen (cmdname));
669 if (NILP (Ffile_executable_p (program)))
672 locate_file (Vexec_path, program, Vlisp_EXEC_SUFFIXES, &full, 1);
679 TO_EXTERNAL_FORMAT (LISP_STRING, full,
680 C_STRING_ALLOCA, cmdname,
685 cmdname = (char*)alloca (strlen (argv[0]) + 1);
686 strcpy ((char*)cmdname, argv[0]);
690 /* make sure argv[0] and cmdname are both in DOS format */
691 unixtodos_filename ((char*)cmdname);
693 ((const char**)argv)[0] = cmdname;
695 /* Determine whether program is a 16-bit DOS executable, or a Win32
696 executable that is implicitly linked to the Cygnus dll (implying it
697 was compiled with the Cygnus GNU toolchain and hence relies on
698 cygwin.dll to parse the command line - we use this to decide how to
699 escape quote chars in command line args that must be quoted). */
700 win32_executable_type (cmdname, &is_dos_app, &is_cygnus_app);
702 /* On Windows 95, if cmdname is a DOS app, we invoke a helper
703 application to start it by specifying the helper app as cmdname,
704 while leaving the real app name as argv[0]. */
707 cmdname = (char*) alloca (MAXPATHLEN);
708 if (egetenv ("CMDPROXY"))
709 strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
712 strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
713 strcat ((char*)cmdname, "cmdproxy.exe");
715 unixtodos_filename ((char*)cmdname);
718 /* we have to do some conjuring here to put argv and envp into the
719 form CreateProcess wants... argv needs to be a space separated/null
720 terminated list of parameters, and envp is a null
721 separated/double-null terminated list of parameters.
723 Additionally, zero-length args and args containing whitespace or
724 quote chars need to be wrapped in double quotes - for this to work,
725 embedded quotes need to be escaped as well. The aim is to ensure
726 the child process reconstructs the argv array we start with
727 exactly, so we treat quotes at the beginning and end of arguments
730 The Win32 GNU-based library from Cygnus doubles quotes to escape
731 them, while MSVC uses backslash for escaping. (Actually the MSVC
732 startup code does attempt to recognize doubled quotes and accept
733 them, but gets it wrong and ends up requiring three quotes to get a
734 single embedded quote!) So by default we decide whether to use
735 quote or backslash as the escape character based on whether the
736 binary is apparently a Cygnus compiled app.
738 Note that using backslash to escape embedded quotes requires
739 additional special handling if an embedded quote is already
740 preceded by backslash, or if an arg requiring quoting ends with
741 backslash. In such cases, the run of escape characters needs to be
742 doubled. For consistency, we apply this special handling as long
743 as the escape character is not quote.
745 Since we have no idea how large argv and envp are likely to be we
746 figure out list lengths on the fly and allocate them. */
748 if (!NILP (Vwin32_quote_process_args))
751 /* Override escape char by binding win32-quote-process-args to
752 desired character, or use t for auto-selection. */
753 if (INTP (Vwin32_quote_process_args))
754 escape_char = XINT (Vwin32_quote_process_args);
756 escape_char = is_cygnus_app ? '"' : '\\';
766 int escape_char_run = 0;
774 /* allow for embedded quotes to be escaped */
777 /* handle the case where the embedded quote is already escaped */
778 if (escape_char_run > 0)
780 /* To preserve the arg exactly, we need to double the
781 preceding escape characters (plus adding one to
782 escape the quote character itself). */
783 arglen += escape_char_run;
786 else if (*p == ' ' || *p == '\t')
791 if (*p == escape_char && escape_char != '"')
799 /* handle the case where the arg ends with an escape char - we
800 must not let the enclosing quote be escaped. */
801 if (escape_char_run > 0)
802 arglen += escape_char_run;
804 arglen += strlen (*targ++) + 1;
806 cmdline = (char*) alloca (arglen);
820 if (*p == ' ' || *p == '\t' || *p == '"')
825 int escape_char_run = 0;
831 last = p + strlen (p) - 1;
834 /* This version does not escape quotes if they occur at the
835 beginning or end of the arg - this could lead to incorrect
836 behavior when the arg itself represents a command line
837 containing quoted args. I believe this was originally done
838 as a hack to make some things work, before
839 `win32-quote-process-args' was added. */
842 if (*p == '"' && p > first && p < last)
843 *parg++ = escape_char; /* escape embedded quotes */
851 /* double preceding escape chars if any */
852 while (escape_char_run > 0)
854 *parg++ = escape_char;
857 /* escape all quote chars, even at beginning or end */
858 *parg++ = escape_char;
862 if (*p == escape_char && escape_char != '"')
867 /* double escape chars before enclosing quote */
868 while (escape_char_run > 0)
870 *parg++ = escape_char;
878 strcpy (parg, *targ);
879 parg += strlen (*targ);
888 targ = (char**) envp;
889 numenv = 1; /* for end null */
892 arglen += strlen (*targ++) + 1;
895 /* extra env vars... */
896 sprintf (ppid_env_var_buffer, "__PARENT_PROCESS_ID=%d",
897 GetCurrentProcessId ());
898 arglen += strlen (ppid_env_var_buffer) + 1;
901 /* merge env passed in and extra env into one, and sort it. */
902 targ = (char **) alloca (numenv * sizeof (char*));
903 merge_and_sort_env ((char**) envp, extra_env, targ);
905 /* concatenate env entries. */
906 env = (char*) alloca (arglen);
910 strcpy (parg, *targ);
911 parg += strlen (*targ++);
924 /* Now create the process. */
925 if (!create_child (cmdname, cmdline, env, &pid, cp))
935 /* Substitute for certain kill () operations */
938 find_child_console (HWND hwnd, child_process * cp)
943 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
944 if (process_id == cp->procinfo.dwProcessId)
946 char window_class[32];
948 GetClassName (hwnd, window_class, sizeof (window_class));
949 if (strcmp (window_class,
952 : "ConsoleWindowClass") == 0)
963 sys_kill (int pid, int sig)
967 int need_to_free = 0;
970 /* Only handle signals that will result in the process dying */
971 if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP)
977 cp = find_child_pid (pid);
980 proc_hand = OpenProcess (PROCESS_TERMINATE, 0, pid);
981 if (proc_hand == NULL)
990 proc_hand = cp->procinfo.hProcess;
991 pid = cp->procinfo.dwProcessId;
993 /* Try to locate console window for process. */
994 EnumWindows ((WNDENUMPROC)find_child_console, (LPARAM) cp);
999 if (NILP (Vwin32_start_process_share_console) && cp && cp->hwnd)
1001 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
1002 BYTE vk_break_code = VK_CANCEL;
1003 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
1004 HWND foreground_window;
1006 if (break_scan_code == 0)
1008 /* Fake Ctrl-C if we can't manage Ctrl-Break. */
1009 vk_break_code = 'C';
1010 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
1013 foreground_window = GetForegroundWindow ();
1014 if (foreground_window && SetForegroundWindow (cp->hwnd))
1016 /* Generate keystrokes as if user had typed Ctrl-Break or Ctrl-C. */
1017 keybd_event (VK_CONTROL, control_scan_code, 0, 0);
1018 keybd_event (vk_break_code, break_scan_code, 0, 0);
1019 keybd_event (vk_break_code, break_scan_code, KEYEVENTF_KEYUP, 0);
1020 keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
1022 /* Sleep for a bit to give time for Emacs frame to respond
1023 to focus change events (if Emacs was active app). */
1026 SetForegroundWindow (foreground_window);
1029 /* Ctrl-Break is NT equivalent of SIGINT. */
1030 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
1032 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
1033 "for pid %lu\n", GetLastError (), pid));
1040 if (NILP (Vwin32_start_process_share_console) && cp && cp->hwnd)
1046 Another possibility is to try terminating the VDM out-right by
1047 calling the Shell VxD (id 0x17) V86 interface, function #4
1048 "SHELL_Destroy_VM", ie.
1054 First need to determine the current VM handle, and then arrange for
1055 the shellapi call to be made from the system vm (by using
1056 Switch_VM_and_callback).
1058 Could try to invoke DestroyVM through CallVxD.
1062 /* On Win95, posting WM_QUIT causes the 16-bit subsystem
1063 to hang when cmdproxy is used in conjunction with
1064 command.com for an interactive shell. Posting
1065 WM_CLOSE pops up a dialog that, when Yes is selected,
1066 does the same thing. TerminateProcess is also less
1067 than ideal in that subprocesses tend to stick around
1068 until the machine is shutdown, but at least it
1069 doesn't freeze the 16-bit subsystem. */
1070 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
1072 if (!TerminateProcess (proc_hand, 0xff))
1074 DebPrint (("sys_kill.TerminateProcess returned %d "
1075 "for pid %lu\n", GetLastError (), pid));
1082 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
1084 /* Kill the process. On Win32 this doesn't kill child processes
1085 so it doesn't work very well for shells which is why it's not
1086 used in every case. */
1087 else if (!TerminateProcess (proc_hand, 0xff))
1089 DebPrint (("sys_kill.TerminateProcess returned %d "
1090 "for pid %lu\n", GetLastError (), pid));
1097 CloseHandle (proc_hand);
1103 /* Sync with FSF Emacs 19.34.6 note: ifdef'ed out in XEmacs */
1104 extern int report_file_error (const char *, Lisp_Object);
1106 /* The following two routines are used to manipulate stdin, stdout, and
1107 stderr of our child processes.
1109 Assuming that in, out, and err are *not* inheritable, we make them
1110 stdin, stdout, and stderr of the child as follows:
1112 - Save the parent's current standard handles.
1113 - Set the std handles to inheritable duplicates of the ones being passed in.
1114 (Note that _get_osfhandle() is an io.h procedure that retrieves the
1115 NT file handle for a crt file descriptor.)
1116 - Spawn the child, which inherits in, out, and err as stdin,
1117 stdout, and stderr. (see Spawnve)
1118 - Close the std handles passed to the child.
1119 - Reset the parent's standard handles to the saved handles.
1120 (see reset_standard_handles)
1121 We assume that the caller closes in, out, and err after calling us. */
1124 prepare_standard_handles (int in, int out, int err, HANDLE handles[3])
1127 HANDLE newstdin, newstdout, newstderr;
1129 parent = GetCurrentProcess ();
1131 handles[0] = GetStdHandle (STD_INPUT_HANDLE);
1132 handles[1] = GetStdHandle (STD_OUTPUT_HANDLE);
1133 handles[2] = GetStdHandle (STD_ERROR_HANDLE);
1135 /* make inheritable copies of the new handles */
1136 if (!DuplicateHandle (parent,
1137 (HANDLE) _get_osfhandle (in),
1142 DUPLICATE_SAME_ACCESS))
1143 report_file_error ("Duplicating input handle for child", Qnil);
1145 if (!DuplicateHandle (parent,
1146 (HANDLE) _get_osfhandle (out),
1151 DUPLICATE_SAME_ACCESS))
1152 report_file_error ("Duplicating output handle for child", Qnil);
1154 if (!DuplicateHandle (parent,
1155 (HANDLE) _get_osfhandle (err),
1160 DUPLICATE_SAME_ACCESS))
1161 report_file_error ("Duplicating error handle for child", Qnil);
1163 /* and store them as our std handles */
1164 if (!SetStdHandle (STD_INPUT_HANDLE, newstdin))
1165 report_file_error ("Changing stdin handle", Qnil);
1167 if (!SetStdHandle (STD_OUTPUT_HANDLE, newstdout))
1168 report_file_error ("Changing stdout handle", Qnil);
1170 if (!SetStdHandle (STD_ERROR_HANDLE, newstderr))
1171 report_file_error ("Changing stderr handle", Qnil);
1175 reset_standard_handles (int in, int out, int err, HANDLE handles[3])
1177 /* close the duplicated handles passed to the child */
1178 CloseHandle (GetStdHandle (STD_INPUT_HANDLE));
1179 CloseHandle (GetStdHandle (STD_OUTPUT_HANDLE));
1180 CloseHandle (GetStdHandle (STD_ERROR_HANDLE));
1182 /* now restore parent's saved std handles */
1183 SetStdHandle (STD_INPUT_HANDLE, handles[0]);
1184 SetStdHandle (STD_OUTPUT_HANDLE, handles[1]);
1185 SetStdHandle (STD_ERROR_HANDLE, handles[2]);
1189 set_process_dir (const char * dir)
1194 /* Some miscellaneous functions that are Windows specific, but not GUI
1195 specific (ie. are applicable in terminal or batch mode as well). */
1197 /* lifted from fileio.c */
1198 #define CORRECT_DIR_SEPS(s) \
1199 do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
1200 else unixtodos_filename (s); \
1203 DEFUN ("win32-short-file-name", Fwin32_short_file_name, 1, 1, "", /*
1204 Return the short file name version (8.3) of the full path of FILENAME.
1205 If FILENAME does not exist, return nil.
1206 All path elements in FILENAME are converted to their short names.
1210 char shortname[MAX_PATH];
1212 CHECK_STRING (filename);
1214 /* first expand it. */
1215 filename = Fexpand_file_name (filename, Qnil);
1217 /* luckily, this returns the short version of each element in the path. */
1218 if (GetShortPathName (XSTRING_DATA (filename), shortname, MAX_PATH) == 0)
1221 CORRECT_DIR_SEPS (shortname);
1223 return build_string (shortname);
1227 DEFUN ("win32-long-file-name", Fwin32_long_file_name, 1, 1, "", /*
1228 Return the long file name version of the full path of FILENAME.
1229 If FILENAME does not exist, return nil.
1230 All path elements in FILENAME are converted to their long names.
1234 char longname[ MAX_PATH ];
1236 CHECK_STRING (filename);
1238 /* first expand it. */
1239 filename = Fexpand_file_name (filename, Qnil);
1241 if (!win32_get_long_filename (XSTRING_DATA (filename), longname, MAX_PATH))
1244 CORRECT_DIR_SEPS (longname);
1246 return build_string (longname);
1249 DEFUN ("win32-set-process-priority", Fwin32_set_process_priority, 2, 2, "", /*
1250 Set the priority of PROCESS to PRIORITY.
1251 If PROCESS is nil, the priority of Emacs is changed, otherwise the
1252 priority of the process whose pid is PROCESS is changed.
1253 PRIORITY should be one of the symbols high, normal, or low;
1254 any other symbol will be interpreted as normal.
1256 If successful, the return value is t, otherwise nil.
1258 (process, priority))
1260 HANDLE proc_handle = GetCurrentProcess ();
1261 DWORD priority_class = NORMAL_PRIORITY_CLASS;
1262 Lisp_Object result = Qnil;
1264 CHECK_SYMBOL (priority);
1266 if (!NILP (process))
1271 CHECK_INT (process);
1273 /* Allow pid to be an internally generated one, or one obtained
1274 externally. This is necessary because real pids on Win95 are
1277 pid = XINT (process);
1278 cp = find_child_pid (pid);
1280 pid = cp->procinfo.dwProcessId;
1282 proc_handle = OpenProcess (PROCESS_SET_INFORMATION, FALSE, pid);
1285 if (EQ (priority, Qhigh))
1286 priority_class = HIGH_PRIORITY_CLASS;
1287 else if (EQ (priority, Qlow))
1288 priority_class = IDLE_PRIORITY_CLASS;
1290 if (proc_handle != NULL)
1292 if (SetPriorityClass (proc_handle, priority_class))
1294 if (!NILP (process))
1295 CloseHandle (proc_handle);
1302 DEFUN ("win32-get-locale-info", Fwin32_get_locale_info, 1, 2, "", /*
1303 "Return information about the Windows locale LCID.
1304 By default, return a three letter locale code which encodes the default
1305 language as the first two characters, and the country or regional variant
1306 as the third letter. For example, ENU refers to `English (United States)',
1307 while ENC means `English (Canadian)'.
1309 If the optional argument LONGFORM is non-nil, the long form of the locale
1310 name is returned, e.g. `English (United States)' instead.
1312 If LCID (a 16-bit number) is not a valid locale, the result is nil.
1318 char abbrev_name[32] = { 0 };
1319 char full_name[256] = { 0 };
1323 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
1326 if (NILP (longform))
1328 got_abbrev = GetLocaleInfo (XINT (lcid),
1329 LOCALE_SABBREVLANGNAME | LOCALE_USE_CP_ACP,
1330 abbrev_name, sizeof (abbrev_name));
1332 return build_string (abbrev_name);
1336 got_full = GetLocaleInfo (XINT (lcid),
1337 LOCALE_SLANGUAGE | LOCALE_USE_CP_ACP,
1338 full_name, sizeof (full_name));
1340 return build_string (full_name);
1347 DEFUN ("win32-get-current-locale-id", Fwin32_get_current_locale_id, 0, 0, "", /*
1348 "Return Windows locale id for current locale setting.
1349 This is a numerical value; use `win32-get-locale-info' to convert to a
1350 human-readable form.
1354 return make_int (GetThreadLocale ());
1358 DEFUN ("win32-get-default-locale-id", Fwin32_get_default_locale_id, 0, 1, "", /*
1359 "Return Windows locale id for default locale setting.
1360 By default, the system default locale setting is returned; if the optional
1361 parameter USERP is non-nil, the user default locale setting is returned.
1362 This is a numerical value; use `win32-get-locale-info' to convert to a
1363 human-readable form.
1368 return make_int (GetSystemDefaultLCID ());
1369 return make_int (GetUserDefaultLCID ());
1372 DWORD int_from_hex (char * s)
1375 static char hex[] = "0123456789abcdefABCDEF";
1378 while (*s && (p = strchr(hex, *s)) != NULL)
1380 unsigned digit = p - hex;
1383 val = val * 16 + digit;
1389 /* We need to build a global list, since the EnumSystemLocale callback
1390 function isn't given a context pointer. */
1391 Lisp_Object Vwin32_valid_locale_ids;
1393 BOOL CALLBACK enum_locale_fn (LPTSTR localeNum)
1395 DWORD id = int_from_hex (localeNum);
1396 Vwin32_valid_locale_ids = Fcons (make_int (id), Vwin32_valid_locale_ids);
1400 DEFUN ("win32-get-valid-locale-ids", Fwin32_get_valid_locale_ids, 0, 0, "", /*
1401 Return list of all valid Windows locale ids.
1402 Each id is a numerical value; use `win32-get-locale-info' to convert to a
1403 human-readable form.
1407 Vwin32_valid_locale_ids = Qnil;
1409 EnumSystemLocales (enum_locale_fn, LCID_SUPPORTED);
1411 Vwin32_valid_locale_ids = Fnreverse (Vwin32_valid_locale_ids);
1412 return Vwin32_valid_locale_ids;
1416 DEFUN ("win32-set-current-locale", Fwin32_set_current_locale, 1, 1, "", /*
1417 Make Windows locale LCID be the current locale setting for Emacs.
1418 If successful, the new locale id is returned, otherwise nil.
1424 if (!IsValidLocale (XINT (lcid), LCID_SUPPORTED))
1427 if (!SetThreadLocale (XINT (lcid)))
1430 /* Sync with FSF Emacs 19.34.6 note: dwWinThreadId declared in
1431 w32term.h and defined in w32fns.c, both of which are not in current
1432 XEmacs. #### Check what we lose by ifdef'ing out these. --marcpa */
1434 /* Need to set input thread locale if present. */
1436 /* Reply is not needed. */
1437 PostThreadMessage (dwWinThreadId, WM_EMACS_SETLOCALE, XINT (lcid), 0);
1440 return make_int (GetThreadLocale ());
1447 DEFSUBR (Fwin32_short_file_name);
1448 DEFSUBR (Fwin32_long_file_name);
1449 DEFSUBR (Fwin32_set_process_priority);
1450 DEFSUBR (Fwin32_get_locale_info);
1451 DEFSUBR (Fwin32_get_current_locale_id);
1452 DEFSUBR (Fwin32_get_default_locale_id);
1453 DEFSUBR (Fwin32_get_valid_locale_ids);
1454 DEFSUBR (Fwin32_set_current_locale);
1459 vars_of_ntproc (void)
1461 defsymbol (&Qhigh, "high");
1462 defsymbol (&Qlow, "low");
1464 DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /*
1465 Non-nil enables quoting of process arguments to ensure correct parsing.
1466 Because Windows does not directly pass argv arrays to child processes,
1467 programs have to reconstruct the argv array by parsing the command
1468 line string. For an argument to contain a space, it must be enclosed
1469 in double quotes or it will be parsed as multiple arguments.
1471 If the value is a character, that character will be used to escape any
1472 quote characters that appear, otherwise a suitable escape character
1473 will be chosen based on the type of the program.
1475 Vwin32_quote_process_args = Qt;
1477 DEFVAR_LISP ("win32-start-process-show-window",
1478 &Vwin32_start_process_show_window /*
1479 When nil, processes started via start-process hide their windows.
1480 When non-nil, they show their window in the method of their choice.
1482 Vwin32_start_process_show_window = Qnil;
1484 DEFVAR_LISP ("win32-start-process-share-console",
1485 &Vwin32_start_process_share_console /*
1486 When nil, processes started via start-process are given a new console.
1487 When non-nil, they share the Emacs console; this has the limitation of
1488 allowing only only DOS subprocess to run at a time (whether started directly
1489 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1490 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1491 otherwise respond to interrupts from Emacs.
1493 Vwin32_start_process_share_console = Qt;
1495 DEFVAR_LISP ("win32-pipe-read-delay", &Vwin32_pipe_read_delay /*
1496 Forced delay before reading subprocess output.
1497 This is done to improve the buffering of subprocess output, by
1498 avoiding the inefficiency of frequently reading small amounts of data.
1500 If positive, the value is the number of milliseconds to sleep before
1501 reading the subprocess output. If negative, the magnitude is the number
1502 of time slices to wait (effectively boosting the priority of the child
1503 process temporarily). A value of zero disables waiting entirely.
1505 Vwin32_pipe_read_delay = make_int (50);
1508 DEFVAR_LISP ("win32-generate-fake-inodes", &Vwin32_generate_fake_inodes /*
1509 "Non-nil means attempt to fake realistic inode values.
1510 This works by hashing the truename of files, and should detect
1511 aliasing between long and short (8.3 DOS) names, but can have
1512 false positives because of hash collisions. Note that determining
1513 the truename of a file can be slow.
1515 Vwin32_generate_fake_inodes = Qnil;
1519 /* end of ntproc.c */