2684 |
2684 |
2685 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory |
2685 exec:aCommandPath withArguments:argString environment:environment fileDescriptors:fdArray fork:doFork newPgrp:newPgrp inDirectory:aDirectory |
2686 "Internal lowLevel entry for combined fork & exec for WIN32 |
2686 "Internal lowLevel entry for combined fork & exec for WIN32 |
2687 |
2687 |
2688 If fork is false (chain a command): |
2688 If fork is false (chain a command): |
2689 execute the OS command specified by the argument, aCommandPath, with |
2689 execute the OS command specified by the argument, aCommandPath, with |
2690 arguments in argArray (no arguments, if nil). |
2690 arguments in argArray (no arguments, if nil). |
2691 If successful, this method does not return and smalltalk is gone. |
2691 If successful, this method does not return and smalltalk is gone. |
2692 If not successful, it does return. |
2692 If not successful, it does return. |
2693 Normal use is with forkForCommand. |
2693 Normal use is with forkForCommand. |
2694 |
2694 |
2695 If fork is true (subprocess command execution): |
2695 If fork is true (subprocess command execution): |
2696 fork a child to do the above. |
2696 fork a child to do the above. |
2697 The process id of the child process is returned; nil if the fork failed. |
2697 The process id of the child process is returned; nil if the fork failed. |
2698 |
2698 |
2699 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
2699 fdArray contains the filedescriptors, to be used for the child (if fork is true). |
2700 fdArray[1] = 15 -> use fd 15 as stdin. |
2700 fdArray[1] = 15 -> use fd 15 as stdin. |
2701 If an element of the array is set to nil, the corresponding filedescriptor |
2701 If an element of the array is set to nil, the corresponding filedescriptor |
2702 will be closed for the child. |
2702 will be closed for the child. |
2703 fdArray[0] == StdIn for child |
2703 fdArray[0] == StdIn for child |
2704 fdArray[1] == StdOut for child |
2704 fdArray[1] == StdOut for child |
2705 fdArray[2] == StdErr for child |
2705 fdArray[2] == StdErr for child |
2706 on VMS, these must be channels as returned by createMailBox. |
2706 on VMS, these must be channels as returned by createMailBox. |
2707 |
2707 |
2708 NOTE that in WIN32 the fds are HANDLES. |
2708 NOTE that in WIN32 the fds are HANDLES. |
2709 |
2709 |
2710 If newPgrp is true, the subprocess will be established in a new process group. |
2710 If newPgrp is true, the subprocess will be established in a new process group. |
2711 The processgroup will be equal to id. |
2711 The processgroup will be equal to id. |
2712 newPgrp is not used on WIN32 and VMS systems." |
2712 newPgrp is not used on WIN32 and VMS systems." |
2713 |
2713 |
2714 |dirPath cmdPath cmdLine| |
2714 |dirPath cmdPath cmdLine rslt| |
2715 |
2715 |
2716 aDirectory notNil ifTrue:[ |
2716 aDirectory notNil ifTrue:[ |
2717 dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory. |
2717 dirPath := aDirectory asFilename asAbsoluteFilename osNameForDirectory. |
2718 (dirPath endsWith:':') ifTrue:[ |
2718 (dirPath endsWith:':') ifTrue:[ |
2719 dirPath := dirPath , '\'. |
2719 dirPath := dirPath , '\'. |
2720 ]. |
2720 ]. |
2721 ]. |
2721 ]. |
2722 |
2722 |
2723 self isMSWINDOWSNTlike ifTrue:[ |
2723 self isMSWINDOWSNTlike ifTrue:[ |
2724 cmdPath := aCommandPath. |
2724 cmdPath := aCommandPath. |
2725 cmdLine := argString |
2725 cmdLine := argString |
2726 ] ifFalse:[ |
2726 ] ifFalse:[ |
2727 cmdPath := 'stxspawn.exe'. |
2727 cmdPath := 'stxspawn.exe'. |
2728 cmdLine := 'stxspawn.exe ' , aCommandPath , ' ' , argString |
2728 cmdLine := 'stxspawn.exe ' , aCommandPath , ' ' , argString |
2729 ]. |
2729 ]. |
2730 |
2730 |
2731 ^ self |
2731 rslt := self |
2732 primExec:cmdPath |
2732 primExec:cmdPath |
2733 commandLine:cmdLine |
2733 commandLine:cmdLine |
2734 fileDescriptors:fdArray |
2734 fileDescriptors:fdArray |
2735 fork:doFork |
2735 fork:doFork |
2736 newPgrp:newPgrp |
2736 newPgrp:newPgrp |
2737 inPath:dirPath |
2737 inPath:dirPath |
2738 createFlags:nil |
2738 createFlags:nil. |
|
2739 |
|
2740 'ctreated ' print. aCommandPath print. ' -> ' print. rslt printCR. |
|
2741 ^ rslt |
2739 |
2742 |
2740 "Modified: / 31.1.1998 / 10:54:24 / md" |
2743 "Modified: / 31.1.1998 / 10:54:24 / md" |
2741 "Modified: / 15.5.1999 / 18:07:51 / cg" |
2744 "Modified: / 15.5.1999 / 18:07:51 / cg" |
2742 ! |
2745 ! |
2743 |
2746 |
3021 or not supported by OS |
3024 or not supported by OS |
3022 " |
3025 " |
3023 ^ self primitiveFailed |
3026 ^ self primitiveFailed |
3024 ! |
3027 ! |
3025 |
3028 |
3026 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream auxFrom:anExternalAuxStream inDirectory:dirOrNil |
3029 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream |
|
3030 errorTo:anExternalErrStream auxFrom:anAuxiliaryStream |
|
3031 environment:anEvironmentDictionary inDirectory:dir |
|
3032 |
3027 "start executing the OS command as specified by the argument, aCommandString |
3033 "start executing the OS command as specified by the argument, aCommandString |
3028 as a separate process; do not wait for the command to finish. |
3034 as a separate process; do not wait for the command to finish. |
3029 The commandString is passed to a shell for execution - see the description of |
3035 The commandString is passed to a shell for execution - see the description of |
3030 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual). |
3036 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual). |
3031 The command gets stdIn, stdOut and stdErr assigned from the arguments; |
3037 The command gets stdIn, stdOut and stdErr assigned from the arguments; |
3032 each may be nil. |
3038 each may be nil. |
3033 Return the processId if successful, nil otherwise. |
3039 Return the processId if successful, nil otherwise. |
3034 Use #monitorPid:action: for synchronization and exec status return, |
3040 Use #monitorPid:action: for synchronization and exec status return, |
3035 or #killProcess: to stop it." |
3041 or #killProcess: to stop it." |
3036 |
3042 |
3037 |ret in out err shellAndArgs errStream outStream inStream| |
3043 |nullStream in out err shellAndArgs rslt auxFd| |
3038 |
3044 |
3039 aCommandString isNil ifTrue:[^ nil]. |
3045 aCommandString isNil ifTrue:[^ nil]. |
3040 |
3046 |
3041 anExternalInStream notNil ifTrue:[ |
3047 (in := anExternalInStream) isNil ifTrue:[ |
3042 in := anExternalInStream fileDescriptor. |
3048 nullStream := Filename nullDevice readWriteStream. |
3043 ] ifFalse:[ |
3049 in := nullStream. |
3044 self isMSWINDOWSNTlike ifTrue:[ |
|
3045 inStream := 'nul' asFilename readStream. |
|
3046 inStream notNil ifTrue:[ |
|
3047 in := inStream fileDescriptor. |
|
3048 ] |
|
3049 ] |
|
3050 ]. |
3050 ]. |
3051 anExternalOutStream notNil ifTrue:[ |
3051 (out := anExternalOutStream) isNil ifTrue:[ |
3052 out := anExternalOutStream fileDescriptor. |
3052 nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream]. |
3053 ] ifFalse:[ |
3053 out := nullStream. |
3054 self isMSWINDOWSNTlike ifTrue:[ |
|
3055 outStream := 'nul' asFilename writeStream. |
|
3056 outStream notNil ifTrue:[ |
|
3057 out := outStream fileDescriptor. |
|
3058 ] |
|
3059 ] |
|
3060 ]. |
3054 ]. |
3061 anExternalErrStream notNil ifTrue:[ |
3055 (err := anExternalErrStream) isNil ifTrue:[ |
3062 err := anExternalErrStream fileDescriptor. |
3056 err := out |
3063 ] ifFalse:[ |
|
3064 self isMSWINDOWSNTlike ifTrue:[ |
|
3065 errStream := 'nul' asFilename writeStream. |
|
3066 errStream notNil ifTrue:[ |
|
3067 err := errStream fileDescriptor. |
|
3068 ] |
|
3069 ] |
|
3070 ]. |
3057 ]. |
3071 anExternalAuxStream notNil ifTrue:[ |
3058 anAuxiliaryStream notNil ifTrue:[ |
3072 self error:'Aux stream is not supported in Windows' mayProceed:true. |
3059 auxFd := anAuxiliaryStream fileDescriptor |
3073 ]. |
3060 ]. |
3074 |
3061 |
3075 shellAndArgs := self commandAndArgsForOSCommand:aCommandString. |
3062 shellAndArgs := self commandAndArgsForOSCommand:aCommandString. |
3076 ret := self |
3063 |
3077 exec:(shellAndArgs at:1) |
3064 rslt := self |
3078 withArguments:(shellAndArgs at:2) |
3065 exec:(shellAndArgs at:1) |
3079 environment:nil |
3066 withArguments:(shellAndArgs at:2) |
3080 fileDescriptors:(Array with:in with:out with:err) |
3067 environment:anEvironmentDictionary |
3081 fork:true |
3068 fileDescriptors:(Array with:in fileDescriptor |
3082 newPgrp:false |
3069 with:out fileDescriptor |
3083 inDirectory:dirOrNil. |
3070 with:err fileDescriptor |
3084 |
3071 with:auxFd) |
3085 inStream notNil ifTrue:[ |
3072 fork:true |
3086 inStream close |
3073 newPgrp:true "/ false |
|
3074 inDirectory:dir. |
|
3075 |
|
3076 nullStream notNil ifTrue:[ |
|
3077 nullStream close. |
3087 ]. |
3078 ]. |
3088 outStream notNil ifTrue:[ |
3079 self halt. |
3089 outStream close |
3080 ^ rslt |
3090 ]. |
3081 |
3091 errStream notNil ifTrue:[ |
3082 "blocking at current prio (i.e. only higher prio threads execute): |
3092 errStream close |
3083 |
3093 ]. |
3084 OperatingSystem executeCommand:'ls -l > out'. |
3094 ^ ret |
3085 " |
3095 |
3086 |
3096 "Created: / 10.11.1998 / 20:48:35 / cg" |
3087 "non-blocking (lower prio threads continue): |
3097 "Modified: / 19.5.1999 / 10:43:01 / cg" |
3088 |
|
3089 |in out err pid sema| |
|
3090 |
|
3091 in := 'out' asFilename readStream. |
|
3092 out := 'out2' asFilename writeStream. |
|
3093 err := 'err' asFilename writeStream. |
|
3094 |
|
3095 sema := Semaphore new. |
|
3096 pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err. |
|
3097 |
|
3098 The following will no longer work. monitorPid has disappeared |
|
3099 |
|
3100 pid notNil ifTrue:[ |
|
3101 Processor monitorPid:pid action:[:OSstatus | sema signal ]. |
|
3102 ]. |
|
3103 in close. |
|
3104 out close. |
|
3105 err close. |
|
3106 sema wait. |
|
3107 Transcript showCR:'finished' |
|
3108 " |
|
3109 |
|
3110 "Modified: / 21.3.1997 / 10:04:35 / dq" |
|
3111 "Modified: / 15.7.1997 / 16:03:51 / stefan" |
|
3112 "Modified: / 5.6.1998 / 19:03:51 / cg" |
|
3113 "Created: / 12.11.1998 / 14:39:20 / cg" |
3098 ! ! |
3114 ! ! |
3099 |
3115 |
3100 !Win32OperatingSystem class methodsFor:'file access'! |
3116 !Win32OperatingSystem class methodsFor:'file access'! |
3101 |
3117 |
3102 closeFd:anInteger |
3118 closeFd:anInteger |
6323 OperatingSystem computeOSTimeFromYear:1970 month:1 day:1 hour:0 minute:0 seconds:0 millis:0 |
6339 OperatingSystem computeOSTimeFromYear:1970 month:1 day:1 hour:0 minute:0 seconds:0 millis:0 |
6324 " |
6340 " |
6325 |
6341 |
6326 ! |
6342 ! |
6327 |
6343 |
6328 timeInfoFromSeconds:osSeconds localTime:isLocalTime |
|
6329 "return a timeInfo structure containing values for the given |
|
6330 OS-second value. |
|
6331 An internal helper" |
|
6332 |
|
6333 |low hi year month day hours minutes seconds utcOffset |
|
6334 dst yDay wDay info| |
|
6335 |
|
6336 %{ |
|
6337 struct tm *tmPtr; |
|
6338 struct tm *gmTmPtr; |
|
6339 INT t; |
|
6340 TIME_T tt; |
|
6341 |
|
6342 t = __longIntVal(osSeconds); |
|
6343 tt = (TIME_T)t; |
|
6344 |
|
6345 tmPtr = localtime(&tt); |
|
6346 hours = __MKSMALLINT(tmPtr->tm_hour); |
|
6347 minutes = __MKSMALLINT(tmPtr->tm_min); |
|
6348 seconds = __MKSMALLINT(tmPtr->tm_sec); |
|
6349 |
|
6350 year = __MKSMALLINT(tmPtr->tm_year + 1900); |
|
6351 month = __MKSMALLINT(tmPtr->tm_mon + 1); |
|
6352 day = __MKSMALLINT(tmPtr->tm_mday); |
|
6353 |
|
6354 yDay = __MKSMALLINT(tmPtr->tm_yday+1); |
|
6355 wDay = __MKSMALLINT(tmPtr->tm_wday == 0 ? 7 : tmPtr->tm_wday); |
|
6356 |
|
6357 if (tmPtr->tm_isdst == 0) { |
|
6358 dst = false; |
|
6359 utcOffset = __MKINT(TIMEZONE(tmPtr)); |
|
6360 } else { |
|
6361 dst = true; |
|
6362 #ifdef HAS_ALTZONE |
|
6363 utcOffset = __MKINT(altzone); |
|
6364 #else |
|
6365 utcOffset = __MKINT(TIMEZONE(tmPtr) + 3600); |
|
6366 #endif |
|
6367 } |
|
6368 %}. |
|
6369 info := self timeInfoClass new. |
|
6370 |
|
6371 info |
|
6372 year:year |
|
6373 month:month |
|
6374 day:day |
|
6375 hours:hours |
|
6376 minutes:minutes |
|
6377 seconds:seconds |
|
6378 utcOffset:utcOffset |
|
6379 dst:dst |
|
6380 dayInYear:yDay |
|
6381 dayInWeek:wDay. |
|
6382 ^ info |
|
6383 |
|
6384 " |
|
6385 OperatingSystem timeInfoFromSeconds:0 localTime:false |
|
6386 " |
|
6387 ! |
|
6388 |
|
6389 computeTimePartsOf:osTime for:aBlock |
6344 computeTimePartsOf:osTime for:aBlock |
6390 "compute hours, minutes, seconds and milliseconds from the osTime |
6345 "compute hours, minutes, seconds and milliseconds from the osTime |
6391 and evaluate the argument, a 4-arg block with these. |
6346 and evaluate the argument, a 4-arg block with these. |
6392 Conversion is to localtime including any daylight saving adjustments." |
6347 Conversion is to localtime including any daylight saving adjustments." |
6393 |
6348 |
6703 " |
6658 " |
6704 ^ self primitiveFailed |
6659 ^ self primitiveFailed |
6705 |
6660 |
6706 " |
6661 " |
6707 OperatingSystem sleep:2 |
6662 OperatingSystem sleep:2 |
|
6663 " |
|
6664 ! |
|
6665 |
|
6666 timeInfoFromSeconds:osSeconds localTime:isLocalTime |
|
6667 "return a timeInfo structure containing values for the given |
|
6668 OS-second value. |
|
6669 An internal helper" |
|
6670 |
|
6671 |low hi year month day hours minutes seconds utcOffset |
|
6672 dst yDay wDay info| |
|
6673 |
|
6674 %{ |
|
6675 struct tm *tmPtr; |
|
6676 struct tm *gmTmPtr; |
|
6677 INT t; |
|
6678 TIME_T tt; |
|
6679 |
|
6680 t = __longIntVal(osSeconds); |
|
6681 tt = (TIME_T)t; |
|
6682 |
|
6683 tmPtr = localtime(&tt); |
|
6684 hours = __MKSMALLINT(tmPtr->tm_hour); |
|
6685 minutes = __MKSMALLINT(tmPtr->tm_min); |
|
6686 seconds = __MKSMALLINT(tmPtr->tm_sec); |
|
6687 |
|
6688 year = __MKSMALLINT(tmPtr->tm_year + 1900); |
|
6689 month = __MKSMALLINT(tmPtr->tm_mon + 1); |
|
6690 day = __MKSMALLINT(tmPtr->tm_mday); |
|
6691 |
|
6692 yDay = __MKSMALLINT(tmPtr->tm_yday+1); |
|
6693 wDay = __MKSMALLINT(tmPtr->tm_wday == 0 ? 7 : tmPtr->tm_wday); |
|
6694 |
|
6695 if (tmPtr->tm_isdst == 0) { |
|
6696 dst = false; |
|
6697 utcOffset = __MKINT(TIMEZONE(tmPtr)); |
|
6698 } else { |
|
6699 dst = true; |
|
6700 #ifdef HAS_ALTZONE |
|
6701 utcOffset = __MKINT(altzone); |
|
6702 #else |
|
6703 utcOffset = __MKINT(TIMEZONE(tmPtr) + 3600); |
|
6704 #endif |
|
6705 } |
|
6706 %}. |
|
6707 info := self timeInfoClass new. |
|
6708 |
|
6709 info |
|
6710 year:year |
|
6711 month:month |
|
6712 day:day |
|
6713 hours:hours |
|
6714 minutes:minutes |
|
6715 seconds:seconds |
|
6716 utcOffset:utcOffset |
|
6717 dst:dst |
|
6718 dayInYear:yDay |
|
6719 dayInWeek:wDay. |
|
6720 ^ info |
|
6721 |
|
6722 " |
|
6723 OperatingSystem timeInfoFromSeconds:0 localTime:false |
6708 " |
6724 " |
6709 ! ! |
6725 ! ! |
6710 |
6726 |
6711 !Win32OperatingSystem class methodsFor:'users & groups'! |
6727 !Win32OperatingSystem class methodsFor:'users & groups'! |
6712 |
6728 |