comparison src/process-nt.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 0784d089fdc9
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
1 /* Asynchronous subprocess implementation for Win32 1 /* Asynchronous subprocess implementation for Win32
2 Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995 2 Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Copyright (C) 1995 Sun Microsystems, Inc. 4 Copyright (C) 1995 Sun Microsystems, Inc.
5 Copyright (C) 1995, 1996 Ben Wing. 5 Copyright (C) 1995, 1996, 2000 Ben Wing.
6 6
7 This file is part of XEmacs. 7 This file is part of XEmacs.
8 8
9 XEmacs is free software; you can redistribute it and/or modify it 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 10 under the terms of the GNU General Public License as published by the
24 /* Written by Kirill M. Katsnelson <kkm@kis.ru>, April 1998 */ 24 /* Written by Kirill M. Katsnelson <kkm@kis.ru>, April 1998 */
25 25
26 #include <config.h> 26 #include <config.h>
27 #include "lisp.h" 27 #include "lisp.h"
28 28
29 #include "buffer.h"
30 #include "console-msw.h"
29 #include "hash.h" 31 #include "hash.h"
30 #include "lstream.h" 32 #include "lstream.h"
33 #include "nt.h"
31 #include "process.h" 34 #include "process.h"
32 #include "procimpl.h" 35 #include "procimpl.h"
33 #include "sysdep.h" 36 #include "sysdep.h"
34 37
35 #ifndef __MINGW32__
36 #include <shellapi.h> 38 #include <shellapi.h>
37 #else
38 #include <errno.h> 39 #include <errno.h>
39 #endif
40 #include <signal.h> 40 #include <signal.h>
41 #ifdef HAVE_SOCKETS 41 #ifdef HAVE_SOCKETS
42 #include <winsock.h> 42 #include <winsock.h>
43 #endif 43 #endif
44 44
45 /* Bound by win32-native.el */
46 Lisp_Object Qmswindows_construct_process_command_line;
47
45 /* Arbitrary size limit for code fragments passed to run_in_other_process */ 48 /* Arbitrary size limit for code fragments passed to run_in_other_process */
46 #define FRAGMENT_CODE_SIZE 32 49 #define FRAGMENT_CODE_SIZE 32
47 50
48 /* Bound by winnt.el */
49 Lisp_Object Qnt_quote_process_args;
50
51 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */ 51 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */
52 struct nt_process_data 52 struct nt_process_data
53 { 53 {
54 HANDLE h_process; 54 HANDLE h_process;
55 int need_enable_child_signals; 55 DWORD dwProcessId;
56 HWND hwnd; /* console window */
56 }; 57 };
58
59 /* Control how args are quoted to ensure correct parsing by child
60 process. */
61 Lisp_Object Vmswindows_quote_process_args;
62
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;
68
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;
57 73
58 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data)) 74 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
59 75
60 /*-----------------------------------------------------------------------*/ 76 /*-----------------------------------------------------------------------*/
61 /* Process helpers */ 77 /* Process helpers */
66 HANDLE 82 HANDLE
67 get_nt_process_handle (Lisp_Process *p) 83 get_nt_process_handle (Lisp_Process *p)
68 { 84 {
69 return (NT_DATA (p)->h_process); 85 return (NT_DATA (p)->h_process);
70 } 86 }
87
88 static struct Lisp_Process *
89 find_process_from_pid (DWORD pid)
90 {
91 Lisp_Object tail, proc;
92
93 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
94 {
95 proc = XCAR (tail);
96 if (NT_DATA (XPROCESS (proc))->dwProcessId == pid)
97 return XPROCESS (proc);
98 }
99 return 0;
100 }
101
71 102
72 /*-----------------------------------------------------------------------*/ 103 /*-----------------------------------------------------------------------*/
73 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5 */ 104 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5 */
74 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/ 105 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/
75 /*-----------------------------------------------------------------------*/ 106 /*-----------------------------------------------------------------------*/
166 run_in_other_process (HANDLE h_process, 197 run_in_other_process (HANDLE h_process,
167 LPTHREAD_START_ROUTINE routine, 198 LPTHREAD_START_ROUTINE routine,
168 LPVOID data, size_t data_size) 199 LPVOID data, size_t data_size)
169 { 200 {
170 process_memory pm; 201 process_memory pm;
171 CONST size_t code_size = FRAGMENT_CODE_SIZE; 202 const size_t code_size = FRAGMENT_CODE_SIZE;
172 /* Need at most 3 extra bytes of memory, for data alignment */ 203 /* Need at most 3 extra bytes of memory, for data alignment */
173 size_t total_size = code_size + data_size + 3; 204 size_t total_size = code_size + data_size + 3;
174 LPVOID remote_data; 205 LPVOID remote_data;
175 HANDLE h_thread; 206 HANDLE h_thread;
176 DWORD dw_unused; 207 DWORD dw_unused;
221 } 252 }
222 253
223 /*-----------------------------------------------------------------------*/ 254 /*-----------------------------------------------------------------------*/
224 /* Sending signals */ 255 /* Sending signals */
225 /*-----------------------------------------------------------------------*/ 256 /*-----------------------------------------------------------------------*/
257
258 /* ---------------------------- the NT way ------------------------------- */
226 259
227 /* 260 /*
228 * We handle the following signals: 261 * We handle the following signals:
229 * 262 *
230 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess 263 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
285 /* 318 /*
286 * Send signal SIGNO to process H_PROCESS. 319 * Send signal SIGNO to process H_PROCESS.
287 * Return nonzero if successful. 320 * Return nonzero if successful.
288 */ 321 */
289 322
290 /* This code assigns a return value of GetProcAddress to function pointers
291 of many different types. Instead of heavy obscure casts, we just disable
292 warnings about assignments to different function pointer types. */
293 #pragma warning (disable : 4113)
294
295 static int 323 static int
296 send_signal (HANDLE h_process, int signo) 324 send_signal_the_nt_way (struct nt_process_data *cp, int pid, int signo)
297 { 325 {
326 HANDLE h_process;
298 HMODULE h_kernel = GetModuleHandle ("kernel32"); 327 HMODULE h_kernel = GetModuleHandle ("kernel32");
328 int close_process = 0;
299 DWORD retval; 329 DWORD retval;
300 330
301 assert (h_kernel != NULL); 331 assert (h_kernel != NULL);
302 332
333 if (cp)
334 {
335 pid = cp->dwProcessId;
336 h_process = cp->h_process;
337 }
338 else
339 {
340 close_process = 1;
341 /* Try to open the process with required privileges */
342 h_process = OpenProcess (PROCESS_CREATE_THREAD
343 | PROCESS_QUERY_INFORMATION
344 | PROCESS_VM_OPERATION
345 | PROCESS_VM_WRITE,
346 FALSE, pid);
347 if (!h_process)
348 return 0;
349 }
350
303 switch (signo) 351 switch (signo)
304 { 352 {
305 case SIGKILL: 353 case SIGKILL:
306 case SIGTERM: 354 case SIGTERM:
307 case SIGQUIT: 355 case SIGQUIT:
308 case SIGHUP: 356 case SIGHUP:
309 { 357 {
310 sigkill_data d; 358 sigkill_data d;
311 d.adr_ExitProcess = GetProcAddress (h_kernel, "ExitProcess"); 359
360 d.adr_ExitProcess =
361 (void (WINAPI *) (UINT)) GetProcAddress (h_kernel, "ExitProcess");
312 assert (d.adr_ExitProcess); 362 assert (d.adr_ExitProcess);
313 retval = run_in_other_process (h_process, 363 retval = run_in_other_process (h_process,
314 (LPTHREAD_START_ROUTINE)sigkill_proc, 364 (LPTHREAD_START_ROUTINE)sigkill_proc,
315 &d, sizeof (d)); 365 &d, sizeof (d));
316 break; 366 break;
317 } 367 }
318 case SIGINT: 368 case SIGINT:
319 { 369 {
320 sigint_data d; 370 sigint_data d;
321 d.adr_GenerateConsoleCtrlEvent = 371 d.adr_GenerateConsoleCtrlEvent =
372 (BOOL (WINAPI *) (DWORD, DWORD))
322 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent"); 373 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
323 assert (d.adr_GenerateConsoleCtrlEvent); 374 assert (d.adr_GenerateConsoleCtrlEvent);
324 d.event = CTRL_C_EVENT; 375 d.event = CTRL_C_EVENT;
325 retval = run_in_other_process (h_process, 376 retval = run_in_other_process (h_process,
326 (LPTHREAD_START_ROUTINE)sigint_proc, 377 (LPTHREAD_START_ROUTINE)sigint_proc,
329 } 380 }
330 default: 381 default:
331 assert (0); 382 assert (0);
332 } 383 }
333 384
385 if (close_process)
386 CloseHandle (h_process);
334 return (int)retval > 0 ? 1 : 0; 387 return (int)retval > 0 ? 1 : 0;
335 } 388 }
336 389
337 /* 390 /*
338 * Enable CTRL_C_EVENT handling in a new child process 391 * Enable CTRL_C_EVENT handling in a new child process
343 HMODULE h_kernel = GetModuleHandle ("kernel32"); 396 HMODULE h_kernel = GetModuleHandle ("kernel32");
344 sig_enable_data d; 397 sig_enable_data d;
345 398
346 assert (h_kernel != NULL); 399 assert (h_kernel != NULL);
347 d.adr_SetConsoleCtrlHandler = 400 d.adr_SetConsoleCtrlHandler =
401 (BOOL (WINAPI *) (LPVOID, BOOL))
348 GetProcAddress (h_kernel, "SetConsoleCtrlHandler"); 402 GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
349 assert (d.adr_SetConsoleCtrlHandler); 403 assert (d.adr_SetConsoleCtrlHandler);
350 run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc, 404 run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
351 &d, sizeof (d)); 405 &d, sizeof (d));
352 } 406 }
353 407
354 #pragma warning (default : 4113) 408 #pragma warning (default : 4113)
355 409
410 /* ---------------------------- the 95 way ------------------------------- */
411
412 static BOOL CALLBACK
413 find_child_console (HWND hwnd, long putada)
414 {
415 DWORD thread_id;
416 DWORD process_id;
417 struct nt_process_data *cp = (struct nt_process_data *) putada;
418
419 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
420 if (process_id == cp->dwProcessId)
421 {
422 char window_class[32];
423
424 GetClassName (hwnd, window_class, sizeof (window_class));
425 if (strcmp (window_class,
426 mswindows_windows9x_p ()
427 ? "tty"
428 : "ConsoleWindowClass") == 0)
429 {
430 cp->hwnd = hwnd;
431 return FALSE;
432 }
433 }
434 /* keep looking */
435 return TRUE;
436 }
437
438 static int
439 send_signal_the_95_way (struct nt_process_data *cp, int pid, int signo)
440 {
441 HANDLE h_process;
442 int close_process = 0;
443 int rc = 1;
444
445 if (cp)
446 {
447 pid = cp->dwProcessId;
448 h_process = cp->h_process;
449
450 /* Try to locate console window for process. */
451 EnumWindows (find_child_console, (LPARAM) cp);
452 }
453 else
454 {
455 close_process = 1;
456 /* Try to open the process with required privileges */
457 h_process = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
458 if (!h_process)
459 return 0;
460 }
461
462 if (signo == SIGINT)
463 {
464 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
465 {
466 BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
467 BYTE vk_break_code = VK_CANCEL;
468 BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
469 HWND foreground_window;
470
471 if (break_scan_code == 0)
472 {
473 /* Fake Ctrl-C if we can't manage Ctrl-Break. */
474 vk_break_code = 'C';
475 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
476 }
477
478 foreground_window = GetForegroundWindow ();
479 if (foreground_window)
480 {
481 /* NT 5.0, and apparently also Windows 98, will not allow
482 a Window to be set to foreground directly without the
483 user's involvement. The workaround is to attach
484 ourselves to the thread that owns the foreground
485 window, since that is the only thread that can set the
486 foreground window. */
487 DWORD foreground_thread, child_thread;
488 foreground_thread =
489 GetWindowThreadProcessId (foreground_window, NULL);
490 if (foreground_thread == GetCurrentThreadId ()
491 || !AttachThreadInput (GetCurrentThreadId (),
492 foreground_thread, TRUE))
493 foreground_thread = 0;
494
495 child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
496 if (child_thread == GetCurrentThreadId ()
497 || !AttachThreadInput (GetCurrentThreadId (),
498 child_thread, TRUE))
499 child_thread = 0;
500
501 /* Set the foreground window to the child. */
502 if (SetForegroundWindow (cp->hwnd))
503 {
504 /* Generate keystrokes as if user had typed Ctrl-Break or
505 Ctrl-C. */
506 keybd_event (VK_CONTROL, control_scan_code, 0, 0);
507 keybd_event (vk_break_code, break_scan_code,
508 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
509 keybd_event (vk_break_code, break_scan_code,
510 (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
511 | KEYEVENTF_KEYUP, 0);
512 keybd_event (VK_CONTROL, control_scan_code,
513 KEYEVENTF_KEYUP, 0);
514
515 /* Sleep for a bit to give time for Emacs frame to respond
516 to focus change events (if Emacs was active app). */
517 Sleep (100);
518
519 SetForegroundWindow (foreground_window);
520 }
521 /* Detach from the foreground and child threads now that
522 the foreground switching is over. */
523 if (foreground_thread)
524 AttachThreadInput (GetCurrentThreadId (),
525 foreground_thread, FALSE);
526 if (child_thread)
527 AttachThreadInput (GetCurrentThreadId (),
528 child_thread, FALSE);
529 }
530 }
531 /* Ctrl-Break is NT equivalent of SIGINT. */
532 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
533 {
534 #if 0 /* FSF Emacs */
535 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
536 "for pid %lu\n", GetLastError (), pid));
537 errno = EINVAL;
538 #endif
539 rc = 0;
540 }
541 }
542 else
543 {
544 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
545 {
546 #if 1
547 if (mswindows_windows9x_p ())
548 {
549 /*
550 Another possibility is to try terminating the VDM out-right by
551 calling the Shell VxD (id 0x17) V86 interface, function #4
552 "SHELL_Destroy_VM", ie.
553
554 mov edx,4
555 mov ebx,vm_handle
556 call shellapi
557
558 First need to determine the current VM handle, and then arrange for
559 the shellapi call to be made from the system vm (by using
560 Switch_VM_and_callback).
561
562 Could try to invoke DestroyVM through CallVxD.
563
564 */
565 #if 0
566 /* On Win95, posting WM_QUIT causes the 16-bit subsystem
567 to hang when cmdproxy is used in conjunction with
568 command.com for an interactive shell. Posting
569 WM_CLOSE pops up a dialog that, when Yes is selected,
570 does the same thing. TerminateProcess is also less
571 than ideal in that subprocesses tend to stick around
572 until the machine is shutdown, but at least it
573 doesn't freeze the 16-bit subsystem. */
574 PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
575 #endif
576 if (!TerminateProcess (h_process, 0xff))
577 {
578 #if 0 /* FSF Emacs */
579 DebPrint (("sys_kill.TerminateProcess returned %d "
580 "for pid %lu\n", GetLastError (), pid));
581 errno = EINVAL;
582 #endif
583 rc = 0;
584 }
585 }
586 else
587 #endif
588 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
589 }
590 /* Kill the process. On W32 this doesn't kill child processes
591 so it doesn't work very well for shells which is why it's not
592 used in every case. */
593 else if (!TerminateProcess (h_process, 0xff))
594 {
595 #if 0 /* FSF Emacs */
596 DebPrint (("sys_kill.TerminateProcess returned %d "
597 "for pid %lu\n", GetLastError (), pid));
598 errno = EINVAL;
599 #endif
600 rc = 0;
601 }
602 }
603
604 if (close_process)
605 CloseHandle (h_process);
606
607 return rc;
608 }
609
610 /* -------------------------- all-OS functions ---------------------------- */
611
612 static int
613 send_signal (struct nt_process_data *cp, int pid, int signo)
614 {
615 return (!mswindows_windows9x_p () && send_signal_the_nt_way (cp, pid, signo))
616 || send_signal_the_95_way (cp, pid, signo);
617 }
618
356 /* 619 /*
357 * Signal error if SIGNO is not supported 620 * Signal error if SIGNO is not supported
358 */ 621 */
359 static void 622 static void
360 validate_signal_number (int signo) 623 validate_signal_number (int signo)
361 { 624 {
362 if (signo != SIGKILL && signo != SIGTERM 625 if (signo != SIGKILL && signo != SIGTERM
363 && signo != SIGQUIT && signo != SIGINT 626 && signo != SIGQUIT && signo != SIGINT
364 && signo != SIGHUP) 627 && signo != SIGHUP)
365 signal_simple_error ("Signal number not supported", make_int (signo)); 628 invalid_argument ("Signal number not supported", make_int (signo));
366 } 629 }
367 630
368 /*-----------------------------------------------------------------------*/ 631 /*-----------------------------------------------------------------------*/
369 /* Process methods */ 632 /* Process methods */
370 /*-----------------------------------------------------------------------*/ 633 /*-----------------------------------------------------------------------*/
381 644
382 static void 645 static void
383 nt_finalize_process_data (Lisp_Process *p, int for_disksave) 646 nt_finalize_process_data (Lisp_Process *p, int for_disksave)
384 { 647 {
385 assert (!for_disksave); 648 assert (!for_disksave);
386 if (NT_DATA(p)->h_process) 649 if (NT_DATA (p)->h_process)
387 CloseHandle (NT_DATA(p)->h_process); 650 CloseHandle (NT_DATA (p)->h_process);
388 } 651 }
389 652
390 /* 653 /*
391 * Initialize XEmacs process implementation once 654 * Initialize XEmacs process implementation once
392 */ 655 */
411 674
412 static void 675 static void
413 signal_cannot_launch (Lisp_Object image_file, DWORD err) 676 signal_cannot_launch (Lisp_Object image_file, DWORD err)
414 { 677 {
415 mswindows_set_errno (err); 678 mswindows_set_errno (err);
416 signal_simple_error_2 ("Error starting", image_file, lisp_strerror (errno)); 679 report_file_error ("Error starting", image_file);
680 }
681
682 static void
683 ensure_console_window_exists (void)
684 {
685 if (mswindows_windows9x_p ())
686 mswindows_hide_console ();
687 }
688
689 int
690 compare_env (const void *strp1, const void *strp2)
691 {
692 const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2;
693
694 while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
695 {
696 if ((*str1) > (*str2))
697 return 1;
698 else if ((*str1) < (*str2))
699 return -1;
700 str1++, str2++;
701 }
702
703 if (*str1 == '=' && *str2 == '=')
704 return 0;
705 else if (*str1 == '=')
706 return -1;
707 else
708 return 1;
417 } 709 }
418 710
419 static int 711 static int
420 nt_create_process (Lisp_Process *p, 712 nt_create_process (Lisp_Process *p,
421 Lisp_Object *argv, int nargv, 713 Lisp_Object *argv, int nargv,
422 Lisp_Object program, Lisp_Object cur_dir) 714 Lisp_Object program, Lisp_Object cur_dir)
423 { 715 {
716 /* Synched up with sys_spawnve in FSF 20.6. Significantly different
717 but still synchable. */
424 HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr; 718 HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
425 LPTSTR command_line; 719 Extbyte *command_line;
426 BOOL do_io, windowed; 720 BOOL do_io, windowed;
427 char *proc_env; 721 char *proc_env;
428 722
723 /* No need to DOS-ize the filename; expand-file-name (called prior)
724 already does this. */
725
429 /* Find out whether the application is windowed or not */ 726 /* Find out whether the application is windowed or not */
430 { 727 if (xSHGetFileInfoA)
431 /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most 728 {
432 errors. This leads to bogus error message. */ 729 /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most
433 DWORD image_type; 730 errors. This leads to bogus error message. */
434 char *p = strrchr ((char *)XSTRING_DATA (program), '.'); 731 DWORD image_type;
435 if (p != NULL && 732 char *p = strrchr ((char *)XSTRING_DATA (program), '.');
436 (stricmp (p, ".exe") == 0 || 733 if (p != NULL &&
437 stricmp (p, ".com") == 0 || 734 (stricmp (p, ".exe") == 0 ||
438 stricmp (p, ".bat") == 0 || 735 stricmp (p, ".com") == 0 ||
439 stricmp (p, ".cmd") == 0)) 736 stricmp (p, ".bat") == 0 ||
440 { 737 stricmp (p, ".cmd") == 0))
441 image_type = SHGetFileInfo ((char *)XSTRING_DATA (program), 0,NULL, 738 {
442 0, SHGFI_EXETYPE); 739 image_type = xSHGetFileInfoA ((char *)XSTRING_DATA (program), 0,NULL,
443 } 740 0, SHGFI_EXETYPE);
444 else 741 }
445 { 742 else
446 char progname[MAX_PATH]; 743 {
447 sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program)); 744 char progname[MAX_PATH];
448 image_type = SHGetFileInfo (progname, 0, NULL, 0, SHGFI_EXETYPE); 745 sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program));
449 } 746 image_type = xSHGetFileInfoA (progname, 0, NULL, 0, SHGFI_EXETYPE);
450 if (image_type == 0) 747 }
451 signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND 748 if (image_type == 0)
452 ? ERROR_BAD_FORMAT : GetLastError ())); 749 signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND
453 windowed = HIWORD (image_type) != 0; 750 ? ERROR_BAD_FORMAT : GetLastError ()));
454 } 751 windowed = HIWORD (image_type) != 0;
752 }
753 else /* NT 3.5; we have no idea so just guess. */
754 windowed = 0;
455 755
456 /* Decide whether to do I/O on process handles, or just mark the 756 /* Decide whether to do I/O on process handles, or just mark the
457 process exited immediately upon successful launching. We do I/O if the 757 process exited immediately upon successful launching. We do I/O if the
458 process is a console one, or if it is windowed but windowed_process_io 758 process is a console one, or if it is windowed but windowed_process_io
459 is non-zero */ 759 is non-zero */
471 771
472 CreatePipe (&hprocin, &hmyshove, &sa, 0); 772 CreatePipe (&hprocin, &hmyshove, &sa, 0);
473 CreatePipe (&hmyslurp, &hprocout, &sa, 0); 773 CreatePipe (&hmyslurp, &hprocout, &sa, 0);
474 774
475 /* Duplicate the stdout handle for use as stderr */ 775 /* Duplicate the stdout handle for use as stderr */
476 DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(), &hprocerr, 776 DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(),
477 0, TRUE, DUPLICATE_SAME_ACCESS); 777 &hprocerr, 0, TRUE, DUPLICATE_SAME_ACCESS);
478 778
479 /* Stupid Win32 allows to create a pipe with *both* ends either 779 /* Stupid Win32 allows to create a pipe with *both* ends either
480 inheritable or not. We need process ends inheritable, and local 780 inheritable or not. We need process ends inheritable, and local
481 ends not inheritable. */ 781 ends not inheritable. */
482 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp, 782 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(),
483 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); 783 &htmp, 0, FALSE,
784 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
484 hmyshove = htmp; 785 hmyshove = htmp;
485 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(), &htmp, 786 DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(),
486 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); 787 &htmp, 0, FALSE,
788 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
487 hmyslurp = htmp; 789 hmyslurp = htmp;
488 } 790 }
489 791
490 /* Convert an argv vector into Win32 style command line by a call to 792 /* Convert an argv vector into Win32 style command line by a call to
491 lisp function `nt-quote-process-args' which see (in winnt.el)*/ 793 lisp function `mswindows-construct-process-command-line'
794 (in win32-native.el) */
492 { 795 {
493 int i; 796 int i;
494 Lisp_Object args_or_ret = Qnil; 797 Lisp_Object args_or_ret = Qnil;
495 struct gcpro gcpro1; 798 struct gcpro gcpro1;
496 799
499 for (i = 0; i < nargv; ++i) 802 for (i = 0; i < nargv; ++i)
500 args_or_ret = Fcons (*argv++, args_or_ret); 803 args_or_ret = Fcons (*argv++, args_or_ret);
501 args_or_ret = Fnreverse (args_or_ret); 804 args_or_ret = Fnreverse (args_or_ret);
502 args_or_ret = Fcons (program, args_or_ret); 805 args_or_ret = Fcons (program, args_or_ret);
503 806
504 args_or_ret = call1 (Qnt_quote_process_args, args_or_ret); 807 args_or_ret = call1 (Qmswindows_construct_process_command_line,
808 args_or_ret);
505 809
506 if (!STRINGP (args_or_ret)) 810 if (!STRINGP (args_or_ret))
507 /* Luser wrote his/her own clever version */ 811 /* Luser wrote his/her own clever version */
508 error ("Bogus return value from `nt-quote-process-args'"); 812 invalid_argument
509 813 ("Bogus return value from `mswindows-construct-process-command-line'",
510 command_line = alloca_array (char, (XSTRING_LENGTH (program) 814 args_or_ret);
511 + XSTRING_LENGTH (args_or_ret) + 2)); 815
512 strcpy (command_line, XSTRING_DATA (program)); 816 LISP_STRING_TO_EXTERNAL (args_or_ret, command_line, Qmswindows_tstr);
513 strcat (command_line, " ");
514 strcat (command_line, XSTRING_DATA (args_or_ret));
515 817
516 UNGCPRO; /* args_or_ret */ 818 UNGCPRO; /* args_or_ret */
517 } 819 }
518 820
519 /* Set `proc_env' to a nul-separated array of the strings in 821 /* Set `proc_env' to a nul-separated array of the strings in
520 Vprocess_environment terminated by 2 nuls. */ 822 Vprocess_environment terminated by 2 nuls. */
521 823
522 { 824 {
523 extern int compare_env (const char **strp1, const char **strp2);
524 char **env; 825 char **env;
525 REGISTER Lisp_Object tem; 826 REGISTER Lisp_Object tem;
526 REGISTER char **new_env; 827 REGISTER char **new_env;
527 REGISTER int new_length = 0, i, new_space; 828 REGISTER int new_length = 0, i, new_space;
528 char *penv; 829 char *penv;
530 for (tem = Vprocess_environment; 831 for (tem = Vprocess_environment;
531 (CONSP (tem) 832 (CONSP (tem)
532 && STRINGP (XCAR (tem))); 833 && STRINGP (XCAR (tem)));
533 tem = XCDR (tem)) 834 tem = XCDR (tem))
534 new_length++; 835 new_length++;
836
837 /* FSF adds an extra env var to hold the current process ID of the
838 Emacs process. Apparently this is used only by emacsserver.c,
839 which we have superseded to gnuserv.c. (#### Does it work under
840 MS Windows?)
841
842 sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d",
843 GetCurrentProcessId ());
844 arglen += strlen (ppid_env_var_buffer) + 1;
845 numenv++;
846 */
535 847
536 /* new_length + 1 to include terminating 0. */ 848 /* new_length + 1 to include terminating 0. */
537 env = new_env = alloca_array (char *, new_length + 1); 849 env = new_env = alloca_array (char *, new_length + 1);
538 850
539 /* Copy the Vprocess_environment strings into new_env. */ 851 /* Copy the Vprocess_environment strings into new_env. */
579 new_space += strlen(env[i]) + 1; 891 new_space += strlen(env[i]) + 1;
580 } 892 }
581 new_space++; 893 new_space++;
582 894
583 /* Allocate space and copy variables into it */ 895 /* Allocate space and copy variables into it */
584 penv = proc_env = alloca(new_space); 896 penv = proc_env = (char*) alloca(new_space);
585 for (i = 0; i < new_length; i++) 897 for (i = 0; i < new_length; i++)
586 { 898 {
587 strcpy(penv, env[i]); 899 strcpy(penv, env[i]);
588 penv += strlen(env[i]) + 1; 900 penv += strlen(env[i]) + 1;
589 } 901 }
590 *penv = 0; 902 *penv = 0;
591 } 903 }
904
905 #if 0
906 /* #### we need to port this. */
907 /* On Windows 95, if cmdname is a DOS app, we invoke a helper
908 application to start it by specifying the helper app as cmdname,
909 while leaving the real app name as argv[0]. */
910 if (is_dos_app)
911 {
912 cmdname = (char*) alloca (MAXPATHLEN);
913 if (egetenv ("CMDPROXY"))
914 strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
915 else
916 {
917 strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
918 strcat ((char*)cmdname, "cmdproxy.exe");
919 }
920 }
921 #endif
592 922
593 /* Create process */ 923 /* Create process */
594 { 924 {
595 STARTUPINFO si; 925 STARTUPINFO si;
596 PROCESS_INFORMATION pi; 926 PROCESS_INFORMATION pi;
597 DWORD err; 927 DWORD err;
928 DWORD flags;
598 929
599 xzero (si); 930 xzero (si);
600 si.dwFlags = STARTF_USESHOWWINDOW; 931 si.dwFlags = STARTF_USESHOWWINDOW;
601 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE; 932 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
602 if (do_io) 933 if (do_io)
605 si.hStdOutput = hprocout; 936 si.hStdOutput = hprocout;
606 si.hStdError = hprocerr; 937 si.hStdError = hprocerr;
607 si.dwFlags |= STARTF_USESTDHANDLES; 938 si.dwFlags |= STARTF_USESTDHANDLES;
608 } 939 }
609 940
610 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, 941 flags = CREATE_SUSPENDED;
611 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP 942 if (mswindows_windows9x_p ())
612 | CREATE_SUSPENDED, 943 flags |= (!NILP (Vmswindows_start_process_share_console)
944 ? CREATE_NEW_PROCESS_GROUP
945 : CREATE_NEW_CONSOLE);
946 else
947 flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP;
948 if (NILP (Vmswindows_start_process_inherit_error_mode))
949 flags |= CREATE_DEFAULT_ERROR_MODE;
950
951 ensure_console_window_exists ();
952
953 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, flags,
613 proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi) 954 proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
614 ? 0 : GetLastError ()); 955 ? 0 : GetLastError ());
615 956
616 if (do_io) 957 if (do_io)
617 { 958 {
634 975
635 /* The process started successfully */ 976 /* The process started successfully */
636 if (do_io) 977 if (do_io)
637 { 978 {
638 NT_DATA(p)->h_process = pi.hProcess; 979 NT_DATA(p)->h_process = pi.hProcess;
980 NT_DATA(p)->dwProcessId = pi.dwProcessId;
639 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0); 981 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
640 } 982 }
641 else 983 else
642 { 984 {
643 /* Indicate as if the process has exited immediately. */ 985 /* Indicate as if the process has exited immediately. */
644 p->status_symbol = Qexit; 986 p->status_symbol = Qexit;
645 CloseHandle (pi.hProcess); 987 CloseHandle (pi.hProcess);
646 } 988 }
647 989
990 if (!windowed)
991 enable_child_signals (pi.hProcess);
992
648 ResumeThread (pi.hThread); 993 ResumeThread (pi.hThread);
649 CloseHandle (pi.hThread); 994 CloseHandle (pi.hThread);
650
651 /* Remember to enable child signals later if this is not a windowed
652 app. Can't do it right now because that screws up the MKS Toolkit
653 shell. */
654 if (!windowed)
655 {
656 NT_DATA(p)->need_enable_child_signals = 10;
657 kick_status_notify ();
658 }
659 995
660 return ((int)pi.dwProcessId); 996 return ((int)pi.dwProcessId);
661 } 997 }
662 } 998 }
663 999
671 1007
672 static void 1008 static void
673 nt_update_status_if_terminated (Lisp_Process* p) 1009 nt_update_status_if_terminated (Lisp_Process* p)
674 { 1010 {
675 DWORD exit_code; 1011 DWORD exit_code;
676
677 if (NT_DATA(p)->need_enable_child_signals > 1)
678 {
679 NT_DATA(p)->need_enable_child_signals -= 1;
680 kick_status_notify ();
681 }
682 else if (NT_DATA(p)->need_enable_child_signals == 1)
683 {
684 enable_child_signals(NT_DATA(p)->h_process);
685 NT_DATA(p)->need_enable_child_signals = 0;
686 }
687
688 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code) 1012 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
689 && exit_code != STILL_ACTIVE) 1013 && exit_code != STILL_ACTIVE)
690 { 1014 {
691 p->tick++; 1015 p->tick++;
692 p->core_dumped = 0; 1016 p->core_dumped = 0;
720 Lisp_Process *volatile p = XPROCESS (proc); 1044 Lisp_Process *volatile p = XPROCESS (proc);
721 1045
722 /* use a reasonable-sized buffer (somewhere around the size of the 1046 /* use a reasonable-sized buffer (somewhere around the size of the
723 stream buffer) so as to avoid inundating the stream with blocked 1047 stream buffer) so as to avoid inundating the stream with blocked
724 data. */ 1048 data. */
725 Bufbyte chunkbuf[128]; 1049 Bufbyte chunkbuf[512];
726 Bytecount chunklen; 1050 Bytecount chunklen;
727 1051
728 while (1) 1052 while (1)
729 { 1053 {
730 ssize_t writeret; 1054 ssize_t writeret;
731 1055
732 chunklen = Lstream_read (lstream, chunkbuf, 128); 1056 chunklen = Lstream_read (lstream, chunkbuf, 512);
733 if (chunklen <= 0) 1057 if (chunklen <= 0)
734 break; /* perhaps should abort() if < 0? 1058 break; /* perhaps should abort() if < 0?
735 This should never happen. */ 1059 This should never happen. */
736 1060
737 /* Lstream_write() will never successfully write less than the 1061 /* Lstream_write() will never successfully write less than the
746 p->exit_code = ERROR_BROKEN_PIPE; 1070 p->exit_code = ERROR_BROKEN_PIPE;
747 p->core_dumped = 0; 1071 p->core_dumped = 0;
748 p->tick++; 1072 p->tick++;
749 process_tick++; 1073 process_tick++;
750 deactivate_process (*((Lisp_Object *) (&vol_proc))); 1074 deactivate_process (*((Lisp_Object *) (&vol_proc)));
751 error ("Broken pipe error sending to process %s; closed it", 1075 invalid_operation ("Broken pipe error sending to process; closed it",
752 XSTRING_DATA (p->name)); 1076 p->name);
753 } 1077 }
754 1078
755 { 1079 {
756 int wait_ms = 25; 1080 int wait_ms = 25;
757 while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream))) 1081 while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
785 nt_kill_child_process (Lisp_Object proc, int signo, 1109 nt_kill_child_process (Lisp_Object proc, int signo,
786 int current_group, int nomsg) 1110 int current_group, int nomsg)
787 { 1111 {
788 Lisp_Process *p = XPROCESS (proc); 1112 Lisp_Process *p = XPROCESS (proc);
789 1113
790 /* Enable child signals if necessary. This may lose the first
791 but it's better than nothing. */
792 if (NT_DATA(p)->need_enable_child_signals > 0)
793 {
794 enable_child_signals(NT_DATA(p)->h_process);
795 NT_DATA(p)->need_enable_child_signals = 0;
796 }
797
798 /* Signal error if SIGNO cannot be sent */ 1114 /* Signal error if SIGNO cannot be sent */
799 validate_signal_number (signo); 1115 validate_signal_number (signo);
800 1116
801 /* Send signal */ 1117 /* Send signal */
802 if (!send_signal (NT_DATA(p)->h_process, signo)) 1118 if (!send_signal (NT_DATA (p), 0, signo))
803 error ("Cannot send signal to process"); 1119 invalid_operation ("Cannot send signal to process", proc);
804 } 1120 }
805 1121
806 /* 1122 /*
807 * Kill any process in the system given its PID. 1123 * Kill any process in the system given its PID
808 * 1124 *
809 * Returns zero if a signal successfully sent, or 1125 * Returns zero if a signal successfully sent, or
810 * negative number upon failure 1126 * negative number upon failure
811 */ 1127 */
812 static int 1128 static int
813 nt_kill_process_by_pid (int pid, int signo) 1129 nt_kill_process_by_pid (int pid, int signo)
814 { 1130 {
815 HANDLE h_process; 1131 struct Lisp_Process *p;
816 int send_result; 1132
817
818 /* Signal error if SIGNO cannot be sent */ 1133 /* Signal error if SIGNO cannot be sent */
819 validate_signal_number (signo); 1134 validate_signal_number (signo);
820 1135
821 /* Try to open the process with required privileges */ 1136 p = find_process_from_pid (pid);
822 h_process = OpenProcess (PROCESS_CREATE_THREAD 1137 return send_signal (p ? NT_DATA (p) : 0, pid, signo) ? 0 : -1;
823 | PROCESS_QUERY_INFORMATION
824 | PROCESS_VM_OPERATION
825 | PROCESS_VM_WRITE,
826 FALSE, pid);
827 if (h_process == NULL)
828 return -1;
829
830 send_result = send_signal (h_process, signo);
831
832 CloseHandle (h_process);
833
834 return send_result ? 0 : -1;
835 } 1138 }
836 1139
837 /*-----------------------------------------------------------------------*/ 1140 /*-----------------------------------------------------------------------*/
838 /* Sockets connections */ 1141 /* Sockets connections */
839 /*-----------------------------------------------------------------------*/ 1142 /*-----------------------------------------------------------------------*/
940 differences are in status display and process deletion. A network 1243 differences are in status display and process deletion. A network
941 connection has no PID; you cannot signal it. All you can do is 1244 connection has no PID; you cannot signal it. All you can do is
942 deactivate and close it via delete-process */ 1245 deactivate and close it via delete-process */
943 1246
944 static void 1247 static void
945 nt_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service, 1248 nt_open_network_stream (Lisp_Object name, Lisp_Object host,
1249 Lisp_Object service,
946 Lisp_Object protocol, void** vinfd, void** voutfd) 1250 Lisp_Object protocol, void** vinfd, void** voutfd)
947 { 1251 {
1252 /* !!#### not Mule-ized */
948 struct sockaddr_in address; 1253 struct sockaddr_in address;
949 SOCKET s; 1254 SOCKET s;
950 int port; 1255 int port;
951 int retval; 1256 int retval;
952 1257
953 CHECK_STRING (host); 1258 CHECK_STRING (host);
954 1259
955 if (!EQ (protocol, Qtcp)) 1260 if (!EQ (protocol, Qtcp))
956 error ("Unsupported protocol \"%s\"", 1261 invalid_argument ("Unsupported protocol", protocol);
957 string_data (symbol_name (XSYMBOL (protocol))));
958 1262
959 if (INTP (service)) 1263 if (INTP (service))
960 port = htons ((unsigned short) XINT (service)); 1264 port = htons ((unsigned short) XINT (service));
961 else 1265 else
962 { 1266 {
963 struct servent *svc_info; 1267 struct servent *svc_info;
964 CHECK_STRING (service); 1268 CHECK_STRING (service);
965 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp"); 1269 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
966 if (svc_info == 0) 1270 if (svc_info == 0)
967 error ("Unknown service \"%s\"", XSTRING_DATA (service)); 1271 invalid_argument ("Unknown service", service);
968 port = svc_info->s_port; 1272 port = svc_info->s_port;
969 } 1273 }
970 1274
971 get_internet_address (host, &address, ERROR_ME); 1275 get_internet_address (host, &address, ERROR_ME);
972 address.sin_port = port; 1276 address.sin_port = port;
1024 0, FALSE, DUPLICATE_SAME_ACCESS); 1328 0, FALSE, DUPLICATE_SAME_ACCESS);
1025 return; 1329 return;
1026 1330
1027 connect_failed: 1331 connect_failed:
1028 closesocket (s); 1332 closesocket (s);
1029 if (INTP (service)) { 1333 if (INTP (service))
1030 warn_when_safe(Qstream, Qwarning, 1334 {
1031 "failure to open network stream to host \"%s\" for service \"%d\"", 1335 warn_when_safe (Qstream, Qwarning,
1032 XSTRING_DATA (host), 1336 "failure to open network stream to host \"%s\" for service \"%d\"",
1033 (unsigned short) XINT (service)); 1337 XSTRING_DATA (host),
1034 } 1338 (unsigned short) XINT (service));
1035 else { 1339 }
1036 warn_when_safe(Qstream, Qwarning, 1340 else
1037 "failure to open network stream to host \"%s\" for service \"%s\"", 1341 {
1038 XSTRING_DATA (host), 1342 warn_when_safe (Qstream, Qwarning,
1039 XSTRING_DATA (service)); 1343 "failure to open network stream to host \"%s\" for service \"%s\"",
1040 } 1344 XSTRING_DATA (host),
1345 XSTRING_DATA (service));
1346 }
1041 report_file_error ("connection failed", list2 (host, name)); 1347 report_file_error ("connection failed", list2 (host, name));
1042 } 1348 }
1043 1349
1044 #endif 1350 #endif
1045 1351
1069 } 1375 }
1070 1376
1071 void 1377 void
1072 syms_of_process_nt (void) 1378 syms_of_process_nt (void)
1073 { 1379 {
1074 defsymbol (&Qnt_quote_process_args, "nt-quote-process-args"); 1380 DEFSYMBOL (Qmswindows_construct_process_command_line);
1075 } 1381 }
1076 1382
1077 void 1383 void
1078 vars_of_process_nt (void) 1384 vars_of_process_nt (void)
1079 { 1385 {
1080 } 1386 DEFVAR_LISP ("mswindows-quote-process-args",
1387 &Vmswindows_quote_process_args /*
1388 Non-nil enables quoting of process arguments to ensure correct parsing.
1389 Because Windows does not directly pass argv arrays to child processes,
1390 programs have to reconstruct the argv array by parsing the command
1391 line string. For an argument to contain a space, it must be enclosed
1392 in double quotes or it will be parsed as multiple arguments.
1393
1394 If the value is a character, that character will be used to escape any
1395 quote characters that appear, otherwise a suitable escape character
1396 will be chosen based on the type of the program (normal or Cygwin).
1397 */ );
1398 Vmswindows_quote_process_args = Qt;
1399
1400 DEFVAR_LISP ("mswindows-start-process-share-console",
1401 &Vmswindows_start_process_share_console /*
1402 When nil, new child processes are given a new console.
1403 When non-nil, they share the Emacs console; this has the limitation of
1404 allowing only only DOS subprocess to run at a time (whether started directly
1405 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1406 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1407 otherwise respond to interrupts from Emacs.
1408 */ );
1409 Vmswindows_start_process_share_console = Qnil;
1410
1411 DEFVAR_LISP ("mswindows-start-process-inherit-error-mode",
1412 &Vmswindows_start_process_inherit_error_mode /*
1413 "When nil, new child processes revert to the default error mode.
1414 When non-nil, they inherit their error mode setting from Emacs, which stops
1415 them blocking when trying to access unmounted drives etc.
1416 */ );
1417 Vmswindows_start_process_inherit_error_mode = Qt;
1418 }