1 /* Asynchronous subprocess implementation for Win32
2 Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995
3 Free Software Foundation, Inc.
4 Copyright (C) 1995 Sun Microsystems, Inc.
5 Copyright (C) 1995, 1996, 2000 Ben Wing.
7 This file is part of XEmacs.
9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with XEmacs; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 /* Written by Kirill M. Katsnelson <kkm@kis.ru>, April 1998 */
30 #include "console-msw.h"
47 /* Arbitrary size limit for code fragments passed to run_in_other_process */
48 #define FRAGMENT_CODE_SIZE 32
50 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */
51 struct nt_process_data
55 HWND hwnd; /* console window */
56 int need_enable_child_signals;
59 /* Control how args are quoted to ensure correct parsing by child
61 Lisp_Object Vmswindows_quote_process_args;
63 /* Control whether create_child causes the process to inherit Emacs'
64 console window, or be given a new one of its own. The default is
65 nil, to allow multiple DOS programs to run on Win95. Having separate
66 consoles also allows Emacs to cleanly terminate process groups. */
67 Lisp_Object Vmswindows_start_process_share_console;
69 /* Control whether create_child cause the process to inherit Emacs'
70 error mode setting. The default is t, to minimize the possibility of
71 subprocesses blocking when accessing unmounted drives. */
72 Lisp_Object Vmswindows_start_process_inherit_error_mode;
74 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
76 /*-----------------------------------------------------------------------*/
78 /*-----------------------------------------------------------------------*/
80 /* This one breaks process abstraction. Prototype is in console-msw.h,
81 used by select_process method in event-msw.c */
83 get_nt_process_handle (Lisp_Process *p)
85 return (NT_DATA (p)->h_process);
88 static struct Lisp_Process *
89 find_process_from_pid (DWORD pid)
91 Lisp_Object tail, proc;
93 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
96 if (NT_DATA (XPROCESS (proc))->dwProcessId == pid)
97 return XPROCESS (proc);
103 /*-----------------------------------------------------------------------*/
104 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5 */
105 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/
106 /*-----------------------------------------------------------------------*/
116 * Allocate SIZE bytes in H_PROCESS address space. Fill in PMC used
117 * further by other routines. Return nonzero if successful.
119 * The memory in other process is allocated by creating a suspended
120 * thread. Initial stack of that thread is used as the memory
121 * block. The thread entry point is the routine ExitThread in
122 * kernel32.dll, so the allocated memory is freed just by resuming the
123 * thread, which immediately terminates after that.
127 alloc_process_memory (HANDLE h_process, size_t size,
130 LPTHREAD_START_ROUTINE adr_ExitThread =
131 (LPTHREAD_START_ROUTINE)
132 GetProcAddress (GetModuleHandle ("kernel32"), "ExitThread");
135 MEMORY_BASIC_INFORMATION mbi;
137 pmc->h_process = h_process;
138 pmc->h_thread = CreateRemoteThread (h_process, NULL, size,
139 adr_ExitThread, NULL,
140 CREATE_SUSPENDED, &dw_unused);
141 if (pmc->h_thread == NULL)
144 /* Get context, for thread's stack pointer */
145 context.ContextFlags = CONTEXT_CONTROL;
146 if (!GetThreadContext (pmc->h_thread, &context))
149 /* Determine base address of the committed range */
150 if (sizeof(mbi) != VirtualQueryEx (h_process,
152 (LPDWORD)context.Esp - 1,
153 #elif defined (_ALPHA_)
154 (LPDWORD)context.IntSp - 1,
156 #error Unknown processor architecture
161 /* Change the page protection of the allocated memory to executable,
163 if (!VirtualProtectEx (h_process, mbi.BaseAddress, size,
164 PAGE_EXECUTE_READWRITE, &dw_unused))
167 pmc->address = mbi.BaseAddress;
171 ResumeThread (pmc->h_thread);
177 free_process_memory (process_memory* pmc)
179 ResumeThread (pmc->h_thread);
183 * Run ROUTINE in the context of process determined by H_PROCESS. The
184 * routine is passed the address of DATA as parameter. The ROUTINE must
185 * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of
188 * Note that the code must be positionally independent, and compiled
189 * without stack checks (they cause implicit calls into CRT so will
190 * fail). DATA should not refer any data in calling process, as both
191 * routine and its data are copied into remote process. Size of data
192 * and code together should not exceed one page (4K on x86 systems).
194 * Return the value returned by ROUTINE, or (DWORD)-1 if call failed.
197 run_in_other_process (HANDLE h_process,
198 LPTHREAD_START_ROUTINE routine,
199 LPVOID data, size_t data_size)
202 const size_t code_size = FRAGMENT_CODE_SIZE;
203 /* Need at most 3 extra bytes of memory, for data alignment */
204 size_t total_size = code_size + data_size + 3;
209 /* Allocate memory */
210 if (!alloc_process_memory (h_process, total_size, &pm))
214 if (!WriteProcessMemory (h_process, pm.address, (LPVOID)routine,
221 remote_data = (LPBYTE)pm.address + ((code_size + 4) & ~3);
222 if (!WriteProcessMemory (h_process, remote_data, data, data_size, NULL))
228 /* Execute the remote copy of code, passing it remote data */
229 h_thread = CreateRemoteThread (h_process, NULL, 0,
230 (LPTHREAD_START_ROUTINE) pm.address,
231 remote_data, 0, &dw_unused);
232 if (h_thread == NULL)
235 /* Wait till thread finishes */
236 WaitForSingleObject (h_thread, INFINITE);
238 /* Free remote memory */
239 free_process_memory (&pm);
241 /* Return thread's exit code */
244 GetExitCodeThread (h_thread, &exit_code);
245 CloseHandle (h_thread);
250 free_process_memory (&pm);
254 /*-----------------------------------------------------------------------*/
255 /* Sending signals */
256 /*-----------------------------------------------------------------------*/
258 /* ---------------------------- the NT way ------------------------------- */
261 * We handle the following signals:
263 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
264 * executed by the remote process
265 * SIGINT - The remote process is sent CTRL_BREAK_EVENT
267 * The MSVC5.0 compiler feels free to re-order functions within a
268 * compilation unit, so we have no way of finding out the size of the
269 * following functions. Therefore these functions must not be larger than
270 * FRAGMENT_CODE_SIZE.
278 void (WINAPI *adr_ExitProcess) (UINT);
282 sigkill_proc (sigkill_data* data)
284 (*data->adr_ExitProcess)(255);
289 * Sending break or control c
293 BOOL (WINAPI *adr_GenerateConsoleCtrlEvent) (DWORD, DWORD);
298 sigint_proc (sigint_data* data)
300 return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
308 BOOL (WINAPI *adr_SetConsoleCtrlHandler) (LPVOID, BOOL);
312 sig_enable_proc (sig_enable_data* data)
314 (*data->adr_SetConsoleCtrlHandler) (NULL, FALSE);
319 * Send signal SIGNO to process H_PROCESS.
320 * Return nonzero if successful.
324 send_signal_the_nt_way (struct nt_process_data *cp, int pid, int signo)
327 HMODULE h_kernel = GetModuleHandle ("kernel32");
328 int close_process = 0;
331 assert (h_kernel != NULL);
335 pid = cp->dwProcessId;
336 h_process = cp->h_process;
341 /* Try to open the process with required privileges */
342 h_process = OpenProcess (PROCESS_CREATE_THREAD
343 | PROCESS_QUERY_INFORMATION
344 | PROCESS_VM_OPERATION
361 (void (WINAPI *) (UINT)) GetProcAddress (h_kernel, "ExitProcess");
362 assert (d.adr_ExitProcess);
363 retval = run_in_other_process (h_process,
364 (LPTHREAD_START_ROUTINE)sigkill_proc,
371 d.adr_GenerateConsoleCtrlEvent =
372 (BOOL (WINAPI *) (DWORD, DWORD))
373 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
374 assert (d.adr_GenerateConsoleCtrlEvent);
375 d.event = CTRL_C_EVENT;
376 retval = run_in_other_process (h_process,
377 (LPTHREAD_START_ROUTINE)sigint_proc,
386 CloseHandle (h_process);
387 return (int)retval > 0 ? 1 : 0;
391 * Enable CTRL_C_EVENT handling in a new child process
394 enable_child_signals (HANDLE h_process)
396 HMODULE h_kernel = GetModuleHandle ("kernel32");
399 assert (h_kernel != NULL);
400 d.adr_SetConsoleCtrlHandler =
401 (BOOL (WINAPI *) (LPVOID, BOOL))
402 GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
403 assert (d.adr_SetConsoleCtrlHandler);
404 run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
408 #pragma warning (default : 4113)
410 /* ---------------------------- the 95 way ------------------------------- */
413 find_child_console (HWND hwnd, struct nt_process_data *cp)
418 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
419 if (process_id == cp->dwProcessId)
421 char window_class[32];
423 GetClassName (hwnd, window_class, sizeof (window_class));
424 if (strcmp (window_class,
427 : "ConsoleWindowClass") == 0)
438 send_signal_the_95_way (struct nt_process_data *cp, int pid, int signo)
441 int close_process = 0;
446 pid = cp->dwProcessId;
447 h_process = cp->h_process;
449 /* Try to locate console window for process. */
450 EnumWindows (find_child_console, (LPARAM) cp);
455 /* Try to open the process with required privileges */
456 h_process = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
463 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
465 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
466 BYTE vk_break_code = VK_CANCEL;
467 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
468 HWND foreground_window;
470 if (break_scan_code == 0)
472 /* Fake Ctrl-C if we can't manage Ctrl-Break. */
474 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
477 foreground_window = GetForegroundWindow ();
478 if (foreground_window)
480 /* NT 5.0, and apparently also Windows 98, will not allow
481 a Window to be set to foreground directly without the
482 user's involvement. The workaround is to attach
483 ourselves to the thread that owns the foreground
484 window, since that is the only thread that can set the
485 foreground window. */
486 DWORD foreground_thread, child_thread;
488 GetWindowThreadProcessId (foreground_window, NULL);
489 if (foreground_thread == GetCurrentThreadId ()
490 || !AttachThreadInput (GetCurrentThreadId (),
491 foreground_thread, TRUE))
492 foreground_thread = 0;
494 child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
495 if (child_thread == GetCurrentThreadId ()
496 || !AttachThreadInput (GetCurrentThreadId (),
500 /* Set the foreground window to the child. */
501 if (SetForegroundWindow (cp->hwnd))
503 /* Generate keystrokes as if user had typed Ctrl-Break or
505 keybd_event (VK_CONTROL, control_scan_code, 0, 0);
506 keybd_event (vk_break_code, break_scan_code,
507 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
508 keybd_event (vk_break_code, break_scan_code,
509 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
510 | KEYEVENTF_KEYUP, 0);
511 keybd_event (VK_CONTROL, control_scan_code,
514 /* Sleep for a bit to give time for Emacs frame to respond
515 to focus change events (if Emacs was active app). */
518 SetForegroundWindow (foreground_window);
520 /* Detach from the foreground and child threads now that
521 the foreground switching is over. */
522 if (foreground_thread)
523 AttachThreadInput (GetCurrentThreadId (),
524 foreground_thread, FALSE);
526 AttachThreadInput (GetCurrentThreadId (),
527 child_thread, FALSE);
530 /* Ctrl-Break is NT equivalent of SIGINT. */
531 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
533 #if 0 /* FSF Emacs */
534 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
535 "for pid %lu\n", GetLastError (), pid));
543 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
546 if (msw_windows9x_p ())
549 Another possibility is to try terminating the VDM out-right by
550 calling the Shell VxD (id 0x17) V86 interface, function #4
551 "SHELL_Destroy_VM", ie.
557 First need to determine the current VM handle, and then arrange for
558 the shellapi call to be made from the system vm (by using
559 Switch_VM_and_callback).
561 Could try to invoke DestroyVM through CallVxD.
565 /* On Win95, posting WM_QUIT causes the 16-bit subsystem
566 to hang when cmdproxy is used in conjunction with
567 command.com for an interactive shell. Posting
568 WM_CLOSE pops up a dialog that, when Yes is selected,
569 does the same thing. TerminateProcess is also less
570 than ideal in that subprocesses tend to stick around
571 until the machine is shutdown, but at least it
572 doesn't freeze the 16-bit subsystem. */
573 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
575 if (!TerminateProcess (h_process, 0xff))
577 #if 0 /* FSF Emacs */
578 DebPrint (("sys_kill.TerminateProcess returned %d "
579 "for pid %lu\n", GetLastError (), pid));
587 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
589 /* Kill the process. On W32 this doesn't kill child processes
590 so it doesn't work very well for shells which is why it's not
591 used in every case. */
592 else if (!TerminateProcess (h_process, 0xff))
594 #if 0 /* FSF Emacs */
595 DebPrint (("sys_kill.TerminateProcess returned %d "
596 "for pid %lu\n", GetLastError (), pid));
604 CloseHandle (h_process);
609 /* -------------------------- all-OS functions ---------------------------- */
612 send_signal (struct nt_process_data *cp, int pid, int signo)
614 return send_signal_the_nt_way (cp, pid, signo)
615 || send_signal_the_95_way (cp, pid, signo);
619 * Signal error if SIGNO is not supported
622 validate_signal_number (int signo)
624 if (signo != SIGKILL && signo != SIGTERM
625 && signo != SIGQUIT && signo != SIGINT
627 signal_simple_error ("Signal number not supported", make_int (signo));
630 /*-----------------------------------------------------------------------*/
631 /* Process methods */
632 /*-----------------------------------------------------------------------*/
635 * Allocate and initialize Lisp_Process->process_data
639 nt_alloc_process_data (Lisp_Process *p)
641 p->process_data = xnew_and_zero (struct nt_process_data);
645 nt_finalize_process_data (Lisp_Process *p, int for_disksave)
647 assert (!for_disksave);
648 if (NT_DATA (p)->h_process)
649 CloseHandle (NT_DATA (p)->h_process);
653 * Initialize XEmacs process implementation once
656 nt_init_process (void)
658 /* Initialize winsock */
660 /* Request Winsock v1.1 Note the order: (minor=1, major=1) */
661 WSAStartup (MAKEWORD (1,1), &wsa_data);
665 * Fork off a subprocess. P is a pointer to newly created subprocess
666 * object. If this function signals, the caller is responsible for
667 * deleting (and finalizing) the process object.
669 * The method must return PID of the new process, a (positive??? ####) number
670 * which fits into Lisp_Int. No return value indicates an error, the method
671 * must signal an error instead.
675 signal_cannot_launch (Lisp_Object image_file, DWORD err)
677 mswindows_set_errno (err);
678 signal_simple_error_2 ("Error starting", image_file, lisp_strerror (errno));
682 ensure_console_window_exists (void)
684 if (msw_windows9x_p ())
689 compare_env (const void *strp1, const void *strp2)
691 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2;
693 while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
695 if ((*str1) > (*str2))
697 else if ((*str1) < (*str2))
702 if (*str1 == '=' && *str2 == '=')
704 else if (*str1 == '=')
711 nt_create_process (Lisp_Process *p,
712 Lisp_Object *argv, int nargv,
713 Lisp_Object program, Lisp_Object cur_dir)
715 /* Synched up with sys_spawnve in FSF 20.6. Significantly different
716 but still synchable. */
717 HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
718 Extbyte *command_line;
719 BOOL do_io, windowed;
722 /* No need to DOS-ize the filename; expand-file-name (called prior)
723 already does this. */
725 /* Find out whether the application is windowed or not */
727 /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most
728 errors. This leads to bogus error message. */
730 char *p = strrchr ((char *)XSTRING_DATA (program), '.');
732 (stricmp (p, ".exe") == 0 ||
733 stricmp (p, ".com") == 0 ||
734 stricmp (p, ".bat") == 0 ||
735 stricmp (p, ".cmd") == 0))
737 image_type = SHGetFileInfo ((char *)XSTRING_DATA (program), 0,NULL,
742 char progname[MAX_PATH];
743 sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program));
744 image_type = SHGetFileInfo (progname, 0, NULL, 0, SHGFI_EXETYPE);
747 signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND
748 ? ERROR_BAD_FORMAT : GetLastError ()));
749 windowed = HIWORD (image_type) != 0;
752 /* Decide whether to do I/O on process handles, or just mark the
753 process exited immediately upon successful launching. We do I/O if the
754 process is a console one, or if it is windowed but windowed_process_io
756 do_io = !windowed || windowed_process_io ;
760 /* Create two unidirectional named pipes */
762 SECURITY_ATTRIBUTES sa;
764 sa.nLength = sizeof(sa);
765 sa.bInheritHandle = TRUE;
766 sa.lpSecurityDescriptor = NULL;
768 CreatePipe (&hprocin, &hmyshove, &sa, 0);
769 CreatePipe (&hmyslurp, &hprocout, &sa, 0);
771 /* Duplicate the stdout handle for use as stderr */
772 DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(),
773 &hprocerr, 0, TRUE, DUPLICATE_SAME_ACCESS);
775 /* Stupid Win32 allows to create a pipe with *both* ends either
776 inheritable or not. We need process ends inheritable, and local
777 ends not inheritable. */
778 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(),
780 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
782 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(),
784 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
788 /* Convert an argv vector into Win32 style command line. */
791 Bufbyte **quoted_args;
792 int is_dos_app, is_cygnus_app;
794 char escape_char = 0;
796 nargv++; /* include program; we access argv offset by 1 below */
797 quoted_args = alloca_array (Bufbyte *, nargv);
799 /* Determine whether program is a 16-bit DOS executable, or a Win32
800 executable that is implicitly linked to the Cygnus dll (implying it
801 was compiled with the Cygnus GNU toolchain and hence relies on
802 cygwin.dll to parse the command line - we use this to decide how to
803 escape quote chars in command line args that must be quoted). */
804 mswindows_executable_type (XSTRING_DATA (program),
805 &is_dos_app, &is_cygnus_app);
808 /* #### we need to port this. */
809 /* On Windows 95, if cmdname is a DOS app, we invoke a helper
810 application to start it by specifying the helper app as cmdname,
811 while leaving the real app name as argv[0]. */
814 cmdname = (char*) alloca (MAXPATHLEN);
815 if (egetenv ("CMDPROXY"))
816 strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
819 strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
820 strcat ((char*)cmdname, "cmdproxy.exe");
825 /* we have to do some conjuring here to put argv and envp into the
826 form CreateProcess wants... argv needs to be a space separated/null
827 terminated list of parameters, and envp is a null
828 separated/double-null terminated list of parameters.
830 Additionally, zero-length args and args containing whitespace or
831 quote chars need to be wrapped in double quotes - for this to work,
832 embedded quotes need to be escaped as well. The aim is to ensure
833 the child process reconstructs the argv array we start with
834 exactly, so we treat quotes at the beginning and end of arguments
837 The Win32 GNU-based library from Cygnus doubles quotes to escape
838 them, while MSVC uses backslash for escaping. (Actually the MSVC
839 startup code does attempt to recognize doubled quotes and accept
840 them, but gets it wrong and ends up requiring three quotes to get a
841 single embedded quote!) So by default we decide whether to use
842 quote or backslash as the escape character based on whether the
843 binary is apparently a Cygnus compiled app.
845 Note that using backslash to escape embedded quotes requires
846 additional special handling if an embedded quote is already
847 preceded by backslash, or if an arg requiring quoting ends with
848 backslash. In such cases, the run of escape characters needs to be
849 doubled. For consistency, we apply this special handling as long
850 as the escape character is not quote.
852 Since we have no idea how large argv and envp are likely to be we
853 figure out list lengths on the fly and allocate them. */
855 if (!NILP (Vmswindows_quote_process_args))
858 /* Override escape char by binding mswindows-quote-process-args to
859 desired character, or use t for auto-selection. */
860 if (INTP (Vmswindows_quote_process_args))
861 escape_char = (char) XINT (Vmswindows_quote_process_args);
863 escape_char = is_cygnus_app ? '"' : '\\';
867 for (i = 0; i < nargv; ++i)
869 Bufbyte *targ = XSTRING_DATA (i == 0 ? program : argv[i - 1]);
872 int escape_char_run = 0;
881 /* allow for embedded quotes to be escaped */
884 /* handle the case where the embedded quote is already escaped */
885 if (escape_char_run > 0)
887 /* To preserve the arg exactly, we need to double the
888 preceding escape characters (plus adding one to
889 escape the quote character itself). */
890 arglen += escape_char_run;
893 else if (*p == ' ' || *p == '\t')
898 if (*p == escape_char && escape_char != '"')
906 /* handle the case where the arg ends with an escape char - we
907 must not let the enclosing quote be escaped. */
908 if (escape_char_run > 0)
909 arglen += escape_char_run;
911 arglen += strlen (targ) + 1;
913 quoted_args[i] = alloca_array (Bufbyte, arglen);
916 for (i = 0; i < nargv; ++i)
918 Bufbyte *targ = XSTRING_DATA (i == 0 ? program : argv[i - 1]);
921 Bufbyte *parg = quoted_args[i];
929 if (*p == ' ' || *p == '\t' || *p == '"')
934 int escape_char_run = 0;
940 last = p + strlen (p) - 1;
943 /* This version does not escape quotes if they occur at the
944 beginning or end of the arg - this could lead to incorrect
945 behavior when the arg itself represents a command line
946 containing quoted args. I believe this was originally done
947 as a hack to make some things work, before
948 `mswindows-quote-process-args' was added. */
951 if (*p == '"' && p > first && p < last)
952 *parg++ = escape_char; /* escape embedded quotes */
960 /* double preceding escape chars if any */
961 while (escape_char_run > 0)
963 *parg++ = escape_char;
966 /* escape all quote chars, even at beginning or end */
967 *parg++ = escape_char;
971 if (*p == escape_char && escape_char != '"')
976 /* double escape chars before enclosing quote */
977 while (escape_char_run > 0)
979 *parg++ = escape_char;
988 parg += strlen (targ);
994 int total_cmdline_len = 0;
995 Extcount *extargcount = (Extcount *) alloca_array (Extcount, nargv);
996 Extbyte **extarg = (Extbyte **) alloca_array (Extbyte *, nargv);
997 Extbyte *command_ptr;
999 for (i = 0; i < nargv; ++i)
1001 TO_EXTERNAL_FORMAT (C_STRING, quoted_args[i], ALLOCA,
1002 (extarg[i], extargcount[i]), Qmswindows_tstr);
1003 /* account for space and terminating null */
1004 total_cmdline_len += extargcount[i] + EITCHAR_SIZE;
1007 command_line = alloca_array (char, total_cmdline_len);
1008 command_ptr = command_line;
1009 for (i = 0; i < nargv; ++i)
1011 memcpy (command_ptr, extarg[i], extargcount[i]);
1012 command_ptr += extargcount[i];
1013 EICOPY_TCHAR (command_ptr, ' ');
1014 command_ptr += EITCHAR_SIZE;
1016 EICOPY_TCHAR (command_ptr, '\0');
1017 command_ptr += EITCHAR_SIZE;
1020 /* Set `proc_env' to a nul-separated array of the strings in
1021 Vprocess_environment terminated by 2 nuls. */
1025 REGISTER Lisp_Object tem;
1026 REGISTER char **new_env;
1027 REGISTER int new_length = 0, i, new_space;
1030 for (tem = Vprocess_environment;
1032 && STRINGP (XCAR (tem)));
1036 /* FSF adds an extra env var to hold the current process ID of the
1037 Emacs process. Apparently this is used only by emacsserver.c,
1038 which we have superseded to gnuserv.c. (#### Does it work under
1041 sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d",
1042 GetCurrentProcessId ());
1043 arglen += strlen (ppid_env_var_buffer) + 1;
1047 /* new_length + 1 to include terminating 0. */
1048 env = new_env = alloca_array (char *, new_length + 1);
1050 /* Copy the Vprocess_environment strings into new_env. */
1051 for (tem = Vprocess_environment;
1053 && STRINGP (XCAR (tem)));
1057 char *string = (char *) XSTRING_DATA (XCAR (tem));
1058 /* See if this string duplicates any string already in the env.
1059 If so, don't put it in.
1060 When an env var has multiple definitions,
1061 we keep the definition that comes first in process-environment. */
1062 for (; ep != new_env; ep++)
1064 char *p = *ep, *q = string;
1068 /* The string is malformed; might as well drop it. */
1077 *new_env++ = string;
1082 /* Sort the environment variables */
1083 new_length = new_env - env;
1084 qsort (env, new_length, sizeof (char *), compare_env);
1086 /* Work out how much space to allocate */
1088 for (i = 0; i < new_length; i++)
1090 new_space += strlen(env[i]) + 1;
1094 /* Allocate space and copy variables into it */
1095 penv = proc_env = (char*) alloca(new_space);
1096 for (i = 0; i < new_length; i++)
1098 strcpy(penv, env[i]);
1099 penv += strlen(env[i]) + 1;
1104 /* Create process */
1107 PROCESS_INFORMATION pi;
1112 si.dwFlags = STARTF_USESHOWWINDOW;
1113 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
1116 si.hStdInput = hprocin;
1117 si.hStdOutput = hprocout;
1118 si.hStdError = hprocerr;
1119 si.dwFlags |= STARTF_USESTDHANDLES;
1122 flags = CREATE_SUSPENDED;
1123 if (msw_windows9x_p ())
1124 flags |= (!NILP (Vmswindows_start_process_share_console)
1125 ? CREATE_NEW_PROCESS_GROUP
1126 : CREATE_NEW_CONSOLE);
1128 flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP;
1129 if (NILP (Vmswindows_start_process_inherit_error_mode))
1130 flags |= CREATE_DEFAULT_ERROR_MODE;
1132 ensure_console_window_exists ();
1134 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, flags,
1135 proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
1136 ? 0 : GetLastError ());
1140 /* These just have been inherited; we do not need a copy */
1141 CloseHandle (hprocin);
1142 CloseHandle (hprocout);
1143 CloseHandle (hprocerr);
1146 /* Handle process creation failure */
1151 CloseHandle (hmyshove);
1152 CloseHandle (hmyslurp);
1154 signal_cannot_launch (program, GetLastError ());
1157 /* The process started successfully */
1160 NT_DATA(p)->h_process = pi.hProcess;
1161 NT_DATA(p)->dwProcessId = pi.dwProcessId;
1162 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
1166 /* Indicate as if the process has exited immediately. */
1167 p->status_symbol = Qexit;
1168 CloseHandle (pi.hProcess);
1171 ResumeThread (pi.hThread);
1172 CloseHandle (pi.hThread);
1174 /* Remember to enable child signals later if this is not a windowed
1175 app. Can't do it right now because that screws up the MKS Toolkit
1179 NT_DATA(p)->need_enable_child_signals = 10;
1180 kick_status_notify ();
1183 return ((int)pi.dwProcessId);
1188 * This method is called to update status fields of the process
1189 * structure. If the process has not existed, this method is expected
1192 * The method is called only for real child processes.
1196 nt_update_status_if_terminated (Lisp_Process* p)
1200 if (NT_DATA(p)->need_enable_child_signals > 1)
1202 NT_DATA(p)->need_enable_child_signals -= 1;
1203 kick_status_notify ();
1205 else if (NT_DATA(p)->need_enable_child_signals == 1)
1207 enable_child_signals(NT_DATA(p)->h_process);
1208 NT_DATA(p)->need_enable_child_signals = 0;
1211 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
1212 && exit_code != STILL_ACTIVE)
1216 /* The exit code can be a code returned by process, or an
1217 NTSTATUS value. We cannot accurately handle the latter since
1218 it is a full 32 bit integer */
1219 if (exit_code & 0xC0000000)
1221 p->status_symbol = Qsignal;
1222 p->exit_code = exit_code & 0x1FFFFFFF;
1226 p->status_symbol = Qexit;
1227 p->exit_code = exit_code;
1233 * Stuff the entire contents of LSTREAM to the process output pipe
1236 /* #### If only this function could be somehow merged with
1237 unix_send_process... */
1240 nt_send_process (Lisp_Object proc, struct lstream* lstream)
1242 volatile Lisp_Object vol_proc = proc;
1243 Lisp_Process *volatile p = XPROCESS (proc);
1245 /* use a reasonable-sized buffer (somewhere around the size of the
1246 stream buffer) so as to avoid inundating the stream with blocked
1248 Bufbyte chunkbuf[512];
1255 chunklen = Lstream_read (lstream, chunkbuf, 512);
1257 break; /* perhaps should abort() if < 0?
1258 This should never happen. */
1260 /* Lstream_write() will never successfully write less than the
1261 amount sent in. In the worst case, it just buffers the
1263 writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
1265 Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
1268 p->status_symbol = Qexit;
1269 p->exit_code = ERROR_BROKEN_PIPE;
1273 deactivate_process (*((Lisp_Object *) (&vol_proc)));
1274 error ("Broken pipe error sending to process %s; closed it",
1275 XSTRING_DATA (p->name));
1280 while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
1282 /* Buffer is full. Wait, accepting input; that may allow
1283 the program to finish doing output and read more. */
1284 Faccept_process_output (Qnil, Qzero, make_int (wait_ms));
1285 Lstream_flush (XLSTREAM (p->pipe_outstream));
1286 wait_ms = min (1000, 2 * wait_ms);
1293 * Send a signal number SIGNO to PROCESS.
1294 * CURRENT_GROUP means send to the process group that currently owns
1295 * the terminal being used to communicate with PROCESS.
1296 * This is used for various commands in shell mode.
1297 * If NOMSG is zero, insert signal-announcements into process's buffers
1300 * If we can, we try to signal PROCESS by sending control characters
1301 * down the pty. This allows us to signal inferiors who have changed
1302 * their uid, for which killpg would return an EPERM error.
1304 * The method signals an error if the given SIGNO is not valid
1308 nt_kill_child_process (Lisp_Object proc, int signo,
1309 int current_group, int nomsg)
1311 Lisp_Process *p = XPROCESS (proc);
1313 /* Enable child signals if necessary. This may lose the first
1314 but it's better than nothing. */
1315 if (NT_DATA (p)->need_enable_child_signals > 0)
1317 enable_child_signals (NT_DATA(p)->h_process);
1318 NT_DATA (p)->need_enable_child_signals = 0;
1321 /* Signal error if SIGNO cannot be sent */
1322 validate_signal_number (signo);
1325 if (!send_signal (NT_DATA (p), 0, signo))
1326 signal_simple_error ("Cannot send signal to process", proc);
1330 * Kill any process in the system given its PID
1332 * Returns zero if a signal successfully sent, or
1333 * negative number upon failure
1336 nt_kill_process_by_pid (int pid, int signo)
1338 struct Lisp_Process *p;
1340 /* Signal error if SIGNO cannot be sent */
1341 validate_signal_number (signo);
1343 p = find_process_from_pid (pid);
1344 return send_signal (p ? NT_DATA (p) : 0, pid, signo) ? 0 : -1;
1347 /*-----------------------------------------------------------------------*/
1348 /* Sockets connections */
1349 /*-----------------------------------------------------------------------*/
1352 /* #### Hey MS, how long Winsock 2 for '95 will be in beta? */
1354 #define SOCK_TIMER_ID 666
1355 #define XM_SOCKREPLY (WM_USER + 666)
1358 get_internet_address (Lisp_Object host, struct sockaddr_in *address,
1359 Error_behavior errb)
1361 char buf [MAXGETHOSTSTRUCT];
1366 address->sin_family = AF_INET;
1368 /* First check if HOST is already a numeric address */
1370 unsigned long inaddr = inet_addr (XSTRING_DATA (host));
1371 if (inaddr != INADDR_NONE)
1373 address->sin_addr.s_addr = inaddr;
1378 /* Create a window which will receive completion messages */
1379 hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1,
1380 NULL, NULL, NULL, NULL);
1383 /* Post name resolution request */
1384 hasync = WSAAsyncGetHostByName (hwnd, XM_SOCKREPLY, XSTRING_DATA (host),
1389 /* Set a timer to poll for quit every 250 ms */
1390 SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL);
1395 GetMessage (&msg, hwnd, 0, 0);
1396 if (msg.message == XM_SOCKREPLY)
1398 /* Ok, got an answer */
1399 if (WSAGETASYNCERROR(msg.lParam) == NO_ERROR)
1403 warn_when_safe(Qstream, Qwarning,
1404 "cannot get IP address for host \"%s\"",
1405 XSTRING_DATA (host));
1409 else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID)
1413 WSACancelAsyncRequest (hasync);
1414 KillTimer (hwnd, SOCK_TIMER_ID);
1415 DestroyWindow (hwnd);
1419 DispatchMessage (&msg);
1423 KillTimer (hwnd, SOCK_TIMER_ID);
1424 DestroyWindow (hwnd);
1427 /* BUF starts with struct hostent */
1428 struct hostent* he = (struct hostent*) buf;
1429 address->sin_addr.s_addr = *(unsigned long*)he->h_addr_list[0];
1435 nt_canonicalize_host_name (Lisp_Object host)
1437 struct sockaddr_in address;
1439 if (!get_internet_address (host, &address, ERROR_ME_NOT))
1442 if (address.sin_family == AF_INET)
1443 return build_string (inet_ntoa (address.sin_addr));
1448 /* open a TCP network connection to a given HOST/SERVICE. Treated
1449 exactly like a normal process when reading and writing. Only
1450 differences are in status display and process deletion. A network
1451 connection has no PID; you cannot signal it. All you can do is
1452 deactivate and close it via delete-process */
1455 nt_open_network_stream (Lisp_Object name, Lisp_Object host,
1456 Lisp_Object service,
1457 Lisp_Object protocol, void** vinfd, void** voutfd)
1459 /* !!#### not Mule-ized */
1460 struct sockaddr_in address;
1465 CHECK_STRING (host);
1467 if (!EQ (protocol, Qtcp))
1468 signal_simple_error ("Unsupported protocol", protocol);
1471 port = htons ((unsigned short) XINT (service));
1474 struct servent *svc_info;
1475 CHECK_STRING (service);
1476 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
1478 signal_simple_error ("Unknown service", service);
1479 port = svc_info->s_port;
1482 get_internet_address (host, &address, ERROR_ME);
1483 address.sin_port = port;
1485 s = socket (address.sin_family, SOCK_STREAM, 0);
1487 report_file_error ("error creating socket", list1 (name));
1489 /* We don't want to be blocked on connect */
1491 unsigned long nonblock = 1;
1492 ioctlsocket (s, FIONBIO, &nonblock);
1495 retval = connect (s, (struct sockaddr *) &address, sizeof (address));
1496 if (retval != NO_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
1497 goto connect_failed;
1498 /* Wait while connection is established */
1511 /* Poll for quit every 250 ms */
1513 tv.tv_usec = 250 * 1000;
1517 nsel = select (0, NULL, &fdset, &fdset, &tv);
1521 /* Check: was connection successful or not? */
1523 nsel = select (0, NULL, NULL, &fdset, &tv);
1525 goto connect_failed;
1531 /* We are connected at this point */
1533 DuplicateHandle (GetCurrentProcess(), (HANDLE)s,
1534 GetCurrentProcess(), (LPHANDLE)voutfd,
1535 0, FALSE, DUPLICATE_SAME_ACCESS);
1542 warn_when_safe (Qstream, Qwarning,
1543 "failure to open network stream to host \"%s\" for service \"%d\"",
1544 XSTRING_DATA (host),
1545 (unsigned short) XINT (service));
1549 warn_when_safe (Qstream, Qwarning,
1550 "failure to open network stream to host \"%s\" for service \"%s\"",
1551 XSTRING_DATA (host),
1552 XSTRING_DATA (service));
1554 report_file_error ("connection failed", list2 (host, name));
1559 /*-----------------------------------------------------------------------*/
1560 /* Initialization */
1561 /*-----------------------------------------------------------------------*/
1564 process_type_create_nt (void)
1566 PROCESS_HAS_METHOD (nt, alloc_process_data);
1567 PROCESS_HAS_METHOD (nt, finalize_process_data);
1568 PROCESS_HAS_METHOD (nt, init_process);
1569 PROCESS_HAS_METHOD (nt, create_process);
1570 PROCESS_HAS_METHOD (nt, update_status_if_terminated);
1571 PROCESS_HAS_METHOD (nt, send_process);
1572 PROCESS_HAS_METHOD (nt, kill_child_process);
1573 PROCESS_HAS_METHOD (nt, kill_process_by_pid);
1575 PROCESS_HAS_METHOD (nt, canonicalize_host_name);
1576 PROCESS_HAS_METHOD (nt, open_network_stream);
1577 #ifdef HAVE_MULTICAST
1578 #error I won't do this until '95 has winsock2
1579 PROCESS_HAS_METHOD (nt, open_multicast_group);
1585 syms_of_process_nt (void)
1590 vars_of_process_nt (void)
1592 DEFVAR_LISP ("mswindows-quote-process-args",
1593 &Vmswindows_quote_process_args /*
1594 Non-nil enables quoting of process arguments to ensure correct parsing.
1595 Because Windows does not directly pass argv arrays to child processes,
1596 programs have to reconstruct the argv array by parsing the command
1597 line string. For an argument to contain a space, it must be enclosed
1598 in double quotes or it will be parsed as multiple arguments.
1600 If the value is a character, that character will be used to escape any
1601 quote characters that appear, otherwise a suitable escape character
1602 will be chosen based on the type of the program (normal or Cygwin).
1604 Vmswindows_quote_process_args = Qt;
1606 DEFVAR_LISP ("mswindows-start-process-share-console",
1607 &Vmswindows_start_process_share_console /*
1608 When nil, new child processes are given a new console.
1609 When non-nil, they share the Emacs console; this has the limitation of
1610 allowing only only DOS subprocess to run at a time (whether started directly
1611 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1612 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1613 otherwise respond to interrupts from Emacs.
1615 Vmswindows_start_process_share_console = Qnil;
1617 DEFVAR_LISP ("mswindows-start-process-inherit-error-mode",
1618 &Vmswindows_start_process_inherit_error_mode /*
1619 "When nil, new child processes revert to the default error mode.
1620 When non-nil, they inherit their error mode setting from Emacs, which stops
1621 them blocking when trying to access unmounted drives etc.
1623 Vmswindows_start_process_inherit_error_mode = Qt;