comparison src/process-nt.c @ 430:a5df635868b2 r21-2-23

Import from CVS: tag r21-2-23
author cvs
date Mon, 13 Aug 2007 11:29:08 +0200
parents 3ecd8885ac67
children 3a7e78e1142d
comparison
equal deleted inserted replaced
429:8305706cbb93 430:a5df635868b2
51 51
52 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */ 52 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */
53 struct nt_process_data 53 struct nt_process_data
54 { 54 {
55 HANDLE h_process; 55 HANDLE h_process;
56 int need_enable_child_signals;
56 }; 57 };
57 58
58 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data)) 59 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
59 60
60 /*-----------------------------------------------------------------------*/ 61 /*-----------------------------------------------------------------------*/
419 static int 420 static int
420 nt_create_process (struct Lisp_Process *p, 421 nt_create_process (struct Lisp_Process *p,
421 Lisp_Object *argv, int nargv, 422 Lisp_Object *argv, int nargv,
422 Lisp_Object program, Lisp_Object cur_dir) 423 Lisp_Object program, Lisp_Object cur_dir)
423 { 424 {
424 HANDLE hmyshove, hmyslurp, hprocin, hprocout; 425 HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
425 LPTSTR command_line; 426 LPTSTR command_line;
426 BOOL do_io, windowed; 427 BOOL do_io, windowed;
427 char *proc_env; 428 char *proc_env;
428 429
429 /* Find out whether the application is windowed or not */ 430 /* Find out whether the application is windowed or not */
469 sa.bInheritHandle = TRUE; 470 sa.bInheritHandle = TRUE;
470 sa.lpSecurityDescriptor = NULL; 471 sa.lpSecurityDescriptor = NULL;
471 472
472 CreatePipe (&hprocin, &hmyshove, &sa, 0); 473 CreatePipe (&hprocin, &hmyshove, &sa, 0);
473 CreatePipe (&hmyslurp, &hprocout, &sa, 0); 474 CreatePipe (&hmyslurp, &hprocout, &sa, 0);
475
476 /* Duplicate the stdout handle for use as stderr */
477 DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(), &hprocerr,
478 0, TRUE, DUPLICATE_SAME_ACCESS);
474 479
475 /* Stupid Win32 allows to create a pipe with *both* ends either 480 /* Stupid Win32 allows to create a pipe with *both* ends either
476 inheritable or not. We need process ends inheritable, and local 481 inheritable or not. We need process ends inheritable, and local
477 ends not inheritable. */ 482 ends not inheritable. */
478 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp, 483 DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(), &htmp,
597 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE; 602 si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
598 if (do_io) 603 if (do_io)
599 { 604 {
600 si.hStdInput = hprocin; 605 si.hStdInput = hprocin;
601 si.hStdOutput = hprocout; 606 si.hStdOutput = hprocout;
602 si.hStdError = hprocout; 607 si.hStdError = hprocerr;
603 si.dwFlags |= STARTF_USESTDHANDLES; 608 si.dwFlags |= STARTF_USESTDHANDLES;
604 } 609 }
605 610
606 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, 611 err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE,
607 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP 612 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP
612 if (do_io) 617 if (do_io)
613 { 618 {
614 /* These just have been inherited; we do not need a copy */ 619 /* These just have been inherited; we do not need a copy */
615 CloseHandle (hprocin); 620 CloseHandle (hprocin);
616 CloseHandle (hprocout); 621 CloseHandle (hprocout);
622 CloseHandle (hprocerr);
617 } 623 }
618 624
619 /* Handle process creation failure */ 625 /* Handle process creation failure */
620 if (err) 626 if (err)
621 { 627 {
638 /* Indicate as if the process has exited immediately. */ 644 /* Indicate as if the process has exited immediately. */
639 p->status_symbol = Qexit; 645 p->status_symbol = Qexit;
640 CloseHandle (pi.hProcess); 646 CloseHandle (pi.hProcess);
641 } 647 }
642 648
643 if (!windowed)
644 enable_child_signals (pi.hProcess);
645
646 ResumeThread (pi.hThread); 649 ResumeThread (pi.hThread);
647 CloseHandle (pi.hThread); 650 CloseHandle (pi.hThread);
651
652 /* Remember to enable child signals later if this is not a windowed
653 app. Can't do it right now because that screws up the MKS Toolkit
654 shell. */
655 if (!windowed)
656 {
657 NT_DATA(p)->need_enable_child_signals = 10;
658 kick_status_notify ();
659 }
648 660
649 /* Hack to support Windows 95 negative pids */ 661 /* Hack to support Windows 95 negative pids */
650 return ((int)pi.dwProcessId < 0 662 return ((int)pi.dwProcessId < 0
651 ? -(int)pi.dwProcessId : (int)pi.dwProcessId); 663 ? -(int)pi.dwProcessId : (int)pi.dwProcessId);
652 } 664 }
662 674
663 static void 675 static void
664 nt_update_status_if_terminated (struct Lisp_Process* p) 676 nt_update_status_if_terminated (struct Lisp_Process* p)
665 { 677 {
666 DWORD exit_code; 678 DWORD exit_code;
679
680 if (NT_DATA(p)->need_enable_child_signals > 1)
681 {
682 NT_DATA(p)->need_enable_child_signals -= 1;
683 kick_status_notify ();
684 }
685 else if (NT_DATA(p)->need_enable_child_signals == 1)
686 {
687 enable_child_signals(NT_DATA(p)->h_process);
688 NT_DATA(p)->need_enable_child_signals = 0;
689 }
690
667 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code) 691 if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
668 && exit_code != STILL_ACTIVE) 692 && exit_code != STILL_ACTIVE)
669 { 693 {
670 p->tick++; 694 p->tick++;
671 p->core_dumped = 0; 695 p->core_dumped = 0;
762 static void 786 static void
763 nt_kill_child_process (Lisp_Object proc, int signo, 787 nt_kill_child_process (Lisp_Object proc, int signo,
764 int current_group, int nomsg) 788 int current_group, int nomsg)
765 { 789 {
766 struct Lisp_Process *p = XPROCESS (proc); 790 struct Lisp_Process *p = XPROCESS (proc);
791
792 /* Enable child signals if necessary. This may lose the first
793 but it's better than nothing. */
794 if (NT_DATA(p)->need_enable_child_signals > 0)
795 {
796 enable_child_signals(NT_DATA(p)->h_process);
797 NT_DATA(p)->need_enable_child_signals = 0;
798 }
767 799
768 /* Signal error if SIGNO cannot be sent */ 800 /* Signal error if SIGNO cannot be sent */
769 validate_signal_number (signo); 801 validate_signal_number (signo);
770 802
771 /* Send signal */ 803 /* Send signal */