Win32OperatingSystem.st
changeset 7638 a211d1f10797
parent 7535 9bcb9a436394
child 7645 fd98d4cfa617
equal deleted inserted replaced
7637:6137943fb16c 7638:a211d1f10797
  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 
  8822     libraries...
  8838     libraries...
  8823 "
  8839 "
  8824 !
  8840 !
  8825 
  8841 
  8826 version
  8842 version
  8827     ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.132 2003-07-25 20:19:01 cg Exp $'
  8843     ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.133 2003-10-08 12:45:01 mb Exp $'
  8828 ! !
  8844 ! !
  8829 
  8845 
  8830 !Win32OperatingSystem::Win32FILEHandle methodsFor:'release'!
  8846 !Win32OperatingSystem::Win32FILEHandle methodsFor:'release'!
  8831 
  8847 
  8832 closeFile
  8848 closeFile
  8849     I represent a generic HANDLE, which can be closed via CloseHandle.
  8865     I represent a generic HANDLE, which can be closed via CloseHandle.
  8850 "
  8866 "
  8851 !
  8867 !
  8852 
  8868 
  8853 version
  8869 version
  8854     ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.132 2003-07-25 20:19:01 cg Exp $'
  8870     ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.133 2003-10-08 12:45:01 mb Exp $'
  8855 ! !
  8871 ! !
  8856 
  8872 
  8857 !Win32OperatingSystem::Win32Handle methodsFor:'io'!
  8873 !Win32OperatingSystem::Win32Handle methodsFor:'io'!
  8858 
  8874 
  8859 readBytes:count into:aByteBuffer startingAt:firstIndex
  8875 readBytes:count into:aByteBuffer startingAt:firstIndex
  9236 ! !
  9252 ! !
  9237 
  9253 
  9238 !Win32OperatingSystem class methodsFor:'documentation'!
  9254 !Win32OperatingSystem class methodsFor:'documentation'!
  9239 
  9255 
  9240 version
  9256 version
  9241     ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.132 2003-07-25 20:19:01 cg Exp $'
  9257     ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.133 2003-10-08 12:45:01 mb Exp $'
  9242 ! !
  9258 ! !
  9243 
  9259 
  9244 Win32OperatingSystem initialize!
  9260 Win32OperatingSystem initialize!
  9245 Win32OperatingSystem::RegistryEntry initialize!
  9261 Win32OperatingSystem::RegistryEntry initialize!