3660 "Modified: / 20-01-1998 / 16:57:19 / md" |
3674 "Modified: / 20-01-1998 / 16:57:19 / md" |
3661 "Modified: / 11-02-2007 / 20:51:08 / cg" |
3675 "Modified: / 11-02-2007 / 20:51:08 / cg" |
3662 ! |
3676 ! |
3663 |
3677 |
3664 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork |
3678 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork |
3665 newPgrp:newPgrp inDirectory:aDirectory |
3679 newPgrp:newPgrp inDirectory:aDirectory |
3666 showWindow:showWindowBooleanOrNil |
3680 showWindow:showWindowBooleanOrNil |
3667 |
3681 |
3668 "Internal lowLevel entry for combined fork & exec for WIN32 |
3682 "Internal lowLevel entry for combined fork & exec for WIN32 |
3669 |
3683 |
3670 If fork is false (chain a command): |
3684 If fork is false (chain a command): |
3671 execute the OS command specified by the argument, aCommandPath, with |
3685 execute the OS command specified by the argument, aCommandPath, with |
3672 arguments in argArray (no arguments, if nil). |
3686 arguments in argArray (no arguments, if nil). |
3673 If successful, this method does not return and smalltalk is gone. |
3687 If successful, this method does not return and smalltalk is gone. |
3674 If not successful, it does return. |
3688 If not successful, it does return. |
3675 Normal use is with forkForCommand. |
3689 Normal use is with forkForCommand. |
3676 |
3690 |
3677 If fork is true (subprocess command execution): |
3691 If fork is true (subprocess command execution): |
3678 fork a child to do the above. |
3692 fork a child to do the above. |
3679 The Win32ProcessHandle of the child process is returned; nil if the fork failed. |
3693 The Win32ProcessHandle of the child process is returned; nil if the fork failed. |
3680 |
3694 |
3681 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
3695 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
3682 fdArray[1] = 15 -> use fd 15 as stdin. |
3696 fdArray[1] = 15 -> use fd 15 as stdin. |
3683 If an element of the array is set to nil, the corresponding filedescriptor |
3697 If an element of the array is set to nil, the corresponding filedescriptor |
3684 will be closed for the child. |
3698 will be closed for the child. |
3685 fdArray[0] == StdIn for child |
3699 fdArray[0] == StdIn for child |
3686 fdArray[1] == StdOut for child |
3700 fdArray[1] == StdOut for child |
3687 fdArray[2] == StdErr for child |
3701 fdArray[2] == StdErr for child |
3688 |
3702 |
3689 NOTE that in WIN32 the fds are HANDLES. |
3703 NOTE that in WIN32 the fds are HANDLES. |
3690 |
3704 |
3691 If newPgrp is true, the subprocess will be established in a new process group. |
3705 If newPgrp is true, the subprocess will be established in a new process group. |
3692 The processgroup will be equal to id. |
3706 The processgroup will be equal to id. |
3693 newPgrp is not used on WIN32 and VMS systems. |
3707 newPgrp is not used on WIN32 and VMS systems. |
3694 |
3708 |
3695 showWindowOrBoolean may be: |
3709 showWindowOrBoolean may be: |
3696 true - a window is shown on start of the command |
3710 true - a window is shown on start of the command |
3697 false - the command window is hidden |
3711 false - the command window is hidden |
3698 nil - the nCmdShown parameter of the commans's winmain function determins, |
3712 nil - the nCmdShown parameter of the commans's winmain function determins, |
3699 if a window is shown. |
3713 if a window is shown. |
3700 #default |
3714 #default |
3701 - same as nil |
3715 - same as nil |
3702 " |
3716 " |
3703 |
3717 |
3704 |dirPath rslt| |
3718 |dirPath rslt| |
3705 |
3719 |
3706 aDirectory notNil ifTrue:[ |
3720 aDirectory notNil ifTrue:[ |
3707 dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory. |
3721 dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory. |
3708 (dirPath endsWith:':') ifTrue:[ |
3722 (dirPath endsWith:':') ifTrue:[ |
3709 dirPath := dirPath , '\'. |
3723 dirPath := dirPath , '\'. |
3710 ]. |
3724 ]. |
3711 ]. |
3725 ]. |
3712 |
3726 |
3713 rslt := self |
3727 rslt := self |
3714 primExec:aCommandPath |
3728 primExec:aCommandPath |
3715 commandLine:argString |
3729 commandLine:argString |
3716 fileDescriptors:fdArray |
3730 fileDescriptors:fdArray |
3717 fork:doFork |
3731 fork:doFork |
3718 newPgrp:newPgrp |
3732 newPgrp:newPgrp |
3719 inPath:dirPath |
3733 inPath:dirPath |
3720 createFlags:nil |
3734 createFlags:nil |
3721 inheritHandles:true |
3735 inheritHandles:true |
3722 showWindow:showWindowBooleanOrNil. |
3736 showWindow:showWindowBooleanOrNil. |
3723 |
3737 |
3724 "/ 'created ' print. cmdLine print. ' -> ' print. rslt printCR. |
3738 "/ 'created ' print. cmdLine print. ' -> ' print. rslt printCR. |
3725 ^ rslt |
3739 ^ rslt |
3726 |
3740 |
3727 "Modified: / 31-01-1998 / 10:54:24 / md" |
3741 "Modified: / 31-01-1998 / 10:54:24 / md" |
3904 PROCESS_INFORMATION lppiProcInfo; |
3922 PROCESS_INFORMATION lppiProcInfo; |
3905 SECURITY_ATTRIBUTES securityAttributes; |
3923 SECURITY_ATTRIBUTES securityAttributes; |
3906 SECURITY_DESCRIPTOR securityDescriptor; |
3924 SECURITY_DESCRIPTOR securityDescriptor; |
3907 |
3925 |
3908 if ((__isUnicode16String(commandPathUni16) || (commandPathUni16 == nil)) && __isUnicode16String(commandLineUni16)) { |
3926 if ((__isUnicode16String(commandPathUni16) || (commandPathUni16 == nil)) && __isUnicode16String(commandLineUni16)) { |
3909 HANDLE stdinHandle = NULL; |
3927 HANDLE stdinHandle = NULL; |
3910 HANDLE stdoutHandle = NULL; |
3928 HANDLE stdoutHandle = NULL; |
3911 HANDLE stderrHandle = NULL; |
3929 HANDLE stderrHandle = NULL; |
3912 int mustClose_stdinHandle = 0; |
3930 int mustClose_stdinHandle = 0; |
3913 int mustClose_stdoutHandle = 0; |
3931 int mustClose_stdoutHandle = 0; |
3914 int mustClose_stderrHandle = 0; |
3932 int mustClose_stderrHandle = 0; |
3915 |
3933 |
3916 /* |
3934 /* |
3917 * terminate the multi byte strings |
3935 * terminate the multi byte strings |
3918 */ |
3936 */ |
3919 // #commandPathUni16 |
3937 // #commandPathUni16 |
3920 if (commandPathUni16 != nil) { |
3938 if (commandPathUni16 != nil) { |
3921 l = __unicode16StringSize(commandPathUni16); |
3939 l = __unicode16StringSize(commandPathUni16); |
3922 if (l >= 4096) { // >= need 1 space for terminator |
3940 if (l >= 4096) { // >= need 1 space for terminator |
3923 #ifdef PROCESSDEBUGWIN32 |
3941 # ifdef PROCESSDEBUGWIN32 |
3924 console_fprintf(stderr, "argument #commandPathUni16 is to long\n"); |
3942 if (flag_PROCESSDEBUGWIN32) { |
3925 #endif |
3943 console_fprintf(stderr, "argument #commandPathUni16 is to long\n"); |
3926 RETURN(nil); |
3944 } |
3927 } |
3945 # endif |
3928 for (i = 0; i < l; i++) { |
3946 RETURN(nil); |
3929 cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i]; |
3947 } |
3930 } |
3948 for (i = 0; i < l; i++) { |
3931 cmdPathW[i] = 0; // set terminator |
3949 cmdPathW[i] = __unicode16StringVal(commandPathUni16)[i]; |
3932 cmdPathWP = &cmdPathW[0]; |
3950 } |
3933 } |
3951 cmdPathW[i] = 0; // set terminator |
3934 |
3952 cmdPathWP = &cmdPathW[0]; |
3935 // commandLineUni16 |
3953 } |
3936 l = __unicode16StringSize(commandLineUni16); |
3954 |
3937 if (l >= 4096) { // >= need 1 space for terminator |
3955 // commandLineUni16 |
3938 #ifdef PROCESSDEBUGWIN32 |
3956 l = __unicode16StringSize(commandLineUni16); |
3939 console_fprintf(stderr, "argument #commandLineUni16 is to long\n"); |
3957 if (l >= 4096) { // >= need 1 space for terminator |
3940 #endif |
3958 # ifdef PROCESSDEBUGWIN32 |
3941 RETURN(nil); |
3959 if (flag_PROCESSDEBUGWIN32) { |
3942 } |
3960 console_fprintf(stderr, "argument #commandLineUni16 is to long\n"); |
3943 for (i = 0; i < l; i++) { |
3961 } |
3944 cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i]; |
3962 # endif |
3945 } |
3963 RETURN(nil); |
3946 cmdLineW[i] = 0; // set terminator |
3964 } |
3947 cmdLineWP = &cmdLineW[0]; |
3965 for (i = 0; i < l; i++) { |
3948 |
3966 cmdLineW[i] = __unicode16StringVal(commandLineUni16)[i]; |
3949 // #dirNameUni16 |
3967 } |
3950 if (__isUnicode16String(dirNameUni16)) { |
3968 cmdLineW[i] = 0; // set terminator |
3951 l = __unicode16StringSize(dirNameUni16); |
3969 cmdLineWP = &cmdLineW[0]; |
3952 if (l >= 4096) { // >= need 1 space for terminator |
3970 |
3953 #ifdef PROCESSDEBUGWIN32 |
3971 // #dirNameUni16 |
3954 console_fprintf(stderr, "argument #dirNameUni16 is to long\n"); |
3972 if (__isUnicode16String(dirNameUni16)) { |
3955 #endif |
3973 l = __unicode16StringSize(dirNameUni16); |
3956 RETURN(nil); |
3974 if (l >= 4096) { // >= need 1 space for terminator |
3957 } |
3975 # ifdef PROCESSDEBUGWIN32 |
3958 for (i = 0; i < l; i++) { |
3976 if (flag_PROCESSDEBUGWIN32) { |
3959 dirNameW[i] = __unicode16StringVal(dirNameUni16)[i]; |
3977 console_fprintf(stderr, "argument #dirNameUni16 is to long\n"); |
3960 } |
3978 } |
3961 dirNameW[i] = 0; // set terminator |
3979 # endif |
3962 dirNameWP = &dirNameW[0]; |
3980 RETURN(nil); |
3963 } |
3981 } |
3964 |
3982 for (i = 0; i < l; i++) { |
3965 /* |
3983 dirNameW[i] = __unicode16StringVal(dirNameUni16)[i]; |
3966 * create descriptors as req'd |
3984 } |
3967 */ |
3985 dirNameW[i] = 0; // set terminator |
3968 memset(&securityAttributes, 0, sizeof(securityAttributes)); |
3986 dirNameWP = &dirNameW[0]; |
3969 securityAttributes.nLength = sizeof(securityAttributes); |
3987 } |
3970 securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE; |
3988 |
3971 |
3989 /* |
3972 InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION); |
3990 * create descriptors as req'd |
3973 SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0); |
3991 */ |
3974 |
3992 memset(&securityAttributes, 0, sizeof(securityAttributes)); |
3975 securityAttributes.lpSecurityDescriptor = &securityDescriptor; |
3993 securityAttributes.nLength = sizeof(securityAttributes); |
3976 memset(&lppiProcInfo, 0, sizeof (lppiProcInfo)); |
3994 securityAttributes.bInheritHandle = (inheritHandles == true) ? TRUE : FALSE; |
3977 |
3995 |
3978 memset(&lpsiStartInfo, 0, sizeof(lpsiStartInfo)); |
3996 InitializeSecurityDescriptor(&securityDescriptor, SECURITY_DESCRIPTOR_REVISION); |
3979 lpsiStartInfo.cb = sizeof(lpsiStartInfo); |
3997 SetSecurityDescriptorDacl(&securityDescriptor, -1, 0, 0); |
3980 lpsiStartInfo.lpReserved = NULL; |
3998 |
3981 lpsiStartInfo.lpDesktop = NULL; |
3999 securityAttributes.lpSecurityDescriptor = &securityDescriptor; |
3982 lpsiStartInfo.lpTitle = NULL; |
4000 |
3983 lpsiStartInfo.dwX = 0; |
4001 memset(&lpsiStartInfo, 0, sizeof(lpsiStartInfo)); |
3984 lpsiStartInfo.dwY = 0; |
4002 lpsiStartInfo.cb = sizeof(lpsiStartInfo); |
3985 lpsiStartInfo.dwXSize = 100; |
4003 lpsiStartInfo.lpReserved = NULL; |
3986 lpsiStartInfo.dwYSize = 100; |
4004 lpsiStartInfo.lpDesktop = NULL; |
3987 lpsiStartInfo.dwXCountChars = 0; |
4005 lpsiStartInfo.lpTitle = NULL; |
3988 lpsiStartInfo.dwYCountChars = 0; |
4006 lpsiStartInfo.dwX = 0; |
3989 lpsiStartInfo.dwFillAttribute = 0; |
4007 lpsiStartInfo.dwY = 0; |
3990 lpsiStartInfo.dwFlags = STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/; |
4008 lpsiStartInfo.dwXSize = 100; |
3991 if ((showWindowBooleanOrNil != nil) && (showWindowBooleanOrNil != @symbol(default))) { |
4009 lpsiStartInfo.dwYSize = 100; |
3992 lpsiStartInfo.dwFlags |= STARTF_USESHOWWINDOW; |
4010 lpsiStartInfo.dwXCountChars = 0; |
3993 lpsiStartInfo.wShowWindow = showWindowBooleanOrNil == true ? SW_SHOWNORMAL : SW_HIDE; |
4011 lpsiStartInfo.dwYCountChars = 0; |
3994 } |
4012 lpsiStartInfo.dwFillAttribute = 0; |
3995 lpsiStartInfo.cbReserved2 = 0; |
4013 lpsiStartInfo.dwFlags = STARTF_USESTDHANDLES /*| STARTF_USEPOSITION*/; |
3996 lpsiStartInfo.lpReserved2 = NULL; |
4014 if ((showWindowBooleanOrNil != nil) && (showWindowBooleanOrNil != @symbol(default))) { |
3997 lpsiStartInfo.hStdInput = NULL; |
4015 lpsiStartInfo.dwFlags |= STARTF_USESHOWWINDOW; |
3998 lpsiStartInfo.hStdOutput = NULL; |
4016 lpsiStartInfo.wShowWindow = showWindowBooleanOrNil == true ? SW_SHOWNORMAL : SW_HIDE; |
3999 lpsiStartInfo.hStdError = NULL; |
4017 } |
4000 |
4018 lpsiStartInfo.cbReserved2 = 0; |
4001 /* |
4019 lpsiStartInfo.lpReserved2 = NULL; |
4002 * set create process flags |
4020 lpsiStartInfo.hStdInput = NULL; |
4003 * if the flags arg is nil, use common defaults; |
4021 lpsiStartInfo.hStdOutput = NULL; |
4004 * if non-nil, it must be a positive integer containing the fdwCreate bits. |
4022 lpsiStartInfo.hStdError = NULL; |
4005 */ |
4023 |
4006 if (flagsOrNil != nil) { |
4024 /* |
4007 fdwCreate = __longIntVal(flagsOrNil); |
4025 * set create process flags |
4008 } else { |
4026 * if the flags arg is nil, use common defaults; |
4009 fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ; |
4027 * if non-nil, it must be a positive integer containing the fdwCreate bits. |
4010 if (newPgrp == true) { |
4028 */ |
4011 fdwCreate |= CREATE_NEW_PROCESS_GROUP; |
4029 if (flagsOrNil != nil) { |
4012 } |
4030 fdwCreate = __longIntVal(flagsOrNil); |
4013 fdwCreate |= CREATE_DEFAULT_ERROR_MODE; |
4031 } else { |
4014 } |
4032 fdwCreate = CREATE_NEW_CONSOLE; //|IDLE_PRIORITY_CLASS; // DETACHED_PROCESS; // NORMAL_PRIORITY_CLASS ; |
4015 |
4033 if (newPgrp == true) { |
4016 if (fdArray == nil) { |
4034 fdwCreate |= CREATE_NEW_PROCESS_GROUP; |
4017 stdinHandle = (HANDLE) _get_osfhandle (0); |
4035 } |
4018 stdoutHandle = (HANDLE) _get_osfhandle (1); |
4036 fdwCreate |= CREATE_DEFAULT_ERROR_MODE; |
4019 stderrHandle = (HANDLE) _get_osfhandle (2); |
4037 } |
4020 } else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) { |
4038 |
4021 if (__ArrayInstPtr(fdArray)->a_element[0] != nil) { |
4039 if (fdArray == nil) { |
4022 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) { |
4040 stdinHandle = (HANDLE) _get_osfhandle (0); |
4023 stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]); |
4041 stdoutHandle = (HANDLE) _get_osfhandle (1); |
4024 } else { |
4042 stderrHandle = (HANDLE) _get_osfhandle (2); |
4025 stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0])); |
4043 } else if (__isArrayLike(fdArray) && (__arraySize(fdArray) >= 3)) { |
4026 } |
4044 if (__ArrayInstPtr(fdArray)->a_element[0] != nil) { |
4027 } |
4045 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[0])) { |
4028 if (__ArrayInstPtr(fdArray)->a_element[1] != nil) { |
4046 stdinHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[0]); |
4029 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) { |
4047 } else { |
4030 stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]); |
4048 stdinHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[0])); |
4031 } else { |
4049 } |
4032 stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1])); |
4050 } |
4033 } |
4051 if (__ArrayInstPtr(fdArray)->a_element[1] != nil) { |
4034 } |
4052 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[1])) { |
4035 if (__ArrayInstPtr(fdArray)->a_element[2] != nil) { |
4053 stdoutHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[1]); |
4036 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) { |
4054 } else { |
4037 stderrHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]); |
4055 stdoutHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[1])); |
4038 } else { |
4056 } |
4039 stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2])); |
4057 } |
4040 } |
4058 if (__ArrayInstPtr(fdArray)->a_element[2] != nil) { |
4041 } |
4059 if (__isExternalAddressLike(__ArrayInstPtr(fdArray)->a_element[2])) { |
4042 } else { |
4060 stderrHandle = _HANDLEVal(__ArrayInstPtr(fdArray)->a_element[2]); |
4043 console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n"); |
4061 } else { |
4044 } |
4062 stderrHandle = (HANDLE) _get_osfhandle (__intVal(__ArrayInstPtr(fdArray)->a_element[2])); |
|
4063 } |
|
4064 } |
|
4065 } else { |
|
4066 console_fprintf(stderr, "Win32OS [warning]: bad fd arg in createProcess\n"); |
|
4067 } |
4045 |
4068 |
4046 #if defined(PROCESSDEBUGWIN32) |
4069 #if defined(PROCESSDEBUGWIN32) |
4047 console_fprintf(stderr, "stdin %x\n", stdinHandle); |
4070 if (flag_PROCESSDEBUGWIN32) { |
4048 console_fprintf(stderr, "stdout %x\n", stdoutHandle); |
4071 console_fprintf(stderr, "stdin %x\n", stdinHandle); |
4049 console_fprintf(stderr, "stderr %x\n", stderrHandle); |
4072 console_fprintf(stderr, "stdout %x\n", stdoutHandle); |
4050 #endif |
4073 console_fprintf(stderr, "stderr %x\n", stderrHandle); |
4051 |
4074 } |
4052 { |
4075 #endif |
4053 HANDLE childHandle; |
4076 |
4054 int sameHandle = (stdoutHandle == stderrHandle); |
4077 { |
4055 |
4078 HANDLE childHandle; |
4056 // these MUST be inheritable! |
4079 int sameHandle = (stdoutHandle == stderrHandle); |
4057 if (stdinHandle) { |
4080 |
|
4081 // these MUST be inheritable! |
|
4082 if (stdinHandle) { |
4058 #if 0 |
4083 #if 0 |
4059 if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { |
4084 if (SetHandleInformation(stdinHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { |
4060 // good |
4085 // good |
4061 } else { |
4086 } else { |
4062 console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n"); |
4087 console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n"); |
4063 } |
4088 } |
4064 #else |
4089 #else |
4065 if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(), |
4090 if (DuplicateHandle(GetCurrentProcess(), stdinHandle, GetCurrentProcess(), |
4066 &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
4091 &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
4067 stdinHandle = childHandle; |
4092 stdinHandle = childHandle; |
4068 mustClose_stdinHandle = 1; |
4093 mustClose_stdinHandle = 1; |
4069 } else { |
4094 } else { |
4070 console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n"); |
4095 console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n"); |
4071 } |
4096 } |
4072 #endif |
4097 #endif |
4073 } |
4098 } |
4074 if (stdoutHandle) { |
4099 if (stdoutHandle) { |
4075 #if 0 |
4100 #if 0 |
4076 if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { |
4101 if (SetHandleInformation(stdoutHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { |
4077 // good |
4102 // good |
4078 } else { |
4103 } else { |
4079 console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n"); |
4104 console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n"); |
4080 } |
4105 } |
4081 #else |
4106 #else |
4082 if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(), |
4107 if (DuplicateHandle(GetCurrentProcess(), stdoutHandle, GetCurrentProcess(), |
4083 &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
4108 &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
4084 stdoutHandle = childHandle; |
4109 stdoutHandle = childHandle; |
4085 mustClose_stdoutHandle = 1; |
4110 mustClose_stdoutHandle = 1; |
4086 } else { |
4111 } else { |
4087 console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n"); |
4112 console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n"); |
4088 } |
4113 } |
4089 #endif |
4114 #endif |
4090 } |
4115 } |
4091 if (stderrHandle) { |
4116 if (stderrHandle) { |
4092 if (sameHandle) { |
4117 if (sameHandle) { |
4093 stderrHandle = stdoutHandle; |
4118 stderrHandle = stdoutHandle; |
4094 } else { |
4119 } else { |
4095 #if 0 |
4120 #if 0 |
4096 if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { |
4121 if (SetHandleInformation(stderrHandle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { |
4097 // good |
4122 // good |
4098 } else { |
4123 } else { |
4099 console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n"); |
4124 console_fprintf(stderr, "Win32OS [warning]: SetHandleInformation failed in createProcess\n"); |
4100 } |
4125 } |
4101 #else |
4126 #else |
4102 if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(), |
4127 if (DuplicateHandle(GetCurrentProcess(), stderrHandle, GetCurrentProcess(), |
4103 &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
4128 &childHandle, 0, TRUE, DUPLICATE_SAME_ACCESS)) { |
4104 stderrHandle = childHandle; |
4129 stderrHandle = childHandle; |
4105 mustClose_stderrHandle = 1; |
4130 mustClose_stderrHandle = 1; |
4106 } else { |
4131 } else { |
4107 console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n"); |
4132 console_fprintf(stderr, "Win32OS [warning]: duplicateHandle failed in createProcess\n"); |
4108 } |
4133 } |
4109 #endif |
4134 #endif |
4110 } |
4135 } |
4111 } |
4136 } |
4112 } |
4137 } |
4113 lpsiStartInfo.hStdInput = stdinHandle; |
4138 lpsiStartInfo.hStdInput = stdinHandle; |
4114 lpsiStartInfo.hStdOutput = stdoutHandle; |
4139 lpsiStartInfo.hStdOutput = stdoutHandle; |
4115 lpsiStartInfo.hStdError = stderrHandle; |
4140 lpsiStartInfo.hStdError = stderrHandle; |
4116 |
4141 |
4117 if (doFork == true) { |
4142 if (doFork == true) { |
4118 #ifdef PROCESSDEBUGWIN32 |
4143 #ifdef PROCESSDEBUGWIN32 |
4119 console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir); |
4144 if (flag_PROCESSDEBUGWIN32) { |
4120 #endif |
4145 console_fprintf(stderr, "create process cmdPath:<%s> cmdLine:<%s> in <%s>\n", cmdPath, cmdLine, dir); |
4121 if (CreateProcessW( cmdPathWP, |
4146 } |
4122 cmdLineWP, |
4147 #endif |
4123 &securityAttributes, NULL /* &securityAttributes */, |
4148 memset(&lppiProcInfo, 0, sizeof (lppiProcInfo)); |
4124 securityAttributes.bInheritHandle, /* inherit handles */ |
4149 |
4125 fdwCreate | CREATE_SUSPENDED, /* resume after setting affinity */ |
4150 if (CreateProcessW( cmdPathWP, |
4126 NULL, /* env */ |
4151 cmdLineWP, |
4127 dirNameWP, |
4152 &securityAttributes, NULL /* &securityAttributes */, |
4128 &lpsiStartInfo, |
4153 securityAttributes.bInheritHandle, /* inherit handles */ |
4129 &lppiProcInfo )) |
4154 fdwCreate | CREATE_SUSPENDED, /* resume after setting affinity */ |
4130 { |
4155 NULL, /* env */ |
4131 DWORD_PTR processAffinityMask, systemAffinityMask; |
4156 dirNameWP, |
4132 |
4157 &lpsiStartInfo, |
4133 /* |
4158 &lppiProcInfo )) |
4134 * Process was created suspended, now set the affinity mask |
4159 { |
4135 * to any processor, and resume the processes main thread. |
4160 DWORD_PTR processAffinityMask, systemAffinityMask; |
4136 * (librun/process.s limited the affinity to a single processor). |
4161 |
4137 */ |
4162 /* |
4138 GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask); |
4163 * Process was created suspended, now set the affinity mask |
4139 SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask); |
4164 * to any processor, and resume the processes main thread. |
4140 if ((fdwCreate & CREATE_SUSPENDED) == 0) { |
4165 * (librun/process.s limited the affinity to a single processor). |
4141 ResumeThread(lppiProcInfo.hThread); |
4166 */ |
4142 } |
4167 GetProcessAffinityMask(lppiProcInfo.hProcess, &processAffinityMask, &systemAffinityMask); |
4143 CloseHandle(lppiProcInfo.hThread); |
4168 SetProcessAffinityMask(lppiProcInfo.hProcess, systemAffinityMask); |
|
4169 if ((fdwCreate & CREATE_SUSPENDED) == 0) { |
|
4170 ResumeThread(lppiProcInfo.hThread); |
|
4171 } |
|
4172 CloseHandle(lppiProcInfo.hThread); |
4144 |
4173 |
4145 #if 0 |
4174 #if 0 |
4146 // only works with real console handles |
4175 // only works with real console handles |
4147 { |
4176 { |
4148 // change the child's stdIn (console) mode |
4177 // change the child's stdIn (console) mode |
4149 DWORD mode = 0; |
4178 DWORD mode = 0; |
4150 |
4179 |
4151 if (! GetConsoleMode(stdinHandle, &mode)) { |
4180 if (! GetConsoleMode(stdinHandle, &mode)) { |
4152 console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n"); |
4181 console_fprintf(stderr, "Win32OS [warning]: GetConsoleMode failed in createProcess\n"); |
4153 } |
4182 } |
4154 if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){ |
4183 if (! SetConsoleMode(stdinHandle, mode & (~ENABLE_ECHO_INPUT))){ |
4155 console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n"); |
4184 console_fprintf(stderr, "Win32OS [warning]: SetConsoleMode failed in createProcess\n"); |
4156 } |
4185 } |
4157 } |
4186 } |
4158 #endif |
4187 #endif |
4159 if (mustClose_stdinHandle) { |
4188 if (mustClose_stdinHandle) { |
4160 CloseHandle(stdinHandle); |
4189 CloseHandle(stdinHandle); |
4161 } |
4190 } |
4162 if (mustClose_stdoutHandle) { |
4191 if (mustClose_stdoutHandle) { |
4163 CloseHandle(stdoutHandle); |
4192 CloseHandle(stdoutHandle); |
4164 } |
4193 } |
4165 if (mustClose_stderrHandle) { |
4194 if (mustClose_stderrHandle) { |
4166 CloseHandle(stderrHandle); |
4195 CloseHandle(stderrHandle); |
4167 } |
4196 } |
4168 #ifdef PROCESSDEBUGWIN32 |
4197 #ifdef PROCESSDEBUGWIN32 |
4169 console_fprintf(stderr, "created process hProcess=%x\n", lppiProcInfo.hProcess); |
4198 if (flag_PROCESSDEBUGWIN32) { |
4170 #endif |
4199 console_fprintf(stderr, "created process hProcess=%x pid=%d\n", lppiProcInfo.hProcess, lppiProcInfo.dwProcessId); |
4171 |
4200 } |
4172 __externalAddressVal(handle) = lppiProcInfo.hProcess; |
4201 #endif |
4173 ((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId); |
4202 |
4174 RETURN (handle); |
4203 __externalAddressVal(handle) = lppiProcInfo.hProcess; |
4175 } |
4204 ((struct __Win32OperatingSystem__Win32ProcessHandle_struct *)(handle))->pid = __mkSmallInteger(lppiProcInfo.dwProcessId); |
|
4205 RETURN (handle); |
|
4206 } |
4176 #ifdef PROCESSDEBUGWIN32 |
4207 #ifdef PROCESSDEBUGWIN32 |
4177 console_fprintf(stderr, "created process error %d\n", GetLastError()); |
4208 if (flag_PROCESSDEBUGWIN32) { |
4178 #endif |
4209 console_fprintf(stderr, "created process error %d\n", GetLastError()); |
4179 RETURN (nil); |
4210 } |
4180 } else { |
4211 #endif |
4181 ; /* should never be called that way */ |
4212 RETURN (nil); |
4182 } |
4213 } else { |
|
4214 ; /* should never be called that way */ |
|
4215 } |
4183 } |
4216 } |
4184 %}. |
4217 %}. |
4185 " |
4218 " |
4186 path-argument not string |
4219 path-argument not string |
4187 or argArray not an array/nil |
4220 or argArray not an array/nil |