comparison src/process-nt.c @ 404:2f8bb876ab1d r21-2-32

Import from CVS: tag r21-2-32
author cvs
date Mon, 13 Aug 2007 11:16:07 +0200
parents a86b2b5e0111
children b8cc9ab3f761
comparison
equal deleted inserted replaced
403:9f011ab08d48 404:2f8bb876ab1d
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 "console-msw.h"
29 #include "hash.h" 30 #include "hash.h"
30 #include "lstream.h" 31 #include "lstream.h"
31 #include "process.h" 32 #include "process.h"
32 #include "procimpl.h" 33 #include "procimpl.h"
33 #include "sysdep.h" 34 #include "sysdep.h"
34 35
35 #ifndef __MINGW32__
36 #include <shellapi.h> 36 #include <shellapi.h>
37 #else 37 #ifdef __MINGW32__
38 #include <errno.h> 38 #include <errno.h>
39 #endif 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>
50 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 DWORD dwProcessId;
56 HWND hwnd; /* console window */
55 int need_enable_child_signals; 57 int need_enable_child_signals;
56 }; 58 };
59
60 /* Control whether create_child causes the process to inherit Emacs'
61 console window, or be given a new one of its own. The default is
62 nil, to allow multiple DOS programs to run on Win95. Having separate
63 consoles also allows Emacs to cleanly terminate process groups. */
64 Lisp_Object Vmswindows_start_process_share_console;
65
66 /* Control whether create_child cause the process to inherit Emacs'
67 error mode setting. The default is t, to minimize the possibility of
68 subprocesses blocking when accessing unmounted drives. */
69 Lisp_Object Vmswindows_start_process_inherit_error_mode;
57 70
58 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data)) 71 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
59 72
60 /*-----------------------------------------------------------------------*/ 73 /*-----------------------------------------------------------------------*/
61 /* Process helpers */ 74 /* Process helpers */
66 HANDLE 79 HANDLE
67 get_nt_process_handle (Lisp_Process *p) 80 get_nt_process_handle (Lisp_Process *p)
68 { 81 {
69 return (NT_DATA (p)->h_process); 82 return (NT_DATA (p)->h_process);
70 } 83 }
84
85 static struct Lisp_Process *
86 find_process_from_pid (DWORD pid)
87 {
88 Lisp_Object tail, proc;
89
90 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
91 {
92 proc = XCAR (tail);
93 if (NT_DATA (XPROCESS (proc))->dwProcessId == pid)
94 return XPROCESS (proc);
95 }
96 return 0;
97 }
98
71 99
72 /*-----------------------------------------------------------------------*/ 100 /*-----------------------------------------------------------------------*/
73 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5 */ 101 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5 */
74 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/ 102 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/
75 /*-----------------------------------------------------------------------*/ 103 /*-----------------------------------------------------------------------*/
222 250
223 /*-----------------------------------------------------------------------*/ 251 /*-----------------------------------------------------------------------*/
224 /* Sending signals */ 252 /* Sending signals */
225 /*-----------------------------------------------------------------------*/ 253 /*-----------------------------------------------------------------------*/
226 254
255 /* ---------------------------- the NT way ------------------------------- */
256
227 /* 257 /*
228 * We handle the following signals: 258 * We handle the following signals:
229 * 259 *
230 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess 260 * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
231 * executed by the remote process 261 * executed by the remote process
285 /* 315 /*
286 * Send signal SIGNO to process H_PROCESS. 316 * Send signal SIGNO to process H_PROCESS.
287 * Return nonzero if successful. 317 * Return nonzero if successful.
288 */ 318 */
289 319
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 320 static int
296 send_signal (HANDLE h_process, int signo) 321 send_signal_the_nt_way (struct nt_process_data *cp, int pid, int signo)
297 { 322 {
323 HANDLE h_process;
298 HMODULE h_kernel = GetModuleHandle ("kernel32"); 324 HMODULE h_kernel = GetModuleHandle ("kernel32");
325 int close_process = 0;
299 DWORD retval; 326 DWORD retval;
300 327
301 assert (h_kernel != NULL); 328 assert (h_kernel != NULL);
302 329
330 if (cp)
331 {
332 pid = cp->dwProcessId;
333 h_process = cp->h_process;
334 }
335 else
336 {
337 close_process = 1;
338 /* Try to open the process with required privileges */
339 h_process = OpenProcess (PROCESS_CREATE_THREAD
340 | PROCESS_QUERY_INFORMATION
341 | PROCESS_VM_OPERATION
342 | PROCESS_VM_WRITE,
343 FALSE, pid);
344 if (!h_process)
345 return 0;
346 }
347
303 switch (signo) 348 switch (signo)
304 { 349 {
305 case SIGKILL: 350 case SIGKILL:
306 case SIGTERM: 351 case SIGTERM:
307 case SIGQUIT: 352 case SIGQUIT:
308 case SIGHUP: 353 case SIGHUP:
309 { 354 {
310 sigkill_data d; 355 sigkill_data d;
311 d.adr_ExitProcess = GetProcAddress (h_kernel, "ExitProcess"); 356
357 d.adr_ExitProcess =
358 (void (WINAPI *) (UINT)) GetProcAddress (h_kernel, "ExitProcess");
312 assert (d.adr_ExitProcess); 359 assert (d.adr_ExitProcess);
313 retval = run_in_other_process (h_process, 360 retval = run_in_other_process (h_process,
314 (LPTHREAD_START_ROUTINE)sigkill_proc, 361 (LPTHREAD_START_ROUTINE)sigkill_proc,
315 &d, sizeof (d)); 362 &d, sizeof (d));
316 break; 363 break;
317 } 364 }
318 case SIGINT: 365 case SIGINT:
319 { 366 {
320 sigint_data d; 367 sigint_data d;
321 d.adr_GenerateConsoleCtrlEvent = 368 d.adr_GenerateConsoleCtrlEvent =
369 (BOOL (WINAPI *) (DWORD, DWORD))
322 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent"); 370 GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
323 assert (d.adr_GenerateConsoleCtrlEvent); 371 assert (d.adr_GenerateConsoleCtrlEvent);
324 d.event = CTRL_C_EVENT; 372 d.event = CTRL_C_EVENT;
325 retval = run_in_other_process (h_process, 373 retval = run_in_other_process (h_process,
326 (LPTHREAD_START_ROUTINE)sigint_proc, 374 (LPTHREAD_START_ROUTINE)sigint_proc,
329 } 377 }
330 default: 378 default:
331 assert (0); 379 assert (0);
332 } 380 }
333 381
382 if (close_process)
383 CloseHandle (h_process);
334 return (int)retval > 0 ? 1 : 0; 384 return (int)retval > 0 ? 1 : 0;
335 } 385 }
336 386
337 /* 387 /*
338 * Enable CTRL_C_EVENT handling in a new child process 388 * Enable CTRL_C_EVENT handling in a new child process
343 HMODULE h_kernel = GetModuleHandle ("kernel32"); 393 HMODULE h_kernel = GetModuleHandle ("kernel32");
344 sig_enable_data d; 394 sig_enable_data d;
345 395
346 assert (h_kernel != NULL); 396 assert (h_kernel != NULL);
347 d.adr_SetConsoleCtrlHandler = 397 d.adr_SetConsoleCtrlHandler =
398 (BOOL (WINAPI *) (LPVOID, BOOL))
348 GetProcAddress (h_kernel, "SetConsoleCtrlHandler"); 399 GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
349 assert (d.adr_SetConsoleCtrlHandler); 400 assert (d.adr_SetConsoleCtrlHandler);
350 run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc, 401 run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
351 &d, sizeof (d)); 402 &d, sizeof (d));
352 } 403 }
353 404
354 #pragma warning (default : 4113) 405 #pragma warning (default : 4113)
355 406
407 /* ---------------------------- the 95 way ------------------------------- */
408
409 static BOOL CALLBACK
410 find_child_console (HWND hwnd, struct nt_process_data *cp)
411 {
412 DWORD thread_id;
413 DWORD process_id;
414
415 thread_id = GetWindowThreadProcessId (hwnd, &process_id);
416 if (process_id == cp->dwProcessId)
417 {
418 char window_class[32];
419
420 GetClassName (hwnd, window_class, sizeof (window_class));
421 if (strcmp (window_class,
422 msw_windows9x_p ()
423 ? "tty"
424 : "ConsoleWindowClass") == 0)
425 {
426 cp->hwnd = hwnd;
427 return FALSE;
428 }
429 }
430 /* keep looking */
431 return TRUE;
432 }
433
434 static int
435 send_signal_the_95_way (struct nt_process_data *cp, int pid, int signo)
436 {
437 HANDLE h_process;
438 int close_process = 0;
439 int rc = 1;
440
441 if (cp)
442 {
443 pid = cp->dwProcessId;
444 h_process = cp->h_process;
445
446 /* Try to locate console window for process. */
447 EnumWindows (find_child_console, (LPARAM) cp);
448 }
449 else
450 {
451 close_process = 1;
452 /* Try to open the process with required privileges */
453 h_process = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
454 if (!h_process)
455 return 0;
456 }
457
458 if (signo == SIGINT)
459 {
460 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
461 {
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;
466
467 if (break_scan_code == 0)
468 {
469 /* Fake Ctrl-C if we can't manage Ctrl-Break. */
470 vk_break_code = 'C';
471 break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
472 }
473
474 foreground_window = GetForegroundWindow ();
475 if (foreground_window)
476 {
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;
484 foreground_thread =
485 GetWindowThreadProcessId (foreground_window, NULL);
486 if (foreground_thread == GetCurrentThreadId ()
487 || !AttachThreadInput (GetCurrentThreadId (),
488 foreground_thread, TRUE))
489 foreground_thread = 0;
490
491 child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
492 if (child_thread == GetCurrentThreadId ()
493 || !AttachThreadInput (GetCurrentThreadId (),
494 child_thread, TRUE))
495 child_thread = 0;
496
497 /* Set the foreground window to the child. */
498 if (SetForegroundWindow (cp->hwnd))
499 {
500 /* Generate keystrokes as if user had typed Ctrl-Break or
501 Ctrl-C. */
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,
509 KEYEVENTF_KEYUP, 0);
510
511 /* Sleep for a bit to give time for Emacs frame to respond
512 to focus change events (if Emacs was active app). */
513 Sleep (100);
514
515 SetForegroundWindow (foreground_window);
516 }
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);
522 if (child_thread)
523 AttachThreadInput (GetCurrentThreadId (),
524 child_thread, FALSE);
525 }
526 }
527 /* Ctrl-Break is NT equivalent of SIGINT. */
528 else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
529 {
530 #if 0 /* FSF Emacs */
531 DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
532 "for pid %lu\n", GetLastError (), pid));
533 errno = EINVAL;
534 #endif
535 rc = 0;
536 }
537 }
538 else
539 {
540 if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
541 {
542 #if 1
543 if (msw_windows9x_p ())
544 {
545 /*
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.
549
550 mov edx,4
551 mov ebx,vm_handle
552 call shellapi
553
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).
557
558 Could try to invoke DestroyVM through CallVxD.
559
560 */
561 #if 0
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);
571 #endif
572 if (!TerminateProcess (h_process, 0xff))
573 {
574 #if 0 /* FSF Emacs */
575 DebPrint (("sys_kill.TerminateProcess returned %d "
576 "for pid %lu\n", GetLastError (), pid));
577 errno = EINVAL;
578 #endif
579 rc = 0;
580 }
581 }
582 else
583 #endif
584 PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
585 }
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))
590 {
591 #if 0 /* FSF Emacs */
592 DebPrint (("sys_kill.TerminateProcess returned %d "
593 "for pid %lu\n", GetLastError (), pid));
594 errno = EINVAL;
595 #endif
596 rc = 0;
597 }
598 }
599
600 if (close_process)
601 CloseHandle (h_process);
602
603 return rc;
604 }
605
606 /* -------------------------- all-OS functions ---------------------------- */
607
608 static int
609 send_signal (struct nt_process_data *cp, int pid, int signo)
610 {
611 return send_signal_the_nt_way (cp, pid, signo)
612 || send_signal_the_95_way (cp, pid, signo);
613 }
614
356 /* 615 /*
357 * Signal error if SIGNO is not supported 616 * Signal error if SIGNO is not supported
358 */ 617 */
359 static void 618 static void
360 validate_signal_number (int signo) 619 validate_signal_number (int signo)
381 640
382 static void 641 static void
383 nt_finalize_process_data (Lisp_Process *p, int for_disksave) 642 nt_finalize_process_data (Lisp_Process *p, int for_disksave)
384 { 643 {
385 assert (!for_disksave); 644 assert (!for_disksave);
386 if (NT_DATA(p)->h_process) 645 if (NT_DATA (p)->h_process)
387 CloseHandle (NT_DATA(p)->h_process); 646 CloseHandle (NT_DATA (p)->h_process);
388 } 647 }
389 648
390 /* 649 /*
391 * Initialize XEmacs process implementation once 650 * Initialize XEmacs process implementation once
392 */ 651 */
412 static void 671 static void
413 signal_cannot_launch (Lisp_Object image_file, DWORD err) 672 signal_cannot_launch (Lisp_Object image_file, DWORD err)
414 { 673 {
415 mswindows_set_errno (err); 674 mswindows_set_errno (err);
416 signal_simple_error_2 ("Error starting", image_file, lisp_strerror (errno)); 675 signal_simple_error_2 ("Error starting", image_file, lisp_strerror (errno));
676 }
677
678 static void
679 ensure_console_window_exists ()
680 {
681 if (msw_windows9x_p ())
682 msw_hide_console ();
417 } 683 }
418 684
419 static int 685 static int
420 nt_create_process (Lisp_Process *p, 686 nt_create_process (Lisp_Process *p,
421 Lisp_Object *argv, int nargv, 687 Lisp_Object *argv, int nargv,
593 /* Create process */ 859 /* Create process */
594 { 860 {
595 STARTUPINFO si; 861 STARTUPINFO si;
596 PROCESS_INFORMATION pi; 862 PROCESS_INFORMATION pi;
597 DWORD err; 863 DWORD err;
864 DWORD flags;
598 865
599 xzero (si); 866 xzero (si);
600 si.dwFlags = STARTF_USESHOWWINDOW; 867 si.dwFlags = STARTF_USESHOWWINDOW;
601 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE; 868 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
602 if (do_io) 869 if (do_io)
605 si.hStdOutput = hprocout; 872 si.hStdOutput = hprocout;
606 si.hStdError = hprocerr; 873 si.hStdError = hprocerr;
607 si.dwFlags |= STARTF_USESTDHANDLES; 874 si.dwFlags |= STARTF_USESTDHANDLES;
608 } 875 }
609 876
610 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, 877 flags = CREATE_SUSPENDED;
611 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP 878 if (msw_windows9x_p ())
612 | CREATE_SUSPENDED, 879 flags |= (!NILP (Vmswindows_start_process_share_console)
880 ? CREATE_NEW_PROCESS_GROUP
881 : CREATE_NEW_CONSOLE);
882 else
883 flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP;
884 if (NILP (Vmswindows_start_process_inherit_error_mode))
885 flags |= CREATE_DEFAULT_ERROR_MODE;
886
887 ensure_console_window_exists ();
888
889 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, flags,
613 proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi) 890 proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
614 ? 0 : GetLastError ()); 891 ? 0 : GetLastError ());
615 892
616 if (do_io) 893 if (do_io)
617 { 894 {
634 911
635 /* The process started successfully */ 912 /* The process started successfully */
636 if (do_io) 913 if (do_io)
637 { 914 {
638 NT_DATA(p)->h_process = pi.hProcess; 915 NT_DATA(p)->h_process = pi.hProcess;
916 NT_DATA(p)->dwProcessId = pi.dwProcessId;
639 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0); 917 init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
640 } 918 }
641 else 919 else
642 { 920 {
643 /* Indicate as if the process has exited immediately. */ 921 /* Indicate as if the process has exited immediately. */
787 { 1065 {
788 Lisp_Process *p = XPROCESS (proc); 1066 Lisp_Process *p = XPROCESS (proc);
789 1067
790 /* Enable child signals if necessary. This may lose the first 1068 /* Enable child signals if necessary. This may lose the first
791 but it's better than nothing. */ 1069 but it's better than nothing. */
792 if (NT_DATA(p)->need_enable_child_signals > 0) 1070 if (NT_DATA (p)->need_enable_child_signals > 0)
793 { 1071 {
794 enable_child_signals(NT_DATA(p)->h_process); 1072 enable_child_signals (NT_DATA(p)->h_process);
795 NT_DATA(p)->need_enable_child_signals = 0; 1073 NT_DATA (p)->need_enable_child_signals = 0;
796 } 1074 }
797 1075
798 /* Signal error if SIGNO cannot be sent */ 1076 /* Signal error if SIGNO cannot be sent */
799 validate_signal_number (signo); 1077 validate_signal_number (signo);
800 1078
801 /* Send signal */ 1079 /* Send signal */
802 if (!send_signal (NT_DATA(p)->h_process, signo)) 1080 if (!send_signal (NT_DATA (p), 0, signo))
803 error ("Cannot send signal to process"); 1081 signal_simple_error ("Cannot send signal to process", proc);
804 } 1082 }
805 1083
806 /* 1084 /*
807 * Kill any process in the system given its PID. 1085 * Kill any process in the system given its PID.
808 * 1086 *
810 * negative number upon failure 1088 * negative number upon failure
811 */ 1089 */
812 static int 1090 static int
813 nt_kill_process_by_pid (int pid, int signo) 1091 nt_kill_process_by_pid (int pid, int signo)
814 { 1092 {
815 HANDLE h_process; 1093 struct Lisp_Process *p;
816 int send_result; 1094
817
818 /* Signal error if SIGNO cannot be sent */ 1095 /* Signal error if SIGNO cannot be sent */
819 validate_signal_number (signo); 1096 validate_signal_number (signo);
820 1097
821 /* Try to open the process with required privileges */ 1098 p = find_process_from_pid (pid);
822 h_process = OpenProcess (PROCESS_CREATE_THREAD 1099 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 } 1100 }
836 1101
837 /*-----------------------------------------------------------------------*/ 1102 /*-----------------------------------------------------------------------*/
838 /* Sockets connections */ 1103 /* Sockets connections */
839 /*-----------------------------------------------------------------------*/ 1104 /*-----------------------------------------------------------------------*/
940 differences are in status display and process deletion. A network 1205 differences are in status display and process deletion. A network
941 connection has no PID; you cannot signal it. All you can do is 1206 connection has no PID; you cannot signal it. All you can do is
942 deactivate and close it via delete-process */ 1207 deactivate and close it via delete-process */
943 1208
944 static void 1209 static void
945 nt_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service, 1210 nt_open_network_stream (Lisp_Object name, Lisp_Object host,
1211 Lisp_Object service,
946 Lisp_Object protocol, void** vinfd, void** voutfd) 1212 Lisp_Object protocol, void** vinfd, void** voutfd)
947 { 1213 {
1214 /* !!#### not Mule-ized */
948 struct sockaddr_in address; 1215 struct sockaddr_in address;
949 SOCKET s; 1216 SOCKET s;
950 int port; 1217 int port;
951 int retval; 1218 int retval;
952 1219
953 CHECK_STRING (host); 1220 CHECK_STRING (host);
954 1221
955 if (!EQ (protocol, Qtcp)) 1222 if (!EQ (protocol, Qtcp))
956 error ("Unsupported protocol \"%s\"", 1223 signal_simple_error ("Unsupported protocol", protocol);
957 string_data (symbol_name (XSYMBOL (protocol))));
958 1224
959 if (INTP (service)) 1225 if (INTP (service))
960 port = htons ((unsigned short) XINT (service)); 1226 port = htons ((unsigned short) XINT (service));
961 else 1227 else
962 { 1228 {
963 struct servent *svc_info; 1229 struct servent *svc_info;
964 CHECK_STRING (service); 1230 CHECK_STRING (service);
965 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp"); 1231 svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
966 if (svc_info == 0) 1232 if (svc_info == 0)
967 error ("Unknown service \"%s\"", XSTRING_DATA (service)); 1233 signal_simple_error ("Unknown service", service);
968 port = svc_info->s_port; 1234 port = svc_info->s_port;
969 } 1235 }
970 1236
971 get_internet_address (host, &address, ERROR_ME); 1237 get_internet_address (host, &address, ERROR_ME);
972 address.sin_port = port; 1238 address.sin_port = port;
1024 0, FALSE, DUPLICATE_SAME_ACCESS); 1290 0, FALSE, DUPLICATE_SAME_ACCESS);
1025 return; 1291 return;
1026 1292
1027 connect_failed: 1293 connect_failed:
1028 closesocket (s); 1294 closesocket (s);
1029 if (INTP (service)) { 1295 if (INTP (service))
1030 warn_when_safe(Qstream, Qwarning, 1296 {
1031 "failure to open network stream to host \"%s\" for service \"%d\"", 1297 warn_when_safe (Qstream, Qwarning,
1032 XSTRING_DATA (host), 1298 "failure to open network stream to host \"%s\" for service \"%d\"",
1033 (unsigned short) XINT (service)); 1299 XSTRING_DATA (host),
1034 } 1300 (unsigned short) XINT (service));
1035 else { 1301 }
1036 warn_when_safe(Qstream, Qwarning, 1302 else
1037 "failure to open network stream to host \"%s\" for service \"%s\"", 1303 {
1038 XSTRING_DATA (host), 1304 warn_when_safe (Qstream, Qwarning,
1039 XSTRING_DATA (service)); 1305 "failure to open network stream to host \"%s\" for service \"%s\"",
1040 } 1306 XSTRING_DATA (host),
1307 XSTRING_DATA (service));
1308 }
1041 report_file_error ("connection failed", list2 (host, name)); 1309 report_file_error ("connection failed", list2 (host, name));
1042 } 1310 }
1043 1311
1044 #endif 1312 #endif
1045 1313
1075 } 1343 }
1076 1344
1077 void 1345 void
1078 vars_of_process_nt (void) 1346 vars_of_process_nt (void)
1079 { 1347 {
1080 } 1348 DEFVAR_LISP ("mswindows-start-process-share-console",
1349 &Vmswindows_start_process_share_console /*
1350 When nil, new child processes are given a new console.
1351 When non-nil, they share the Emacs console; this has the limitation of
1352 allowing only only DOS subprocess to run at a time (whether started directly
1353 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1354 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1355 otherwise respond to interrupts from Emacs.
1356 */ );
1357 Vmswindows_start_process_share_console = Qnil;
1358
1359 DEFVAR_LISP ("mswindows-start-process-inherit-error-mode",
1360 &Vmswindows_start_process_inherit_error_mode /*
1361 "When nil, new child processes revert to the default error mode.
1362 When non-nil, they inherit their error mode setting from Emacs, which stops
1363 them blocking when trying to access unmounted drives etc.
1364 */ );
1365 Vmswindows_start_process_inherit_error_mode = Qt;
1366 }