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"
45 /* Bound by win32-native.el */
46 Lisp_Object Qmswindows_construct_process_command_line;
48 /* Arbitrary size limit for code fragments passed to run_in_other_process */
49 #define FRAGMENT_CODE_SIZE 32
51 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */
52 struct nt_process_data
56 HWND hwnd; /* console window */
59 /* Control whether create_child causes the process to inherit Emacs'
60 console window, or be given a new one of its own. The default is
61 nil, to allow multiple DOS programs to run on Win95. Having separate
62 consoles also allows Emacs to cleanly terminate process groups. */
63 Lisp_Object Vmswindows_start_process_share_console;
65 /* Control whether create_child cause the process to inherit Emacs'
66 error mode setting. The default is t, to minimize the possibility of
67 subprocesses blocking when accessing unmounted drives. */
68 Lisp_Object Vmswindows_start_process_inherit_error_mode;
70 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
72 /*-----------------------------------------------------------------------*/
74 /*-----------------------------------------------------------------------*/
76 /* This one breaks process abstraction. Prototype is in console-msw.h,
77 used by select_process method in event-msw.c */
79 get_nt_process_handle (Lisp_Process *p)
81 return (NT_DATA (p)->h_process);
84 static struct Lisp_Process *
85 find_process_from_pid (DWORD pid)
87 Lisp_Object tail, proc;
89 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
92 if (NT_DATA (XPROCESS (proc))->dwProcessId == pid)
93 return XPROCESS (proc);
99 /*-----------------------------------------------------------------------*/
100 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5 */
101 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/
102 /*-----------------------------------------------------------------------*/
112 * Allocate SIZE bytes in H_PROCESS address space. Fill in PMC used
113 * further by other routines. Return nonzero if successful.
115 * The memory in other process is allocated by creating a suspended
116 * thread. Initial stack of that thread is used as the memory
117 * block. The thread entry point is the routine ExitThread in
118 * kernel32.dll, so the allocated memory is freed just by resuming the
119 * thread, which immediately terminates after that.
123 alloc_process_memory (HANDLE h_process, size_t size,
126 LPTHREAD_START_ROUTINE adr_ExitThread =
127 (LPTHREAD_START_ROUTINE)
128 GetProcAddress (GetModuleHandle ("kernel32"), "ExitThread");
131 MEMORY_BASIC_INFORMATION mbi;
133 pmc->h_process = h_process;
134 pmc->h_thread = CreateRemoteThread (h_process, NULL, size,
135 adr_ExitThread, NULL,
136 CREATE_SUSPENDED, &dw_unused);
137 if (pmc->h_thread == NULL)
140 /* Get context, for thread's stack pointer */
141 context.ContextFlags = CONTEXT_CONTROL;
142 if (!GetThreadContext (pmc->h_thread, &context))
145 /* Determine base address of the committed range */
146 if (sizeof(mbi) != VirtualQueryEx (h_process,
148 (LPDWORD)context.Esp - 1,
149 #elif defined (_ALPHA_)
150 (LPDWORD)context.IntSp - 1,
152 #error Unknown processor architecture
157 /* Change the page protection of the allocated memory to executable,
159 if (!VirtualProtectEx (h_process, mbi.BaseAddress, size,
160 PAGE_EXECUTE_READWRITE, &dw_unused))
163 pmc->address = mbi.BaseAddress;
167 ResumeThread (pmc->h_thread);
173 free_process_memory (process_memory* pmc)
175 ResumeThread (pmc->h_thread);
179 * Run ROUTINE in the context of process determined by H_PROCESS. The
180 * routine is passed the address of DATA as parameter. The ROUTINE must
181 * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of
184 * Note that the code must be positionally independent, and compiled
185 * without stack checks (they cause implicit calls into CRT so will
186 * fail). DATA should not refer any data in calling process, as both
187 * routine and its data are copied into remote process. Size of data
188 * and code together should not exceed one page (4K on x86 systems).
190 * Return the value returned by ROUTINE, or (DWORD)-1 if call failed.
193 run_in_other_process (HANDLE h_process,
194 LPTHREAD_START_ROUTINE routine,
195 LPVOID data, size_t data_size)
198 const size_t code_size = FRAGMENT_CODE_SIZE;
199 /* Need at most 3 extra bytes of memory, for data alignment */
200 size_t total_size = code_size + data_size + 3;
205 /* Allocate memory */
206 if (!alloc_process_memory (h_process, total_size, &pm))
210 if (!WriteProcessMemory (h_process, pm.address, (LPVOID)routine,
217 remote_data = (LPBYTE)pm.address + ((code_size + 4) & ~3);
218 if (!WriteProcessMemory (h_process, remote_data, data, data_size, NULL))
224 /* Execute the remote copy of code, passing it remote data */
225 h_thread = CreateRemoteThread (h_process, NULL, 0,
226 (LPTHREAD_START_ROUTINE) pm.address,
227 remote_data, 0, &dw_unused);
228 if (h_thread == NULL)
231 /* Wait till thread finishes */
232 WaitForSingleObject (h_thread, INFINITE);
234 /* Free remote memory */
235 free_process_memory (&pm);
237 /* Return thread's exit code */
240 GetExitCodeThread (h_thread, &exit_code);
241 CloseHandle (h_thread);
246 free_process_memory (&pm);
250 /*-----------------------------------------------------------------------*/
251 /* Sending signals */
252 /*-----------------------------------------------------------------------*/
254 /* ---------------------------- the NT way ------------------------------- */
257 * We handle the following signals:
259 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
260 * executed by the remote process
261 * SIGINT - The remote process is sent CTRL_BREAK_EVENT
263 * The MSVC5.0 compiler feels free to re-order functions within a
264 * compilation unit, so we have no way of finding out the size of the
265 * following functions. Therefore these functions must not be larger than
266 * FRAGMENT_CODE_SIZE.
274 void (WINAPI *adr_ExitProcess) (UINT);
278 sigkill_proc (sigkill_data* data)
280 (*data->adr_ExitProcess)(255);
285 * Sending break or control c
289 BOOL (WINAPI *adr_GenerateConsoleCtrlEvent) (DWORD, DWORD);
294 sigint_proc (sigint_data* data)
296 return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
304 BOOL (WINAPI *adr_SetConsoleCtrlHandler) (LPVOID, BOOL);
308 sig_enable_proc (sig_enable_data* data)
310 (*data->adr_SetConsoleCtrlHandler) (NULL, FALSE);
315 * Send signal SIGNO to process H_PROCESS.
316 * Return nonzero if successful.
320 send_signal_the_nt_way (struct nt_process_data *cp, int pid, int signo)
323 HMODULE h_kernel = GetModuleHandle ("kernel32");
324 int close_process = 0;
327 assert (h_kernel != NULL);
331 pid = cp->dwProcessId;
332 h_process = cp->h_process;
337 /* Try to open the process with required privileges */
338 h_process = OpenProcess (PROCESS_CREATE_THREAD
339 | PROCESS_QUERY_INFORMATION
340 | PROCESS_VM_OPERATION
357 (void (WINAPI *) (UINT)) GetProcAddress (h_kernel, "ExitProcess");
358 assert (d.adr_ExitProcess);
359 retval = run_in_other_process (h_process,
360 (LPTHREAD_START_ROUTINE)sigkill_proc,
367 d.adr_GenerateConsoleCtrlEvent =
368 (BOOL (WINAPI *) (DWORD, DWORD))
369 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
370 assert (d.adr_GenerateConsoleCtrlEvent);
371 d.event = CTRL_C_EVENT;
372 retval = run_in_other_process (h_process,
373 (LPTHREAD_START_ROUTINE)sigint_proc,
382 CloseHandle (h_process);
383 return (int)retval > 0 ? 1 : 0;
387 * Enable CTRL_C_EVENT handling in a new child process
390 enable_child_signals (HANDLE h_process)
392 HMODULE h_kernel = GetModuleHandle ("kernel32");
395 assert (h_kernel != NULL);
396 d.adr_SetConsoleCtrlHandler =
397 (BOOL (WINAPI *) (LPVOID, BOOL))
398 GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
399 assert (d.adr_SetConsoleCtrlHandler);
400 run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
404 #pragma warning (default : 4113)
406 /* ---------------------------- the 95 way ------------------------------- */
409 find_child_console (HWND hwnd, long putada)
413 struct nt_process_data *cp = (struct nt_process_data *) putada;
415 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
416 if (process_id == cp->dwProcessId)
418 char window_class[32];
420 GetClassName (hwnd, window_class, sizeof (window_class));
421 if (strcmp (window_class,
422 mswindows_windows9x_p ()
424 : "ConsoleWindowClass") == 0)
435 send_signal_the_95_way (struct nt_process_data *cp, int pid, int signo)
438 int close_process = 0;
443 pid = cp->dwProcessId;
444 h_process = cp->h_process;
446 /* Try to locate console window for process. */
447 EnumWindows (find_child_console, (LPARAM) cp);
452 /* Try to open the process with required privileges */
453 h_process = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
460 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
462 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
463 BYTE vk_break_code = VK_CANCEL;
464 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
465 HWND foreground_window;
467 if (break_scan_code == 0)
469 /* Fake Ctrl-C if we can't manage Ctrl-Break. */
471 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
474 foreground_window = GetForegroundWindow ();
475 if (foreground_window)
477 /* NT 5.0, and apparently also Windows 98, will not allow
478 a Window to be set to foreground directly without the
479 user's involvement. The workaround is to attach
480 ourselves to the thread that owns the foreground
481 window, since that is the only thread that can set the
482 foreground window. */
483 DWORD foreground_thread, child_thread;
485 GetWindowThreadProcessId (foreground_window, NULL);
486 if (foreground_thread == GetCurrentThreadId ()
487 || !AttachThreadInput (GetCurrentThreadId (),
488 foreground_thread, TRUE))
489 foreground_thread = 0;
491 child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
492 if (child_thread == GetCurrentThreadId ()
493 || !AttachThreadInput (GetCurrentThreadId (),
497 /* Set the foreground window to the child. */
498 if (SetForegroundWindow (cp->hwnd))
500 /* Generate keystrokes as if user had typed Ctrl-Break or
502 keybd_event (VK_CONTROL, control_scan_code, 0, 0);
503 keybd_event (vk_break_code, break_scan_code,
504 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
505 keybd_event (vk_break_code, break_scan_code,
506 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
507 | KEYEVENTF_KEYUP, 0);
508 keybd_event (VK_CONTROL, control_scan_code,
511 /* Sleep for a bit to give time for Emacs frame to respond
512 to focus change events (if Emacs was active app). */
515 SetForegroundWindow (foreground_window);
517 /* Detach from the foreground and child threads now that
518 the foreground switching is over. */
519 if (foreground_thread)
520 AttachThreadInput (GetCurrentThreadId (),
521 foreground_thread, FALSE);
523 AttachThreadInput (GetCurrentThreadId (),
524 child_thread, FALSE);
527 /* Ctrl-Break is NT equivalent of SIGINT. */
528 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
530 #if 0 /* FSF Emacs */
531 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
532 "for pid %lu\n", GetLastError (), pid));
540 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
543 if (mswindows_windows9x_p ())
546 Another possibility is to try terminating the VDM out-right by
547 calling the Shell VxD (id 0x17) V86 interface, function #4
548 "SHELL_Destroy_VM", ie.
554 First need to determine the current VM handle, and then arrange for
555 the shellapi call to be made from the system vm (by using
556 Switch_VM_and_callback).
558 Could try to invoke DestroyVM through CallVxD.
562 /* On Win95, posting WM_QUIT causes the 16-bit subsystem
563 to hang when cmdproxy is used in conjunction with
564 command.com for an interactive shell. Posting
565 WM_CLOSE pops up a dialog that, when Yes is selected,
566 does the same thing. TerminateProcess is also less
567 than ideal in that subprocesses tend to stick around
568 until the machine is shutdown, but at least it
569 doesn't freeze the 16-bit subsystem. */
570 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
572 if (!TerminateProcess (h_process, 0xff))
574 #if 0 /* FSF Emacs */
575 DebPrint (("sys_kill.TerminateProcess returned %d "
576 "for pid %lu\n", GetLastError (), pid));
584 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
586 /* Kill the process. On W32 this doesn't kill child processes
587 so it doesn't work very well for shells which is why it's not
588 used in every case. */
589 else if (!TerminateProcess (h_process, 0xff))
591 #if 0 /* FSF Emacs */
592 DebPrint (("sys_kill.TerminateProcess returned %d "
593 "for pid %lu\n", GetLastError (), pid));
601 CloseHandle (h_process);
606 /* -------------------------- all-OS functions ---------------------------- */
609 send_signal (struct nt_process_data *cp, int pid, int signo)
611 return (!mswindows_windows9x_p () && send_signal_the_nt_way (cp, pid, signo))
612 || send_signal_the_95_way (cp, pid, signo);
616 * Signal error if SIGNO is not supported
619 validate_signal_number (int signo)
621 if (signo != SIGKILL && signo != SIGTERM
622 && signo != SIGQUIT && signo != SIGINT
624 invalid_argument ("Signal number not supported", make_int (signo));
627 /*-----------------------------------------------------------------------*/
628 /* Process methods */
629 /*-----------------------------------------------------------------------*/
632 * Allocate and initialize Lisp_Process->process_data
636 nt_alloc_process_data (Lisp_Process *p)
638 p->process_data = xnew_and_zero (struct nt_process_data);
642 nt_finalize_process_data (Lisp_Process *p, int for_disksave)
644 assert (!for_disksave);
645 /* If it's still in the list of processes we are waiting on delete
647 mswindows_unwait_process (p);
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 report_file_error ("Error starting", image_file);
682 ensure_console_window_exists (void)
684 if (mswindows_windows9x_p ())
685 mswindows_hide_console ();
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 */
728 /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most
729 errors. This leads to bogus error message. */
731 char *p = strrchr ((char *)XSTRING_DATA (program), '.');
733 (stricmp (p, ".exe") == 0 ||
734 stricmp (p, ".com") == 0 ||
735 stricmp (p, ".bat") == 0 ||
736 stricmp (p, ".cmd") == 0))
738 image_type = xSHGetFileInfoA ((char *)XSTRING_DATA (program), 0,NULL,
743 char progname[MAX_PATH];
744 sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program));
745 image_type = xSHGetFileInfoA (progname, 0, NULL, 0, SHGFI_EXETYPE);
748 signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND
749 ? ERROR_BAD_FORMAT : GetLastError ()));
750 windowed = HIWORD (image_type) != 0;
752 else /* NT 3.5; we have no idea so just guess. */
755 /* Decide whether to do I/O on process handles, or just mark the
756 process exited immediately upon successful launching. We do I/O if the
757 process is a console one, or if it is windowed but windowed_process_io
759 do_io = !windowed || windowed_process_io ;
763 /* Create two unidirectional named pipes */
765 SECURITY_ATTRIBUTES sa;
767 sa.nLength = sizeof(sa);
768 sa.bInheritHandle = TRUE;
769 sa.lpSecurityDescriptor = NULL;
771 CreatePipe (&hprocin, &hmyshove, &sa, 0);
772 CreatePipe (&hmyslurp, &hprocout, &sa, 0);
774 /* Duplicate the stdout handle for use as stderr */
775 DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(),
776 &hprocerr, 0, TRUE, DUPLICATE_SAME_ACCESS);
778 /* Stupid Win32 allows to create a pipe with *both* ends either
779 inheritable or not. We need process ends inheritable, and local
780 ends not inheritable. */
781 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(),
783 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
785 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(),
787 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
791 /* Convert an argv vector into Win32 style command line by a call to
792 lisp function `mswindows-construct-process-command-line'
793 (in win32-native.el) */
796 Lisp_Object args_or_ret = Qnil;
799 GCPRO1 (args_or_ret);
801 for (i = 0; i < nargv; ++i)
802 args_or_ret = Fcons (*argv++, args_or_ret);
803 args_or_ret = Fnreverse (args_or_ret);
804 args_or_ret = Fcons (program, args_or_ret);
806 args_or_ret = call1 (Qmswindows_construct_process_command_line,
809 if (!STRINGP (args_or_ret))
810 /* Luser wrote his/her own clever version */
812 ("Bogus return value from `mswindows-construct-process-command-line'",
815 LISP_STRING_TO_EXTERNAL (args_or_ret, command_line, Qmswindows_tstr);
817 UNGCPRO; /* args_or_ret */
820 /* Set `proc_env' to a nul-separated array of the strings in
821 Vprocess_environment terminated by 2 nuls. */
825 REGISTER Lisp_Object tem;
826 REGISTER char **new_env;
827 REGISTER int new_length = 0, i, new_space;
830 for (tem = Vprocess_environment;
832 && STRINGP (XCAR (tem)));
836 /* FSF adds an extra env var to hold the current process ID of the
837 Emacs process. Apparently this is used only by emacsserver.c,
838 which we have superseded to gnuserv.c. (#### Does it work under
841 sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d",
842 GetCurrentProcessId ());
843 arglen += strlen (ppid_env_var_buffer) + 1;
847 /* new_length + 1 to include terminating 0. */
848 env = new_env = alloca_array (char *, new_length + 1);
850 /* Copy the Vprocess_environment strings into new_env. */
851 for (tem = Vprocess_environment;
853 && STRINGP (XCAR (tem)));
857 char *string = (char *) XSTRING_DATA (XCAR (tem));
858 /* See if this string duplicates any string already in the env.
859 If so, don't put it in.
860 When an env var has multiple definitions,
861 we keep the definition that comes first in process-environment. */
862 for (; ep != new_env; ep++)
864 char *p = *ep, *q = string;
868 /* The string is malformed; might as well drop it. */
882 /* Sort the environment variables */
883 new_length = new_env - env;
884 qsort (env, new_length, sizeof (char *), compare_env);
886 /* Work out how much space to allocate */
888 for (i = 0; i < new_length; i++)
890 new_space += strlen(env[i]) + 1;
894 /* Allocate space and copy variables into it */
895 penv = proc_env = (char*) alloca(new_space);
896 for (i = 0; i < new_length; i++)
898 strcpy(penv, env[i]);
899 penv += strlen(env[i]) + 1;
905 /* #### we need to port this. */
906 /* On Windows 95, if cmdname is a DOS app, we invoke a helper
907 application to start it by specifying the helper app as cmdname,
908 while leaving the real app name as argv[0]. */
911 cmdname = (char*) alloca (MAXPATHLEN);
912 if (egetenv ("CMDPROXY"))
913 strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
916 strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
917 strcat ((char*)cmdname, "cmdproxy.exe");
925 PROCESS_INFORMATION pi;
930 si.dwFlags = STARTF_USESHOWWINDOW;
931 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
934 si.hStdInput = hprocin;
935 si.hStdOutput = hprocout;
936 si.hStdError = hprocerr;
937 si.dwFlags |= STARTF_USESTDHANDLES;
940 flags = CREATE_SUSPENDED;
941 if (mswindows_windows9x_p ())
942 flags |= (!NILP (Vmswindows_start_process_share_console)
943 ? CREATE_NEW_PROCESS_GROUP
944 : CREATE_NEW_CONSOLE);
946 flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP;
947 if (NILP (Vmswindows_start_process_inherit_error_mode))
948 flags |= CREATE_DEFAULT_ERROR_MODE;
950 ensure_console_window_exists ();
952 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, flags,
953 proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
954 ? 0 : GetLastError ());
958 /* These just have been inherited; we do not need a copy */
959 CloseHandle (hprocin);
960 CloseHandle (hprocout);
961 CloseHandle (hprocerr);
964 /* Handle process creation failure */
969 CloseHandle (hmyshove);
970 CloseHandle (hmyslurp);
972 signal_cannot_launch (program, GetLastError ());
975 /* The process started successfully */
978 NT_DATA(p)->h_process = pi.hProcess;
979 NT_DATA(p)->dwProcessId = pi.dwProcessId;
980 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
984 /* Indicate as if the process has exited immediately. */
985 p->status_symbol = Qexit;
986 CloseHandle (pi.hProcess);
990 enable_child_signals (pi.hProcess);
992 ResumeThread (pi.hThread);
993 CloseHandle (pi.hThread);
995 return ((int)pi.dwProcessId);
1000 * This method is called to update status fields of the process
1001 * structure. If the process has not existed, this method is expected
1004 * The method is called only for real child processes.
1008 nt_update_status_if_terminated (Lisp_Process* p)
1011 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
1012 && exit_code != STILL_ACTIVE)
1016 /* The exit code can be a code returned by process, or an
1017 NTSTATUS value. We cannot accurately handle the latter since
1018 it is a full 32 bit integer */
1019 if (exit_code & 0xC0000000)
1021 p->status_symbol = Qsignal;
1022 p->exit_code = exit_code & 0x1FFFFFFF;
1026 p->status_symbol = Qexit;
1027 p->exit_code = exit_code;
1033 * Stuff the entire contents of LSTREAM to the process output pipe
1036 /* #### If only this function could be somehow merged with
1037 unix_send_process... */
1040 nt_send_process (Lisp_Object proc, struct lstream* lstream)
1042 volatile Lisp_Object vol_proc = proc;
1043 Lisp_Process *volatile p = XPROCESS (proc);
1045 /* use a reasonable-sized buffer (somewhere around the size of the
1046 stream buffer) so as to avoid inundating the stream with blocked
1048 Bufbyte chunkbuf[512];
1053 Lstream_data_count writeret;
1055 chunklen = Lstream_read (lstream, chunkbuf, 512);
1057 break; /* perhaps should abort() if < 0?
1058 This should never happen. */
1060 /* Lstream_write() will never successfully write less than the
1061 amount sent in. In the worst case, it just buffers the
1063 writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
1065 Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
1068 p->status_symbol = Qexit;
1069 p->exit_code = ERROR_BROKEN_PIPE;
1073 deactivate_process (*((Lisp_Object *) (&vol_proc)));
1074 invalid_operation ("Broken pipe error sending to process; closed it",
1080 while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
1082 /* Buffer is full. Wait, accepting input; that may allow
1083 the program to finish doing output and read more. */
1084 Faccept_process_output (Qnil, Qzero, make_int (wait_ms));
1085 Lstream_flush (XLSTREAM (p->pipe_outstream));
1086 wait_ms = min (1000, 2 * wait_ms);
1093 * Send a signal number SIGNO to PROCESS.
1094 * CURRENT_GROUP means send to the process group that currently owns
1095 * the terminal being used to communicate with PROCESS.
1096 * This is used for various commands in shell mode.
1097 * If NOMSG is zero, insert signal-announcements into process's buffers
1100 * If we can, we try to signal PROCESS by sending control characters
1101 * down the pty. This allows us to signal inferiors who have changed
1102 * their uid, for which killpg would return an EPERM error.
1104 * The method signals an error if the given SIGNO is not valid
1108 nt_kill_child_process (Lisp_Object proc, int signo,
1109 int current_group, int nomsg)
1111 Lisp_Process *p = XPROCESS (proc);
1113 /* Signal error if SIGNO cannot be sent */
1114 validate_signal_number (signo);
1117 if (!send_signal (NT_DATA (p), 0, signo))
1118 invalid_operation ("Cannot send signal to process", proc);
1122 * Kill any process in the system given its PID
1124 * Returns zero if a signal successfully sent, or
1125 * negative number upon failure
1128 nt_kill_process_by_pid (int pid, int signo)
1130 struct Lisp_Process *p;
1132 /* Signal error if SIGNO cannot be sent */
1133 validate_signal_number (signo);
1135 p = find_process_from_pid (pid);
1136 return send_signal (p ? NT_DATA (p) : 0, pid, signo) ? 0 : -1;
1139 /*-----------------------------------------------------------------------*/
1140 /* Sockets connections */
1141 /*-----------------------------------------------------------------------*/
1144 /* #### Hey MS, how long Winsock 2 for '95 will be in beta? */
1146 #define SOCK_TIMER_ID 666
1147 #define XM_SOCKREPLY (WM_USER + 666)
1150 get_internet_address (Lisp_Object host, struct sockaddr_in *address,
1151 Error_behavior errb)
1153 char buf [MAXGETHOSTSTRUCT];
1158 address->sin_family = AF_INET;
1160 /* First check if HOST is already a numeric address */
1162 unsigned long inaddr = inet_addr (XSTRING_DATA (host));
1163 if (inaddr != INADDR_NONE)
1165 address->sin_addr.s_addr = inaddr;
1170 /* Create a window which will receive completion messages */
1171 hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1,
1172 NULL, NULL, NULL, NULL);
1175 /* Post name resolution request */
1176 hasync = WSAAsyncGetHostByName (hwnd, XM_SOCKREPLY, XSTRING_DATA (host),
1181 /* Set a timer to poll for quit every 250 ms */
1182 SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL);
1187 GetMessage (&msg, hwnd, 0, 0);
1188 if (msg.message == XM_SOCKREPLY)
1190 /* Ok, got an answer */
1191 if (WSAGETASYNCERROR(msg.lParam) == NO_ERROR)
1195 warn_when_safe(Qstream, Qwarning,
1196 "cannot get IP address for host \"%s\"",
1197 XSTRING_DATA (host));
1201 else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID)
1205 WSACancelAsyncRequest (hasync);
1206 KillTimer (hwnd, SOCK_TIMER_ID);
1207 DestroyWindow (hwnd);
1211 DispatchMessage (&msg);
1215 KillTimer (hwnd, SOCK_TIMER_ID);
1216 DestroyWindow (hwnd);
1219 /* BUF starts with struct hostent */
1220 struct hostent* he = (struct hostent*) buf;
1221 address->sin_addr.s_addr = *(unsigned long*)he->h_addr_list[0];
1227 nt_canonicalize_host_name (Lisp_Object host)
1229 struct sockaddr_in address;
1231 if (!get_internet_address (host, &address, ERROR_ME_NOT))
1234 if (address.sin_family == AF_INET)
1235 return build_string (inet_ntoa (address.sin_addr));
1240 /* open a TCP network connection to a given HOST/SERVICE. Treated
1241 exactly like a normal process when reading and writing. Only
1242 differences are in status display and process deletion. A network
1243 connection has no PID; you cannot signal it. All you can do is
1244 deactivate and close it via delete-process */
1247 nt_open_network_stream (Lisp_Object name, Lisp_Object host,
1248 Lisp_Object service,
1249 Lisp_Object protocol, void** vinfd, void** voutfd)
1251 /* !!#### not Mule-ized */
1252 struct sockaddr_in address;
1257 CHECK_STRING (host);
1259 if (!EQ (protocol, Qtcp))
1260 invalid_argument ("Unsupported protocol", protocol);
1263 port = htons ((unsigned short) XINT (service));
1266 struct servent *svc_info;
1267 CHECK_STRING (service);
1268 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
1270 invalid_argument ("Unknown service", service);
1271 port = svc_info->s_port;
1274 get_internet_address (host, &address, ERROR_ME);
1275 address.sin_port = port;
1277 s = socket (address.sin_family, SOCK_STREAM, 0);
1279 report_file_error ("error creating socket", list1 (name));
1281 /* We don't want to be blocked on connect */
1283 unsigned long nonblock = 1;
1284 ioctlsocket (s, FIONBIO, &nonblock);
1287 retval = connect (s, (struct sockaddr *) &address, sizeof (address));
1288 if (retval != NO_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
1289 goto connect_failed;
1290 /* Wait while connection is established */
1303 /* Poll for quit every 250 ms */
1305 tv.tv_usec = 250 * 1000;
1309 nsel = select (0, NULL, &fdset, &fdset, &tv);
1313 /* Check: was connection successful or not? */
1315 nsel = select (0, NULL, NULL, &fdset, &tv);
1317 goto connect_failed;
1323 /* We are connected at this point */
1325 DuplicateHandle (GetCurrentProcess(), (HANDLE)s,
1326 GetCurrentProcess(), (LPHANDLE)voutfd,
1327 0, FALSE, DUPLICATE_SAME_ACCESS);
1334 warn_when_safe (Qstream, Qwarning,
1335 "failure to open network stream to host \"%s\" for service \"%d\"",
1336 XSTRING_DATA (host),
1337 (unsigned short) XINT (service));
1341 warn_when_safe (Qstream, Qwarning,
1342 "failure to open network stream to host \"%s\" for service \"%s\"",
1343 XSTRING_DATA (host),
1344 XSTRING_DATA (service));
1346 report_file_error ("connection failed", list2 (host, name));
1351 /*-----------------------------------------------------------------------*/
1352 /* Initialization */
1353 /*-----------------------------------------------------------------------*/
1356 process_type_create_nt (void)
1358 PROCESS_HAS_METHOD (nt, alloc_process_data);
1359 PROCESS_HAS_METHOD (nt, finalize_process_data);
1360 PROCESS_HAS_METHOD (nt, init_process);
1361 PROCESS_HAS_METHOD (nt, create_process);
1362 PROCESS_HAS_METHOD (nt, update_status_if_terminated);
1363 PROCESS_HAS_METHOD (nt, send_process);
1364 PROCESS_HAS_METHOD (nt, kill_child_process);
1365 PROCESS_HAS_METHOD (nt, kill_process_by_pid);
1367 PROCESS_HAS_METHOD (nt, canonicalize_host_name);
1368 PROCESS_HAS_METHOD (nt, open_network_stream);
1369 #ifdef HAVE_MULTICAST
1370 #error I won't do this until '95 has winsock2
1371 PROCESS_HAS_METHOD (nt, open_multicast_group);
1377 syms_of_process_nt (void)
1379 DEFSYMBOL (Qmswindows_construct_process_command_line);
1383 vars_of_process_nt (void)
1385 DEFVAR_LISP ("mswindows-start-process-share-console",
1386 &Vmswindows_start_process_share_console /*
1387 When nil, new child processes are given a new console.
1388 When non-nil, they share the Emacs console; this has the limitation of
1389 allowing only one DOS subprocess to run at a time (whether started directly
1390 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1391 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1392 otherwise respond to interrupts from Emacs.
1394 Vmswindows_start_process_share_console = Qnil;
1396 DEFVAR_LISP ("mswindows-start-process-inherit-error-mode",
1397 &Vmswindows_start_process_inherit_error_mode /*
1398 "When nil, new child processes revert to the default error mode.
1399 When non-nil, they inherit their error mode setting from Emacs, which stops
1400 them blocking when trying to access unmounted drives etc.
1402 Vmswindows_start_process_inherit_error_mode = Qt;