comparison src/process-nt.c @ 359:8e84bee8ddd0 r21-1-9

Import from CVS: tag r21-1-9
author cvs
date Mon, 13 Aug 2007 10:57:55 +0200
parents 182f72e8cd0d
children 972bbb6d6ca2
comparison
equal deleted inserted replaced
358:fed6e0f6a03a 359:8e84bee8ddd0
47 47
48 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */ 48 /* Implemenation-specific data. Pointed to by Lisp_Process->process_data */
49 struct nt_process_data 49 struct nt_process_data
50 { 50 {
51 HANDLE h_process; 51 HANDLE h_process;
52 int need_enable_child_signals;
52 }; 53 };
53 54
54 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data)) 55 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
55 56
56 /*-----------------------------------------------------------------------*/ 57 /*-----------------------------------------------------------------------*/
413 static int 414 static int
414 nt_create_process (struct Lisp_Process *p, 415 nt_create_process (struct Lisp_Process *p,
415 Lisp_Object *argv, int nargv, 416 Lisp_Object *argv, int nargv,
416 Lisp_Object program, Lisp_Object cur_dir) 417 Lisp_Object program, Lisp_Object cur_dir)
417 { 418 {
418 HANDLE hmyshove, hmyslurp, hprocin, hprocout; 419 HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
419 LPTSTR command_line; 420 LPTSTR command_line;
420 BOOL do_io, windowed; 421 BOOL do_io, windowed;
421 char *proc_env; 422 char *proc_env;
422 423
423 /* Find out whether the application is windowed or not */ 424 /* Find out whether the application is windowed or not */
463 sa.bInheritHandle = TRUE; 464 sa.bInheritHandle = TRUE;
464 sa.lpSecurityDescriptor = NULL; 465 sa.lpSecurityDescriptor = NULL;
465 466
466 CreatePipe (&hprocin, &hmyshove, &sa, 0); 467 CreatePipe (&hprocin, &hmyshove, &sa, 0);
467 CreatePipe (&hmyslurp, &hprocout, &sa, 0); 468 CreatePipe (&hmyslurp, &hprocout, &sa, 0);
469
470 /* Duplicate the stdout handle for use as stderr */
471 DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(), &hprocerr,
472 0, TRUE, DUPLICATE_SAME_ACCESS);
468 473
469 /* Stupid Win32 allows to create a pipe with *both* ends either 474 /* Stupid Win32 allows to create a pipe with *both* ends either
470 inheritable or not. We need process ends inheritable, and local 475 inheritable or not. We need process ends inheritable, and local
471 ends not inheritable. */ 476 ends not inheritable. */
472 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp, 477 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp,
591 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE; 596 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
592 if (do_io) 597 if (do_io)
593 { 598 {
594 si.hStdInput = hprocin; 599 si.hStdInput = hprocin;
595 si.hStdOutput = hprocout; 600 si.hStdOutput = hprocout;
596 si.hStdError = hprocout; 601 si.hStdError = hprocerr;
597 si.dwFlags |= STARTF_USESTDHANDLES; 602 si.dwFlags |= STARTF_USESTDHANDLES;
598 } 603 }
599 604
600 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, 605 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE,
601 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP 606 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP
606 if (do_io) 611 if (do_io)
607 { 612 {
608 /* These just have been inherited; we do not need a copy */ 613 /* These just have been inherited; we do not need a copy */
609 CloseHandle (hprocin); 614 CloseHandle (hprocin);
610 CloseHandle (hprocout); 615 CloseHandle (hprocout);
616 CloseHandle (hprocerr);
611 } 617 }
612 618
613 /* Handle process creation failure */ 619 /* Handle process creation failure */
614 if (err) 620 if (err)
615 { 621 {
632 /* Indicate as if the process has exited immediately. */ 638 /* Indicate as if the process has exited immediately. */
633 p->status_symbol = Qexit; 639 p->status_symbol = Qexit;
634 CloseHandle (pi.hProcess); 640 CloseHandle (pi.hProcess);
635 } 641 }
636 642
637 if (!windowed)
638 enable_child_signals (pi.hProcess);
639
640 ResumeThread (pi.hThread); 643 ResumeThread (pi.hThread);
641 CloseHandle (pi.hThread); 644 CloseHandle (pi.hThread);
645
646 /* Remember to enable child signals later if this is not a windowed
647 app. Can't do it right now because that screws up the MKS Toolkit
648 shell. */
649 if (!windowed)
650 {
651 NT_DATA(p)->need_enable_child_signals = 10;
652 kick_status_notify ();
653 }
642 654
643 /* Hack to support Windows 95 negative pids */ 655 /* Hack to support Windows 95 negative pids */
644 return ((int)pi.dwProcessId < 0 656 return ((int)pi.dwProcessId < 0
645 ? -(int)pi.dwProcessId : (int)pi.dwProcessId); 657 ? -(int)pi.dwProcessId : (int)pi.dwProcessId);
646 } 658 }
656 668
657 static void 669 static void
658 nt_update_status_if_terminated (struct Lisp_Process* p) 670 nt_update_status_if_terminated (struct Lisp_Process* p)
659 { 671 {
660 DWORD exit_code; 672 DWORD exit_code;
673
674 if (NT_DATA(p)->need_enable_child_signals > 1)
675 {
676 NT_DATA(p)->need_enable_child_signals -= 1;
677 kick_status_notify ();
678 }
679 else if (NT_DATA(p)->need_enable_child_signals == 1)
680 {
681 enable_child_signals(NT_DATA(p)->h_process);
682 NT_DATA(p)->need_enable_child_signals = 0;
683 }
684
661 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code) 685 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
662 && exit_code != STILL_ACTIVE) 686 && exit_code != STILL_ACTIVE)
663 { 687 {
664 p->tick++; 688 p->tick++;
665 p->core_dumped = 0; 689 p->core_dumped = 0;
756 static void 780 static void
757 nt_kill_child_process (Lisp_Object proc, int signo, 781 nt_kill_child_process (Lisp_Object proc, int signo,
758 int current_group, int nomsg) 782 int current_group, int nomsg)
759 { 783 {
760 struct Lisp_Process *p = XPROCESS (proc); 784 struct Lisp_Process *p = XPROCESS (proc);
785
786 /* Enable child signals if necessary. This may lose the first
787 but it's better than nothing. */
788 if (NT_DATA(p)->need_enable_child_signals > 0)
789 {
790 enable_child_signals(NT_DATA(p)->h_process);
791 NT_DATA(p)->need_enable_child_signals = 0;
792 }
761 793
762 /* Signal error if SIGNO cannot be sent */ 794 /* Signal error if SIGNO cannot be sent */
763 validate_signal_number (signo); 795 validate_signal_number (signo);
764 796
765 /* Send signal */ 797 /* Send signal */