--- a/AbstractOperatingSystem.st Wed Dec 28 22:58:47 2016 +0000
+++ b/AbstractOperatingSystem.st Thu Jan 05 21:02:10 2017 +0000
@@ -903,16 +903,6 @@
!AbstractOperatingSystem class methodsFor:'executing OS commands-implementation'!
-exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork newPgrp:newGrp inDirectory:aDirectory
- "execute an OS command"
-
- ^ self
- exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork
- newPgrp:newGrp inDirectory:aDirectory showWindow:false
-
- "Created: / 12.11.1998 / 14:46:15 / cg"
-!
-
exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork
newPgrp:newGrp inDirectory:aDirectory showWindow:showWindowBooleanOrNil
"execute an OS command"
@@ -941,243 +931,206 @@
!
startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment inDirectory:dir
+ errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
+ environment:anEvironmentDictionary inDirectory:dir newPgrp:newPgrp showWindow:showWindowBooleanOrNil
"start executing the OS command as specified by the argument, aCommandString
as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- The command gets stdIn, stdOut and stdErr assigned from the arguments;
- each may be nil.
- Return the processId if successful, nil otherwise.
- Use #monitorPid:action: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- "raise an error: must be redefined in concrete subclass(es)"
-
- ^ self
- startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil
- environment:environment inDirectory:dir
- showWindow:nil
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment
- inDirectory:dir newPgrp:newPgrp showWindow:showWindowBooleanOrNil
-
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- The command gets stdIn, stdOut and stdErr assigned from the arguments;
- each may be nil.
- Return the processId if successful, nil otherwise.
- Use #monitorPid:action: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- "raise an error: must be redefined in concrete subclass(es)"
-
- ^ self subclassResponsibility
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment
- inDirectory:dir showWindow:showWindowBooleanOrNil
-
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+ If aCommandString is a String, the commandString is passed to a shell for execution
+ - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+ If aCommandString is an Array, the first element is the command to be executed,
+ and the other elements are the arguments to the command. No shell is invoked in this case.
The command gets stdIn, stdOut and stdErr assigned from the arguments;
each may be nil.
Return the processId if successful, nil otherwise.
Use #monitorPid:action: for synchronization and exec status return,
or #killProcess: to stop it."
- "raise an error: must be redefined in concrete subclass(es)"
-
- ^ self
- startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment
- inDirectory:dir newPgrp:true showWindow:showWindowBooleanOrNil
-
- "Modified: / 08-11-2016 / 21:24:27 / cg"
-! !
-
-!AbstractOperatingSystem class methodsFor:'executing OS commands-private'!
-
-shuffleAllFrom:anInStream to:anOutStream lineWise:lineWise lockWith:aLock
-
- lineWise ifFalse:[
- ^ anInStream copyToEndInto:anOutStream.
+ |nullStream in out err shellAndArgs rslt auxFd|
+
+ aCommandString isNil ifTrue:[^ nil].
+
+ (in := anExternalInStream) isNil ifTrue:[
+ nullStream := Filename nullDevice readWriteStream.
+ in := nullStream.
+ ].
+ (out := anExternalOutStream) isNil ifTrue:[
+ nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
+ out := nullStream.
+ ].
+ (err := anExternalErrStream) isNil ifTrue:[
+ err := out
+ ].
+ anAuxiliaryStream notNil ifTrue:[
+ auxFd := anAuxiliaryStream fileHandle.
].
- [anInStream isOpen and:[anInStream atEnd not]] whileTrue:[
- aLock critical:[
- self
- shuffleFrom:anInStream
- to:anOutStream
- lineWise:lineWise
- ]
- ]
-!
-
-shuffleFrom:anInStream to:anOutStream lineWise:lineWise
- "copy data from anInStream to anOutStream.
- Caller makes sure, than anInStream does not block.
- anOutstream should have been set to non-blocking-mode"
-
- lineWise ifTrue:[
- |data|
-
- data := anInStream nextLine.
- data notNil ifTrue:[
- anOutStream nextPutLine:data
- ] .
- ] ifFalse:[
- anInStream copyToEndInto:anOutStream.
+
+ shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
+
+ rslt := self
+ exec:(shellAndArgs at:1)
+ withArguments:(shellAndArgs at:2)
+ environment:anEvironmentDictionary
+ fileDescriptors:(Array with:in fileHandle
+ with:out fileHandle
+ with:err fileHandle
+ with:auxFd)
+ fork:true
+ newPgrp:newPgrp
+ inDirectory:dir
+ showWindow:(showWindowBooleanOrNil ? (shellAndArgs at:3)).
+
+ nullStream notNil ifTrue:[
+ nullStream close.
].
-!
-
-shuffleRestFrom:anInStream to:anOutStream lineWise:lineWise
- [anInStream atEnd] whileFalse:[
- self
- shuffleFrom:anInStream
- to:anOutStream
- lineWise:lineWise.
- ].
-!
-
-startProcess:aCommandString
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual.
- Return the processId if successful, nil otherwise.
- Use #waitForProcess: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- ^ self
- startProcess:aCommandString
- inputFrom:nil
- outputTo:nil
- errorTo:nil
- auxFrom:nil
- inDirectory:nil
-
- "
- |pid|
-
- pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
- (Delay forSeconds:3) wait.
- OperatingSystem killProcess:pid.
- "
- "
- |pid|
-
- pid := OperatingSystem startProcess:'dir/l'.
- (Delay forSeconds:1) wait.
- OperatingSystem killProcess:pid.
- "
- "
- |pid|
-
- pid := OperatingSystem
- startProcess:'dir/l'
- inputFrom:nil
- outputTo:Stdout
- errorTo:nil
- inDirectory:nil.
- (Delay forSeconds:2) wait.
- OperatingSystem killProcess:pid.
- "
+
+ ^ rslt
+
+ "blocking at current prio (i.e. only higher prio threads execute):
+
+ OperatingSystem executeCommand:'ls -l > out'.
+ OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
+ "
+
+ "non-blocking (lower prio threads continue):
+
+ |in out err pid sema|
+
+ in := 'out' asFilename readStream.
+ out := 'out2' asFilename writeStream.
+ err := 'err' asFilename writeStream.
+
+ sema := Semaphore new.
+ pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
+
+ The following will no longer work. monitorPid has disappeared
+
+ pid notNil ifTrue:[
+ Processor monitorPid:pid action:[:osStatus | sema signal ].
+ ].
+ in close.
+ out close.
+ err close.
+ sema wait.
+ Transcript showCR:'finished'
+ "
+
+ "
+ |pid sema|
+
+ sema := Semaphore new.
+
+ Processor
+ monitor:[
+ pid := OperatingSystem startProcess:'(sleep 2; ls -l) > out 2>err'
+ ]
+ action:[:osStatus | sema signal ].
+
+ sema wait.
+ Transcript showCR:'finished'
+ "
+
+ "
+ |pid sema|
+
+ sema := Semaphore new.
+
+ Processor
+ monitor:[
+ pid := OperatingSystem startProcess:'(sleep 1; echo 1; sleep 9; ls -l) > out 2>err'
+ ]
+ action:[:osStatus | sema signal ].
+
+ Delay waitForSeconds:2.
+ OperatingSystem terminateProcess:pid.
+ Transcript showCR:'terminated'
+ "
+
+ "======================== WINDOWS: ==================================================================="
+
+ "blocking at current prio (i.e. only higher prio threads execute):
+
+ OperatingSystem executeCommand:'dir > out'.
+ OperatingSystem executeCommand:'tree /A' outputTo:Transcript.
+ OperatingSystem executeCommand:#('c:\windows\system32\tree.com' '/A' '/F') outputTo:Transcript.
+ OperatingSystem executeCommand:#('c:\windows\system32\where.exe' '/T' '*.dll') outputTo:Transcript.
+ "
+
+ "non-blocking (lower prio threads continue):
+
+ |in out err pid sema|
+
+ in := 'out' asFilename readStream.
+ out := 'out2' asFilename writeStream.
+ err := 'err' asFilename writeStream.
+
+ sema := Semaphore new.
+ pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
+
+ The following will no longer work. monitorPid has disappeared
+
+ pid notNil ifTrue:[
+ Processor monitorPid:pid action:[:OSstatus | sema signal ].
+ ].
+ in close.
+ out close.
+ err close.
+ sema wait.
+ Transcript showCR:'finished'
+ "
+
+ "
+ |pid sema|
+
+ sema := Semaphore new.
+
+ Processor
+ monitor:[
+ pid := OperatingSystem startProcess:'dir > out 2>err'
+ ]
+ action:[:osStatus | sema signal ].
+
+ sema wait.
+ Transcript showCR:'finished'
+ "
+
+"<<END
+ |pid sema|
+
+ sema := Semaphore new.
+
+ Processor
+ monitor:[
+ pid := OperatingSystem startProcess:'(echo 1 & stx --eval "Delay waitForSeconds:100" & dir) >out' withCRs
+ ]
+ action:[:osStatus | sema signal ].
+
+ Delay waitForSeconds:5.
+ OperatingSystem terminateProcessGroup:pid.
+ Transcript showCR:'terminated'
+END"
+
+"<<END
+ |pid sema|
+
+ sema := Semaphore new.
+
+ Processor
+ monitor:[
+ pid := OperatingSystem startProcess:{ 'C:\Users\cg\work\stx\projects\smalltalk\stx.com' . '--eval' . '"Delay waitForSeconds:100"' }
+ ]
+ action:[:osStatus | sema signal ].
+
+ Delay waitForSeconds:5.
+ OperatingSystem terminateProcess:pid.
+ Transcript showCR:'terminated'
+END"
+
"Modified: / 21.3.1997 / 10:04:35 / dq"
- "Modified: / 10.11.1998 / 21:03:50 / cg"
-!
-
-startProcess:aCommandString inDirectory:aDirectory
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual.
- Return the processId if successful, nil otherwise.
- Use #waitForProcess: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- ^ self
- startProcess:aCommandString
- inputFrom:nil
- outputTo:nil
- errorTo:nil
- auxFrom:nil
- inDirectory:aDirectory
- "
- |pid|
-
- pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
- (Delay forSeconds:3) wait.
- OperatingSystem killProcess:pid.
- "
-
- "Modified: / 21.3.1997 / 10:04:35 / dq"
- "Modified: / 28.1.1998 / 14:13:33 / md"
- "Modified: / 10.11.1998 / 20:59:33 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- The command gets stdIn, stdOut and stdErr assigned from the arguments;
- each may be nil.
- Return the processId if successful, nil otherwise.
- Use #monitorPid:action: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- ^ self
- startProcess:aCommandString
- inputFrom:anExternalInStream
- outputTo:anExternalOutStream
- errorTo:anExternalErrStream
- auxFrom:nil
- inDirectory:nil
-
- "Modified: / 10.11.1998 / 20:59:05 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anAuxiliaryStream inDirectory:dir
-
- ^ self
- startProcess:aCommandString
- inputFrom:anExternalInStream
- outputTo:anExternalOutStream
- errorTo:anExternalErrStream
- auxFrom:anAuxiliaryStream
- environment:nil
- inDirectory:dir
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream inDirectory:dir
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- The commandString is passed to a shell for execution - see the description of
- 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- The command gets stdIn, stdOut and stdErr assigned from the arguments;
- each may be nil.
- Return the processId if successful, nil otherwise.
- Use #monitorPid:action: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- ^ self
- startProcess:aCommandString
- inputFrom:anExternalInStream
- outputTo:anExternalOutStream
- errorTo:anExternalErrStream
- auxFrom:nil
- inDirectory:dir
+ "Modified: / 15.7.1997 / 16:03:51 / stefan"
+ "Modified: / 5.6.1998 / 19:03:51 / cg"
+ "Created: / 12.11.1998 / 14:39:20 / cg"
! !
!AbstractOperatingSystem class methodsFor:'executing OS commands-public'!
@@ -1467,258 +1420,24 @@
This argument is ignored on Unix systems.
See examples below."
- |pid exitStatus sema pIn pOut pErr pAux externalInStream externalOutStream externalErrStream externalAuxStream
- shuffledInStream shuffledOutStream shuffledErrStream shuffledAuxStream
- inputShufflerProcess outputShufflerProcess errorShufflerProcess auxShufflerProcess stopShufflers
- inStreamToClose outStreamToClose errStreamToClose auxStreamToClose nullStream terminateLock
- closeStreams|
-
- terminateLock := Semaphore forMutualExclusion.
- ((externalInStream := anInStream) notNil
- and:[externalInStream isExternalStream not]) ifTrue:[
- pIn := NonPositionableExternalStream makePipe.
- inStreamToClose := externalInStream := pIn at:1.
- shuffledInStream := pIn at:2.
- anInStream isBinary ifTrue:[
- shuffledInStream binary
- ].
- lineWise ifFalse:[
- shuffledInStream blocking:false.
- ].
-
- "/ start a reader process, shuffling data from the given
- "/ inStream to the pipe (which is connected to the commands input)
- inputShufflerProcess :=
- [
- [
- [anInStream atEnd] whileFalse:[
- self shuffleFrom:anInStream to:shuffledInStream lineWise:lineWise.
- shuffledInStream flush
- ]
- ] ensure:[
- shuffledInStream close
- ]
- ] newProcess
- name:'cmd input shuffler';
-"/ beSystemProcess;
- resume.
- ].
- ((externalOutStream := anOutStream) notNil
- and:[externalOutStream isExternalStream not]) ifTrue:[
- pOut := NonPositionableExternalStream makePipe.
- shuffledOutStream := (pOut at:1).
- anOutStream isBinary ifTrue:[
- shuffledOutStream binary
- ].
- outStreamToClose := externalOutStream := pOut at:2.
- outputShufflerProcess :=
- [
- WriteError handle:[:ex |
- "/ ignored
- ] do:[
- self shuffleAllFrom:shuffledOutStream to:anOutStream lineWise:lineWise lockWith:terminateLock.
- ].
- ] newProcess
- priority:(Processor userSchedulingPriority "+ 1");
- name:'cmd output shuffler';
-"/ beSystemProcess;
- resume.
- ].
- (externalErrStream := anErrStream) notNil ifTrue:[
- anErrStream == anOutStream ifTrue:[
- externalErrStream := externalOutStream
- ] ifFalse:[
- anErrStream isExternalStream ifFalse:[
- pErr := NonPositionableExternalStream makePipe.
- shuffledErrStream := (pErr at:1).
- anErrStream isBinary ifTrue:[
- shuffledErrStream binary
- ].
- errStreamToClose := externalErrStream := pErr at:2.
- errorShufflerProcess :=
- [
- self shuffleAllFrom:shuffledErrStream to:anErrStream lineWise:lineWise lockWith:terminateLock.
- ] newProcess
- priority:(Processor userSchedulingPriority + 1);
- name:'cmd err-output shuffler';
-"/ beSystemProcess;
- resume.
- ]
- ]
- ].
- ((externalAuxStream := anAuxStream) notNil
- and:[externalAuxStream isExternalStream not]) ifTrue:[
- pAux := NonPositionableExternalStream makePipe.
- auxStreamToClose := externalAuxStream := pAux at:1.
- shuffledAuxStream := pAux at:2.
- shuffledAuxStream blocking:false.
- anAuxStream isBinary ifTrue:[
- shuffledAuxStream binary
+ |osProcess|
+
+ osProcess := OSProcess new
+ command:aCommandStringOrArray;
+ inStream:anInStream;
+ outStream:anOutStream;
+ errorStream:anErrStream;
+ auxStream:anAuxStream;
+ environment:environmentDictionary;
+ directory:dirOrNil;
+ lineWise:lineWise;
+ showWindow:showWindowBooleanOrNil.
+
+ osProcess execute ifFalse:[
+ aBlock value:osProcess exitStatus.
+ ^ false.
].
-
- "/ start a reader process, shuffling data from the given
- "/ auxStream to the pipe (which is connected to the commands aux)
- auxShufflerProcess :=
- [
- [
- [anAuxStream atEnd] whileFalse:[
- self shuffleFrom:anAuxStream to:shuffledAuxStream lineWise:false.
- shuffledAuxStream flush
- ]
- ] ensure:[
- shuffledAuxStream close
- ]
- ] newProcess
- name:'cmd aux shuffler';
-"/ beSystemProcess;
- resume.
- ].
-
- stopShufflers := [:shuffleRest |
- inputShufflerProcess notNil ifTrue:[
- terminateLock critical:[inputShufflerProcess terminate].
- inputShufflerProcess waitUntilTerminated
- ].
- auxShufflerProcess notNil ifTrue:[
- terminateLock critical:[auxShufflerProcess terminate].
- auxShufflerProcess waitUntilTerminated
- ].
- outputShufflerProcess notNil ifTrue:[
- terminateLock critical:[outputShufflerProcess terminate].
- outputShufflerProcess waitUntilTerminated.
- shuffleRest ifTrue:[ self shuffleRestFrom:shuffledOutStream to:anOutStream lineWise:lineWise ].
- shuffledOutStream close.
- ].
- errorShufflerProcess notNil ifTrue:[
- terminateLock critical:[errorShufflerProcess terminate].
- errorShufflerProcess waitUntilTerminated.
- shuffleRest ifTrue:[ self shuffleRestFrom:shuffledErrStream to:anErrStream lineWise:lineWise ].
- shuffledErrStream close.
- ].
- ].
-
- closeStreams := [
- inStreamToClose notNil ifTrue:[
- inStreamToClose close
- ].
- errStreamToClose notNil ifTrue:[
- errStreamToClose close
- ].
- outStreamToClose notNil ifTrue:[
- outStreamToClose close
- ].
- auxStreamToClose notNil ifTrue:[
- auxStreamToClose close
- ].
- nullStream notNil ifTrue:[
- nullStream close
- ].
- ].
-
-
- sema := Semaphore new name:'OS command wait'.
- [
- externalInStream isNil ifTrue:[
- externalInStream := nullStream := Filename nullDevice readWriteStream.
- ].
- externalOutStream isNil ifTrue:[
- nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
- externalOutStream := nullStream.
- ].
- externalErrStream isNil ifTrue:[
- externalErrStream := externalOutStream
- ].
-
- pid := Processor
- monitor:[
- self
- startProcess:aCommandStringOrArray
- inputFrom:externalInStream
- outputTo:externalOutStream
- errorTo:externalErrStream
- auxFrom:externalAuxStream
- environment:environmentDictionary
- inDirectory:dirOrNil
- newPgrp:newPgrp
- showWindow:showWindowBooleanOrNil
- ]
- action:[:status |
- status stillAlive ifFalse:[
- exitStatus := status.
- sema signal.
- self closePid:pid
- ]
- ].
-
- pid isNil ifTrue:[
- exitStatus := self osProcessStatusClass processCreationFailure
- ] ifFalse:[
- sema wait.
- ].
- ] ifCurtailed:[
- closeStreams value.
- pid notNil ifTrue:[
- "/ terminate the os-command (and all of its forked commands)
- self terminateProcessGroup:pid.
- self terminateProcess:pid.
- self closePid:pid.
- ].
- stopShufflers value:false.
- ].
-
- closeStreams value.
- stopShufflers value:true.
- (exitStatus isNil or:[exitStatus success]) ifFalse:[
- ^ aBlock value:exitStatus
- ].
- ^ true
-
- "
- |outStream errStream|
-
- outStream := '' writeStream.
-
- OperatingSystem executeCommand:'ls -l'
- inputFrom:'abc' readStream
- outputTo:outStream
- errorTo:nil
- inDirectory:nil
- lineWise:true
- onError:[:exitStatus | ^ false].
- outStream contents
- "
-
- "
- |outStream errStream|
-
- outStream := #[] writeStream.
-
- OperatingSystem executeCommand:'cat'
- inputFrom:(ByteArray new:5000000) readStream
- outputTo:outStream
- errorTo:nil
- inDirectory:nil
- lineWise:false
- onError:[:exitStatus | ^ false].
- outStream size
- "
-
- "
- |outStream errStream|
-
- outStream := '' writeStream.
-
- OperatingSystem executeCommand:'gpg -s --batch --no-tty --passphrase-fd 0 /tmp/passwd'
- inputFrom:'bla' readStream
- outputTo:outStream
- errorTo:nil
- inDirectory:nil
- lineWise:true
- onError:[:exitStatus | false].
- outStream contents
- "
-
- "Modified: / 11-02-2007 / 20:54:39 / cg"
+ ^ true.
!
executeCommand:aCommandStringOrArray inputFrom:anInStream outputTo:anOutStream
@@ -2780,12 +2499,11 @@
"return true, if the OS can execute aCommand.
For now, this only works with UNIX."
- |fn fullPath|
-
- fullPath := (self pathOfCommand:aCommandString).
+ |fullPath|
+
+ fullPath := self pathOfCommand:aCommandString.
fullPath isNil ifTrue:[^ false].
- fn := fullPath asFilename.
- ^ fn exists and:[fn isExecutableProgram].
+ ^ fullPath asFilename isExecutableProgram.
"
OperatingSystem canExecuteCommand:'fooBar'
@@ -2847,12 +2565,12 @@
path := self pathOfCommand:(self nameOfSTXExecutable).
path isNil ifTrue:[
- './stx' asFilename exists ifTrue:[
- path := './stx'
- ].
- ].
- path isNil ifTrue:[
- 'OperatingSystem [warning]: cannot figure out my executable''s path' infoPrintCR.
+ './stx' asFilename exists ifTrue:[
+ path := './stx'
+ ].
+ path isNil ifTrue:[
+ 'OperatingSystem [warning]: cannot figure out my executable''s path' infoPrintCR.
+ ].
].
^ path
@@ -2866,6 +2584,7 @@
!AbstractOperatingSystem class methodsFor:'executing OS commands-wrappers'!
exec:aCommandPath withArguments:argArray
+ <resource: #obsolete>
"execute the OS command specified by the argument, aCommandPath, with
arguments in argArray (no arguments, if nil).
If successful, this method does NOT return and smalltalk is gone.
@@ -2873,56 +2592,71 @@
Can be used on UNIX with fork or on other systems to chain to another program."
^ self
- exec:aCommandPath
- withArguments:argArray
- environment:nil
- fileDescriptors:#(0 1 2)
- fork:false
- newPgrp:false
- inDirectory:nil
+ exec:aCommandPath
+ withArguments:argArray
+ environment:nil
+ fileDescriptors:#(0 1 2)
+ fork:false
+ newPgrp:false
+ inDirectory:nil
+ showWindow:false
"/ never reached ...
"Modified: / 12.11.1998 / 14:44:26 / cg"
!
+exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork newPgrp:newGrp inDirectory:aDirectory
+ <resource: #obsolete>
+ "execute an OS command"
+
+ ^ self
+ exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork
+ newPgrp:newGrp inDirectory:aDirectory showWindow:false
+
+ "Created: / 12.11.1998 / 14:46:15 / cg"
+!
+
exec:aCommandPath withArguments:argArray fileDescriptors:fileDescriptors fork:doFork newPgrp:newPgrp inDirectory:aDirectory
+ <resource: #obsolete>
^ self
- exec:aCommandPath
- withArguments:argArray
- environment:nil
- fileDescriptors:fileDescriptors
- fork:doFork
- newPgrp:newPgrp
- inDirectory:aDirectory
+ exec:aCommandPath
+ withArguments:argArray
+ environment:nil
+ fileDescriptors:fileDescriptors
+ fork:doFork
+ newPgrp:newPgrp
+ inDirectory:aDirectory
+ showWindow:false
!
exec:aCommandPath withArguments:argArray fork:doFork
+ <resource: #obsolete>
"execute an OS command without I/O redirection.
The command reads its input and writes its output
from/to whatever terminal device ST/X was started
(typically, the terminal window)"
^ self
- exec:aCommandPath
- withArguments:argArray
- environment:nil
- fileDescriptors:#(0 1 2)
- fork:doFork
- newPgrp:false
- inDirectory:nil
-
+ exec:aCommandPath
+ withArguments:argArray
+ environment:nil
+ fileDescriptors:#(0 1 2)
+ fork:doFork
+ newPgrp:false
+ inDirectory:nil
+ showWindow:false
"
|id|
id := OperatingSystem fork.
id == 0 ifTrue:[
- 'I am the child'.
- OperatingSystem
- exec:'/bin/ls'
- withArguments:#('ls' '/tmp')
- fork:false.
- 'not reached'.
+ 'I am the child'.
+ OperatingSystem
+ exec:'/bin/ls'
+ withArguments:#('ls' '/tmp')
+ fork:false.
+ 'not reached'.
]
"
@@ -2931,12 +2665,12 @@
id := OperatingSystem fork.
id == 0 ifTrue:[
- 'I am the child'.
- OperatingSystem
- exec:'/bin/sh'
- withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
- fork:false.
- 'not reached'.
+ 'I am the child'.
+ OperatingSystem
+ exec:'/bin/sh'
+ withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
+ fork:false.
+ 'not reached'.
].
id printNL.
(Delay forSeconds:3.5) wait.
@@ -2950,31 +2684,32 @@
!
exec:aCommandPath withArguments:argArray fork:doFork inDirectory:aDirectory
+ <resource: #obsolete>
"execute an OS command without I/O redirection.
The command reads its input and writes its output
from/to whatever terminal device ST/X was started
(typically, the terminal window)"
^ self
- exec:aCommandPath
- withArguments:argArray
- environment:nil
- fileDescriptors:#(0 1 2)
- fork:doFork
- newPgrp:false
- inDirectory:aDirectory
-
+ exec:aCommandPath
+ withArguments:argArray
+ environment:nil
+ fileDescriptors:#(0 1 2)
+ fork:doFork
+ newPgrp:false
+ inDirectory:aDirectory
+ showWindow:false
"
|id|
id := OperatingSystem fork.
id == 0 ifTrue:[
- 'I am the child'.
- OperatingSystem
- exec:'/bin/ls'
- withArguments:#('ls' '/tmp')
- fork:false.
- 'not reached'.
+ 'I am the child'.
+ OperatingSystem
+ exec:'/bin/ls'
+ withArguments:#('ls' '/tmp')
+ fork:false.
+ 'not reached'.
]
"
@@ -2983,12 +2718,12 @@
id := OperatingSystem fork.
id == 0 ifTrue:[
- 'I am the child'.
- OperatingSystem
- exec:'/bin/sh'
- withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
- fork:false.
- 'not reached'.
+ 'I am the child'.
+ OperatingSystem
+ exec:'/bin/sh'
+ withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
+ fork:false.
+ 'not reached'.
].
id printNL.
(Delay forSeconds:3.5) wait.
@@ -3003,6 +2738,7 @@
!
exec:aCommandPath withArguments:argArray showWindow:showWindowBooleanOrNil
+ <resource: #obsolete>
"execute the OS command specified by the argument, aCommandPath, with
arguments in argArray (no arguments, if nil).
If successful, this method does NOT return and smalltalk is gone.
@@ -3022,6 +2758,116 @@
"/ never reached ...
"Modified: / 12.11.1998 / 14:44:26 / cg"
+!
+
+startProcess:aCommandString
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:nil outputTo:nil
+ errorTo:nil auxFrom:nil environment:nil
+ inDirectory:nil newPgrp:true showWindow:nil
+
+ "
+ |pid|
+
+ pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
+ (Delay forSeconds:3) wait.
+ OperatingSystem killProcess:pid.
+ "
+ "
+ |pid|
+
+ pid := OperatingSystem startProcess:'dir/l'.
+ (Delay forSeconds:1) wait.
+ OperatingSystem killProcess:pid.
+ "
+ "
+ |pid|
+
+ pid := OperatingSystem
+ startProcess:'dir/l'
+ inputFrom:nil
+ outputTo:Stdout
+ errorTo:nil
+ inDirectory:nil.
+ (Delay forSeconds:2) wait.
+ OperatingSystem killProcess:pid.
+ "
+
+ "Modified: / 21.3.1997 / 10:04:35 / dq"
+ "Modified: / 10.11.1998 / 21:03:50 / cg"
+!
+
+startProcess:aCommandString inDirectory:aDirectory
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:nil outputTo:nil
+ errorTo:nil auxFrom:nil environment:nil
+ inDirectory:aDirectory newPgrp:true showWindow:nil
+ "
+ |pid|
+
+ pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
+ (Delay forSeconds:3) wait.
+ OperatingSystem killProcess:pid.
+ "
+
+ "Modified: / 21.3.1997 / 10:04:35 / dq"
+ "Modified: / 28.1.1998 / 14:13:33 / md"
+ "Modified: / 10.11.1998 / 20:59:33 / cg"
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:nil environment:nil
+ inDirectory:nil newPgrp:true showWindow:nil
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment inDirectory:dir
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment
+ inDirectory:dir newPgrp:true showWindow:nil
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment
+ inDirectory:dir showWindow:showWindowBooleanOrNil
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment
+ inDirectory:dir newPgrp:true showWindow:showWindowBooleanOrNil
+
+ "Modified: / 08-11-2016 / 21:24:27 / cg"
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:anAuxiliaryStream inDirectory:dir
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:nil environment:nil
+ inDirectory:dir newPgrp:true showWindow:nil
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream inDirectory:dir
+ <resource: #obsolete>
+
+ ^ self
+ startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+ errorTo:anExternalErrStream auxFrom:nil environment:nil
+ inDirectory:dir newPgrp:true showWindow:nil
! !
!AbstractOperatingSystem class methodsFor:'file access'!
--- a/Autoload.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Autoload.st Thu Jan 05 21:02:10 2017 +0000
@@ -172,12 +172,12 @@
nameSymbol := aClassName asSymbol.
(Smalltalk at:nameSymbol) isNil ifTrue:[
- cls := Autoload
- subclass:nameSymbol
- instanceVariableNames:''
- classVariableNames:''
- poolDictionaries:''
- category:aCategory.
+ cls := self
+ subclass:nameSymbol
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:aCategory.
].
^ cls
--- a/Collection.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Collection.st Thu Jan 05 21:02:10 2017 +0000
@@ -343,6 +343,7 @@
^ self
! !
+
!Collection methodsFor:'Compatibility-ANSI'!
identityIncludes:anObject
@@ -1650,6 +1651,12 @@
!
+asCollectionDo:aBlock
+ "enumerate myself"
+
+ self do:aBlock
+!
+
asDictionary
"return a Dictionary with the receiver collection's elements,
using the original keys of the receiver as dictionary key.
--- a/Date.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Date.st Thu Jan 05 21:02:10 2017 +0000
@@ -375,17 +375,17 @@
|weekDayOfJan4 dayInYear year|
year := yearArg.
- weekDayOfJan4 := (Date year:year month:1 day:4) dayInWeek.
+ weekDayOfJan4 := (self year:year month:1 day:4) dayInWeek.
dayInYear := (week * 7) + dayInWeek - (weekDayOfJan4 + 3).
dayInYear < 1 ifTrue:[
- dayInYear := dayInYear + (Date daysInYear:year-1).
+ dayInYear := dayInYear + (self daysInYear:year-1).
year := year - 1.
].
- dayInYear > (Date daysInYear:year) ifTrue:[
- dayInYear := dayInYear - (Date daysInYear:year).
+ dayInYear > (self daysInYear:year) ifTrue:[
+ dayInYear := dayInYear - (self daysInYear:year).
year := year + 1.
].
- ^ Date newDay:dayInYear year:year.
+ ^ self newDay:dayInYear year:year.
"
Date newDayInWeek:6 week:39 year:2008
@@ -532,14 +532,14 @@
].
dayOfYear notNil ifTrue:[
- monthAndDay := Date monthAndDayFromDayInYear:dayOfYear forYear:year.
+ monthAndDay := self monthAndDayFromDayInYear:dayOfYear forYear:year.
month := (monthAndDay at:1).
day := (monthAndDay at:2).
].
day isNil ifTrue:[ day := 1 ].
month isNil ifTrue:[ month := 1 ].
- year isNil ifTrue:[ year := Date today year ].
+ year isNil ifTrue:[ year := self today year ].
(year between:0 and:99) ifTrue:[
year := UserPreferences current twoDigitDateHandler value:year.
@@ -736,7 +736,7 @@
"return a date, representing tomorrow.
See also: Time now / Timestamp now."
- ^ Date today addDays:1
+ ^ self today addDays:1
"
Date tomorrow
@@ -812,7 +812,7 @@
"return a date, representing yesterday.
See also: Time now / Timestamp now."
- ^ Date today subtractDays:1
+ ^ self today subtractDays:1
"
Date yesterday
@@ -925,6 +925,7 @@
"
! !
+
!Date class methodsFor:'change & update'!
update:something with:aParameter from:changedObject
@@ -1132,7 +1133,7 @@
|day dayInWeekOf1stJan firstThursday firstDayInWeek|
"/ find the first thursday ...
- day := Date newDay:1 year:aYear.
+ day := self newDay:1 year:aYear.
dayInWeekOf1stJan := day dayInWeek.
dayInWeekOf1stJan > 4 ifTrue:[
firstThursday := day addDays:(4 - dayInWeekOf1stJan + 7).
@@ -1570,7 +1571,7 @@
numDays < 0 ifTrue:[
"/ not in a week here ...
"/ can be either 52 or 53, depending on the previous year.
- ^ self weekInYearOf:(Date year:date year - 1 month:12 day:31)
+ ^ self weekInYearOf:(self year:date year - 1 month:12 day:31)
].
"/ compute the week
@@ -1896,6 +1897,7 @@
"Modified: 8.10.1996 / 19:25:39 / cg"
! !
+
!Date class methodsFor:'private'!
dayAbbrevsForLanguage:languageOrNilForDefault
@@ -2022,13 +2024,13 @@
].
(format sameAs:'monthName') ifTrue:[
monthName := string.
- month := (Date monthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
+ month := (self monthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
"/ month == 0 ifTrue:[self error:'invalid month name'].
^ #month -> month
].
(format sameAs:'shortMonthName') ifTrue:[
monthName := string.
- month := (Date abbreviatedMonthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
+ month := (self abbreviatedMonthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
"/ month == 0 ifTrue:[self error:'invalid month name'].
^ #month -> month
].
@@ -2112,6 +2114,7 @@
"
! !
+
!Date methodsFor:'Compatibility-ANSI'!
dayOfWeek
@@ -2756,7 +2759,7 @@
daysInMonth
"return the number of days in the month of the receiver"
- ^ Date daysInMonth:(self month) forYear:(self year)
+ ^ self class daysInMonth:(self month) forYear:(self year)
"
Date today daysInMonth
@@ -2766,7 +2769,7 @@
daysInYear
"return the number of days in the year of the receiver"
- ^ Date daysInYear:(self year)
+ ^ self class daysInYear:(self year)
"
Date today daysInYear
@@ -2788,7 +2791,7 @@
Today is excluded from the count (i.e. in a non-leap-year,
the first january will return 364)"
- ^ (Date daysInYear:(self year)) - self dayOfYear
+ ^ (self class daysInYear:(self year)) - self dayOfYear
"
Date today daysLeftInYear
@@ -2798,7 +2801,7 @@
isLeapYear
"return true, if the receiver's year is a leap year"
- ^ Date leapYear:(self year)
+ ^ self class leapYear:self year
"
Date today isLeapYear
@@ -3022,7 +3025,7 @@
- (self month * 100) "in the line above the new month is already completely calculated. So subtract the current month"
- self day "in the line below the new day is already completely calculated. So subtract the current day"
+ (self day min: self daysInMonth). "the new day considering the maximum number of days in the new month."
- ^ Date
+ ^ self class
year: newEncoding // 10000
month: (newEncoding // 100 \\ 100)
day: newEncoding \\ 100.
@@ -3120,7 +3123,7 @@
month := (12 - (monthNegated \\ 12)).
].
- ^ Date year:year month:month day:1.
+ ^ self class year:year month:month day:1.
"
(Date newDay:3 month:6 year:2009) firstDayInMonth
@@ -3171,7 +3174,7 @@
"/ the argument must understand year, month and day to be
"/ comparable, whatever it is
- ^ dateEncoding < (Date encodeYear:aDate year month:aDate month day:aDate day)
+ ^ dateEncoding < (self class encodeYear:aDate year month:aDate month day:aDate day)
"
Date today < (Date day:24 month:12 year:2000)
@@ -3212,7 +3215,7 @@
"/ the argument must understand year, month and day,
"/ to be comparable, whatever it is
- ^ dateEncoding > (Date encodeYear:aDate year month:aDate month day:aDate day)
+ ^ dateEncoding > (self class encodeYear:aDate year month:aDate month day:aDate day)
"
Date today > (Date newDay:24 month:12 year:2099)
@@ -3271,6 +3274,7 @@
! !
+
!Date methodsFor:'obsolete'!
asAbsoluteTime
@@ -3341,6 +3345,7 @@
^ self addDays:days
! !
+
!Date methodsFor:'printing & storing'!
addPrintBindingsTo:aDictionary
@@ -3442,7 +3447,7 @@
aDictionary at:#week put:wsPadded0.
aDictionary at:#Week put:ws.
- year ~~ Date today year ifTrue:[
+ year ~~ self class today year ifTrue:[
aDictionary at:#yearOrTime put:(' ' , year printString).
].
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EventSemaphore.st Thu Jan 05 21:02:10 2017 +0000
@@ -0,0 +1,170 @@
+"
+ COPYRIGHT (c) 2016 by eXept Sofware AG
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'stx:libbasic' }"
+
+"{ NameSpace: Smalltalk }"
+
+Semaphore subclass:#EventSemaphore
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Kernel-Processes'
+!
+
+!EventSemaphore class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2016 by eXept Sofware AG
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+ Processes wait for an EventSemaphores until it is signaled.
+ The EventSemaphore is not consumed and remains signaled until manually reset.
+
+ [author:]
+ Stefan Vogel
+
+ [see also:]
+ Semaphore
+"
+!
+
+example
+"
+ Create an event and signal it.
+ After being signaled waiter on the event return immediately.
+
+ [exBegin]
+ |event|
+
+ event := EventSemaphore new.
+ [ event wait. Transcript showCR:'Process 1 continued' ] forkAt:9.
+ [ event wait. Transcript showCR:'Process 2 continued' ] forkAt:9.
+ event signal.
+ event wait.
+ event wait.
+ [exEnd]
+"
+! !
+
+!EventSemaphore class methodsFor:'signaling'!
+
+new:n
+ "count must be 0 or 1"
+
+ (n == 0 or:[n == 1]) ifTrue:[
+ self new:n.
+ ].
+ ^ self error:'invalid count'.
+! !
+
+!EventSemaphore methodsFor:'blocked'!
+
+signalForAll
+ "blocked, since it would only set the event if there was anyone waiting"
+
+ ^ self shouldNotImplement.
+!
+
+signalIf
+ "blocked, since it would only set the event if there was anyone waiting"
+
+ ^ self shouldNotImplement.
+!
+
+waitWithTimeoutMs:milliSeconds state:waitStateSymbol
+ "blocked, since we had to re-implement it here"
+
+ ^ self shouldNotImplement
+! !
+
+!EventSemaphore methodsFor:'misc'!
+
+reset
+ "reset the event to the non-signaled state"
+
+ count := 0
+! !
+
+!EventSemaphore methodsFor:'semaphoreSet interface'!
+
+checkAndAddWaitingProcess:process
+ "interface for SemaphoreSet.
+ If the semaphore is available, return true.
+ Otherwise register our process to be wakened up once the semaphore is available
+ and return false.
+ ATTENTION: this must be invoked with OperatingSystem-interrupts-blocked.
+ "
+
+ count > 0 ifTrue:[
+ ^ true
+ ].
+ (waitingProcesses notNil and:[(waitingProcesses includesIdentical:process)]) ifFalse:[
+ self addWaitingProcess:process.
+ ].
+ ^ false
+
+ "Modified: / 14-12-1995 / 10:32:17 / stefan"
+ "Modified: / 11-08-2011 / 14:36:20 / cg"
+! !
+
+!EventSemaphore methodsFor:'signaling'!
+
+signal
+ "redefined to limit count to 1"
+
+ self signalOnce.
+! !
+
+!EventSemaphore methodsFor:'waiting'!
+
+wait
+ "once signaled, do not decrement the count"
+
+ self waitUncounted
+!
+
+waitWithTimeoutMs:milliSeconds
+ "wait for the semaphore, but abort the wait after some time.
+ return the receiver if the semaphore triggered normal, nil if we return
+ due to a timeout.
+ With zero timeout, this can be used to poll a semaphore (returning
+ the receiver if the semaphore is available, nil if not).
+ However, polling is not the intended use of semaphores, though.
+ If milliSeconds is nil, wait without timeout.
+
+ Redefined: once signaled, do not decrement the count"
+
+ ^ self waitUncountedWithTimeoutMs:milliSeconds.
+! !
+
+!EventSemaphore class methodsFor:'documentation'!
+
+version
+ ^ '$Header$'
+!
+
+version_CVS
+ ^ '$Header$'
+! !
+
--- a/Infinity.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Infinity.st Thu Jan 05 21:02:10 2017 +0000
@@ -316,6 +316,13 @@
^ self negated
!
+equalFromSomeNumber:aNumber
+ "Sent from aNumber = self, if aNumber does not know how to handle this.
+ Return true if aNumber = self."
+
+ ^ aNumber isInfinite and:[self sign == aNumber sign]
+!
+
lessFromSomeNumber:aNumber
"Sent from aNumber < self, if aNumber does not know how to handle this.
Return true if aNumber < self."
--- a/Make.proto Wed Dec 28 22:58:47 2016 +0000
+++ b/Make.proto Thu Jan 05 21:02:10 2017 +0000
@@ -211,6 +211,7 @@
$(OUTDIR)CompiledCode.$(O) CompiledCode.$(C) CompiledCode.$(H): CompiledCode.st $(INCLUDE_TOP)/stx/libbasic/ExecutableFunction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)ControlInterrupt.$(O) ControlInterrupt.$(C) ControlInterrupt.$(H): ControlInterrupt.st $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)Date.$(O) Date.$(C) Date.$(H): Date.st $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)EventSemaphore.$(O) EventSemaphore.$(C) EventSemaphore.$(H): EventSemaphore.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/Semaphore.$(H) $(STCHDR)
$(OUTDIR)Exception.$(O) Exception.$(C) Exception.$(H): Exception.st $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)ExternalFunction.$(O) ExternalFunction.$(C) ExternalFunction.$(H): ExternalFunction.st $(INCLUDE_TOP)/stx/libbasic/ExecutableFunction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)False.$(O) False.$(C) False.$(H): False.st $(INCLUDE_TOP)/stx/libbasic/Boolean.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -508,10 +509,10 @@
$(OUTDIR)UnderflowError.$(O) UnderflowError.$(C) UnderflowError.$(H): UnderflowError.st $(INCLUDE_TOP)/stx/libbasic/ArithmeticError.$(H) $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/ExecutionError.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProceedableError.$(H) $(INCLUDE_TOP)/stx/libbasic/RangeError.$(H) $(STCHDR)
$(OUTDIR)ZeroDivide.$(O) ZeroDivide.$(C) ZeroDivide.$(H): ZeroDivide.st $(INCLUDE_TOP)/stx/libbasic/ArithmeticError.$(H) $(INCLUDE_TOP)/stx/libbasic/DomainError.$(H) $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/ExecutionError.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProceedableError.$(H) $(STCHDR)
$(OUTDIR)BadRomanNumberFormatError.$(O) BadRomanNumberFormatError.$(C) BadRomanNumberFormatError.$(H): BadRomanNumberFormatError.st $(INCLUDE_TOP)/stx/libbasic/ConversionError.$(H) $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/NumberConversionError.$(H) $(INCLUDE_TOP)/stx/libbasic/NumberFormatError.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProceedableError.$(H) $(INCLUDE_TOP)/stx/libbasic/RomanNumberFormatError.$(H) $(STCHDR)
-$(OUTDIR)UnixFileDescriptorHandle.$(O) UnixFileDescriptorHandle.$(C) UnixFileDescriptorHandle.$(H): UnixFileDescriptorHandle.st $(STCHDR)
-$(OUTDIR)UnixFileHandle.$(O) UnixFileHandle.$(C) UnixFileHandle.$(H): UnixFileHandle.st $(STCHDR)
-$(OUTDIR)UnixOperatingSystem.$(O) UnixOperatingSystem.$(C) UnixOperatingSystem.$(H): UnixOperatingSystem.st $(STCHDR)
-$(OUTDIR)OSXOperatingSystem.$(O) OSXOperatingSystem.$(C) OSXOperatingSystem.$(H): OSXOperatingSystem.st $(STCHDR)
+$(OUTDIR)UnixFileDescriptorHandle.$(O) UnixFileDescriptorHandle.$(C) UnixFileDescriptorHandle.$(H): UnixFileDescriptorHandle.st $(INCLUDE_TOP)/stx/libbasic/ExternalAddress.$(H) $(INCLUDE_TOP)/stx/libbasic/OSFileHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/OSHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)UnixFileHandle.$(O) UnixFileHandle.$(C) UnixFileHandle.$(H): UnixFileHandle.st $(INCLUDE_TOP)/stx/libbasic/ExternalAddress.$(H) $(INCLUDE_TOP)/stx/libbasic/OSFileHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/OSHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)UnixOperatingSystem.$(O) UnixOperatingSystem.$(C) UnixOperatingSystem.$(H): UnixOperatingSystem.st $(INCLUDE_TOP)/stx/libbasic/AbstractOperatingSystem.$(H) $(INCLUDE_TOP)/stx/libbasic/ExternalAddress.$(H) $(INCLUDE_TOP)/stx/libbasic/OSFileHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/OSHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
+$(OUTDIR)OSXOperatingSystem.$(O) OSXOperatingSystem.$(C) OSXOperatingSystem.$(H): OSXOperatingSystem.st $(INCLUDE_TOP)/stx/libbasic/AbstractOperatingSystem.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/UnixOperatingSystem.$(H) $(STCHDR)
# ENDMAKEDEPEND --- do not remove this line
--- a/Make.spec Wed Dec 28 22:58:47 2016 +0000
+++ b/Make.spec Thu Jan 05 21:02:10 2017 +0000
@@ -121,6 +121,7 @@
CompiledCode \
ControlInterrupt \
Date \
+ EventSemaphore \
Exception \
ExternalFunction \
False \
@@ -511,6 +512,7 @@
$(OUTDIR_SLASH)CompiledCode.$(O) \
$(OUTDIR_SLASH)ControlInterrupt.$(O) \
$(OUTDIR_SLASH)Date.$(O) \
+ $(OUTDIR_SLASH)EventSemaphore.$(O) \
$(OUTDIR_SLASH)Exception.$(O) \
$(OUTDIR_SLASH)ExternalFunction.$(O) \
$(OUTDIR_SLASH)False.$(O) \
--- a/NonPositionableExternalStream.st Wed Dec 28 22:58:47 2016 +0000
+++ b/NonPositionableExternalStream.st Thu Jan 05 21:02:10 2017 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -116,6 +118,62 @@
^ StdOutStream
!
+makeBidirectionalPipe
+ "return an array with two streams - the first one for reading,
+ the second for writing.
+ This is the higher level equivalent of OperatingSystem>>makeBidirectionalPipe
+ (which returns an array of file-descriptors)."
+
+ |pipe rs ws|
+
+ pipe := OperatingSystem makeBidirectionalPipe.
+ pipe isNil ifTrue:[
+ "/ ok, maybe someone has forgotten to close a stream; enforce finalization and try again
+ 'makePipe: enforcing finalization to close any open streams' infoPrintCR.
+ ObjectMemory garbageCollect; finalize.
+ pipe := OperatingSystem makeBidirectionalPipe.
+ ].
+
+ pipe isNil ifTrue:[
+ |errorNumber errorHolder|
+
+ errorNumber := OperatingSystem lastErrorNumber.
+ errorHolder := errorNumber.
+ OpenError newException
+ errorCode:errorNumber;
+ osErrorHolder:errorHolder;
+ raise.
+ ].
+
+ rs := self forFileDescriptor:(pipe at:1) mode:#readWrite buffered:false handleType:#pipeFilePointer.
+ ws := self forFileDescriptor:(pipe at:2) mode:#readWrite buffered:false handleType:#pipeFilePointer.
+ ^ Array with:rs with:ws
+
+ "
+ |pipe rs ws|
+
+ pipe := NonPositionableExternalStream makeBidirectionalPipe.
+ rs := pipe at:1.
+ ws := pipe at:2.
+
+ 'read ...'.
+ [
+ 1 to:10 do:[:i |
+ Transcript showCR:rs nextLine
+ ].
+ rs close.
+ ] forkAt:7.
+
+ 'write ...'.
+ [
+ 1 to:10 do:[:i |
+ ws nextPutAll:'hello world '; nextPutAll:i printString; cr
+ ].
+ ws close.
+ ] fork.
+ "
+!
+
makePTYPair
"return an array with two streams - the first one is the master,
the second the slave of a ptym/ptys pair.
@@ -156,18 +214,26 @@
pipe := OperatingSystem makePipe.
pipe isNil ifTrue:[
- "/ ok, maybe someone has forgotten to close a stream; enforce finalization and try again
- 'makePipe: enforcing finalization to close any open streams' infoPrintCR.
- ObjectMemory garbageCollect; finalize.
- pipe := OperatingSystem makePipe.
+ "/ ok, maybe someone has forgotten to close a stream; enforce finalization and try again
+ 'makePipe: enforcing finalization to close any open streams' infoPrintCR.
+ ObjectMemory garbageCollect; finalize.
+ pipe := OperatingSystem makePipe.
].
- pipe notNil ifTrue:[
- rs := self forFileDescriptor:(pipe at:1) mode:#readonly buffered:false handleType:#pipeFilePointer.
- ws := self forFileDescriptor:(pipe at:2) mode:#writeonly buffered:false handleType:#pipeFilePointer.
- ^ Array with:rs with:ws
+ pipe isNil ifTrue:[
+ |errorNumber errorHolder|
+
+ errorNumber := OperatingSystem lastErrorNumber.
+ errorHolder := errorNumber.
+ OpenError newException
+ errorCode:errorNumber;
+ osErrorHolder:errorHolder;
+ raise.
].
- ^ nil
+
+ rs := self forFileDescriptor:(pipe at:1) mode:#readonly buffered:false handleType:#pipeFilePointer.
+ ws := self forFileDescriptor:(pipe at:2) mode:#writeonly buffered:false handleType:#pipeFilePointer.
+ ^ Array with:rs with:ws
"
|pipe rs ws|
@@ -178,18 +244,18 @@
'read ...'.
[
- 1 to:10 do:[:i |
- Transcript showCR:rs nextLine
- ].
- rs close.
+ 1 to:10 do:[:i |
+ Transcript showCR:rs nextLine
+ ].
+ rs close.
] forkAt:7.
'write ...'.
[
- 1 to:10 do:[:i |
- ws nextPutAll:'hello world '; nextPutAll:i printString; cr
- ].
- ws close.
+ 1 to:10 do:[:i |
+ ws nextPutAll:'hello world '; nextPutAll:i printString; cr
+ ].
+ ws close.
] fork.
"
--- a/OSProcess.st Wed Dec 28 22:58:47 2016 +0000
+++ b/OSProcess.st Thu Jan 05 21:02:10 2017 +0000
@@ -7,7 +7,7 @@
Object subclass:#OSProcess
instanceVariableNames:'pid command environment directory inStream outStream errorStream
auxStream showWindow lineWise newPgrp exitStatus finishSema
- shufflerProcesses streamsToClose'
+ shufflerProcesses streamsToClose terminateActionBlock'
classVariableNames:''
poolDictionaries:''
category:'System-Support'
@@ -99,15 +99,14 @@
!OSProcess methodsFor:'accessing'!
-accessor
- ^ self
-!
-
auxStream
^ auxStream
!
auxStream:something
+ "set an auxilliary input stream that will be available to the command as
+ file descriptor 3"
+
auxStream := something.
!
@@ -119,12 +118,14 @@
"Created: / 10.11.1998 / 21:27:07 / cg"
!
-command:something
- "set the value of the instance variable 'command' (automatically generated)"
+command:aStringOrArray
+ "set the command to be executed.
+ If aStringOrArray is a String, the commandString is passed to a shell for execution
+ - see the description of 'sh -c' in your UNIX manual ('cmd.exe' in your Windows manual).
+ If aCommandString is an Array, the first element is the command to be executed,
+ and the other elements are the arguments to the command. No shell is invoked in this case."
- command := something.
-
- "Created: / 10.11.1998 / 21:27:07 / cg"
+ command := aStringOrArray.
!
directory
@@ -135,12 +136,10 @@
"Created: / 10.11.1998 / 21:21:52 / cg"
!
-directory:something
- "set the value of the instance variable 'directory' (automatically generated)"
+directory:aString
+ "set the directory that will be set as the current directory of the command to be executed"
- directory := something.
-
- "Created: / 10.11.1998 / 21:21:52 / cg"
+ directory := aString.
!
environment
@@ -151,12 +150,10 @@
"Created: / 10.11.1998 / 21:26:34 / cg"
!
-environment:something
- "set the value of the instance variable 'environment' (automatically generated)"
+environment:aDictionary
+ "set the environment variables of the command to be executed"
- environment := something.
-
- "Created: / 10.11.1998 / 21:27:07 / cg"
+ environment := aDictionary.
!
errorStream
@@ -167,20 +164,16 @@
"Created: / 10.11.1998 / 21:26:34 / cg"
!
-errorStream:something
- "set the value of the instance variable 'errorStream' (automatically generated)"
+errorStream:aStream
+ "set the stream where the stderr output of the command is directed to"
- errorStream := something.
-
- "Created: / 10.11.1998 / 21:26:34 / cg"
+ errorStream := aStream.
!
exitStatus
- "return the value of the instance variable 'exitStatus' (automatically generated)"
+ "answer the exit status of the command or nil, if the command has not yet been finished"
^ exitStatus
-
- "Created: / 10.11.1998 / 21:24:55 / cg"
!
exitStatus:something
@@ -206,28 +199,33 @@
"Created: / 10.11.1998 / 21:26:34 / cg"
!
-inStream:something
- "set the value of the instance variable 'inStream' (automatically generated)"
+inStream:aStream
+ "set the stream where the stdin input of the command is read from"
- inStream := something.
-
- "Created: / 10.11.1998 / 21:26:34 / cg"
+ inStream := aStream.
!
lineWise
^ lineWise
!
-lineWise:something
- lineWise := something.
+lineWise:aBoolean
+ "When setting to true, read linewise from the command's output and error.
+ This is a bit slower than lineWise = false.
+
+ You may use it also when streaming to e.g. Transcript"
+
+ lineWise := aBoolean.
!
newPgrp
^ newPgrp
!
-newPgrp:something
- newPgrp := something.
+newPgrp:aBoolean
+ "if aBoolean is true, a new process group will be created for the command and its subprocesses"
+
+ newPgrp := aBoolean.
!
outStream
@@ -238,15 +236,15 @@
"Created: / 10.11.1998 / 21:26:34 / cg"
!
-outStream:something
- "set the value of the instance variable 'outStream' (automatically generated)"
+outStream:aStream
+ "set the stream where the stdout output of the command is directed to"
- outStream := something.
-
- "Created: / 10.11.1998 / 21:26:34 / cg"
+ outStream := aStream.
!
pid
+ "answer the pid of the process the command is running in or nil, if the command has not yet been started."
+
^ pid
!
@@ -258,8 +256,30 @@
^ showWindow
!
-showWindow:something
- showWindow := something.
+showWindow:aBooleanOrNil
+ "This parameter is ignored on Unix systems.
+
+ You can control (have to - sigh) if a window should be shown for the command or not.
+ This is the OS's H_SHOWWINDOW argument.
+ If you pass nil as showWindow-argument, the OS's default is used for the particular
+ command, which is correct most of the time: i.e. a notepad will open its window, other (non-UI)
+ executables will not.
+ However, some command-line executables show a window, even if they should not.
+ (and also, there seems to be an inconsistency between windows7 and newer windows: in newer,
+ a shell command opens a cmd-window, whereas in windows7 it did not)
+ In this case, pass an explicit false argument to suppress it."
+
+ showWindow := aBooleanOrNil.
+!
+
+terminateActionBlock
+ ^ terminateActionBlock
+!
+
+terminateActionBlock:aBlock
+ "set the block that will be executed when the command has been finished or terminated."
+
+ terminateActionBlock := aBlock.
! !
!OSProcess methodsFor:'initialization'!
@@ -391,10 +411,14 @@
!OSProcess methodsFor:'queries'!
+finishedWithSuccess
+ ^ exitStatus notNil and:[exitStatus success].
+!
+
isAlive
"answer true, if the process is still alive"
- ^ pid notNil and:[exitStatus notNil]
+ ^ pid notNil and:[exitStatus isNil]
!
isDead
@@ -417,7 +441,8 @@
[
ok := self startProcess.
ok ifTrue:[
- ok := self waitUntilFinished.
+ self waitUntilFinished.
+ ok := self finishedWithSuccess.
].
] ifCurtailed:[
"/ we were interrupted -
@@ -436,10 +461,10 @@
Answer true if the command could be started, false if not.
Return immediately (do not wait until the command is finished)."
- |nullStream externalInStream externalAuxStream externalErrorStream externalOutStream|
+ |externalInStream externalAuxStream externalErrorStream externalOutStream|
- shufflerProcesses := OrderedCollection new.
- streamsToClose := OrderedCollection new:3.
+ shufflerProcesses := OrderedCollection new:4.
+ streamsToClose := OrderedCollection new:2.
externalInStream := self setupShufflerForInput:inStream.
externalAuxStream := self setupShufflerForInput:auxStream.
@@ -450,41 +475,21 @@
externalOutStream := self setupShufflerForOutput:outStream.
].
- "make sure, that the command gets a stdin, stdout and stderr"
- externalInStream isNil ifTrue:[
- externalInStream := nullStream := Filename nullDevice readWriteStream.
- streamsToClose add:nullStream.
- ].
- externalOutStream isNil ifTrue:[
- nullStream isNil ifTrue:[
- nullStream := Filename nullDevice writeStream.
- streamsToClose add:nullStream.
- ].
- externalOutStream := nullStream.
- ].
- externalErrorStream isNil ifTrue:[
- nullStream isNil ifTrue:[
- nullStream := Filename nullDevice writeStream.
- streamsToClose add:nullStream.
- ].
- externalErrorStream := nullStream.
- ].
-
"start the command"
- finishSema := Semaphore new.
+ finishSema := EventSemaphore new.
Processor
monitor:[
pid := OperatingSystem
- startProcess:command
- inputFrom:externalInStream
- outputTo:externalOutStream
- errorTo:externalErrorStream
- auxFrom:externalAuxStream
- environment:environment
- inDirectory:directory
- newPgrp:newPgrp
- showWindow:showWindow.
+ startProcess:command
+ inputFrom:externalInStream
+ outputTo:externalOutStream
+ errorTo:externalErrorStream
+ auxFrom:externalAuxStream
+ environment:environment
+ inDirectory:directory
+ newPgrp:newPgrp
+ showWindow:showWindow.
]
action:[:status |
status stillAlive ifFalse:[
@@ -497,6 +502,7 @@
They close the local side of the pipe when being terminated"
eachProcess terminate.
].
+ terminateActionBlock value.
finishSema signal.
].
].
@@ -512,6 +518,7 @@
].
shufflerProcesses := nil.
exitStatus := OperatingSystem osProcessStatusClass processCreationFailure.
+ finishSema signal.
^ false.
].
@@ -523,21 +530,27 @@
kill
"kill the process - the process does not get the chance to clean up"
- OperatingSystem killProcess:pid.
+ pid notNil ifTrue:[
+ OperatingSystem killProcess:pid.
+ ].
!
killGroup
"kill the processGroup - the processes do not get the chance to clean up"
- OperatingSystem
- killProcessGroup:pid;
- killProcess:pid.
+ pid notNil ifTrue:[
+ OperatingSystem
+ killProcessGroup:pid;
+ killProcess:pid.
+ ].
!
terminate
"terminate the process gracefully"
- OperatingSystem terminateProcess:pid.
+ pid notNil ifTrue:[
+ OperatingSystem terminateProcess:pid.
+ ].
!
terminateGroup
@@ -545,28 +558,35 @@
Under Windows, these is the same as terminateWithhAllChildren,
under unix, this terminates a subset of all children"
- OperatingSystem
- terminateProcessGroup:pid;
- terminateProcess:pid.
+ pid notNil ifTrue:[
+ OperatingSystem
+ terminateProcessGroup:pid;
+ terminateProcess:pid.
+ ].
! !
!OSProcess methodsFor:'waiting'!
waitUntilFinished
+ ^ self waitUntilFinishedWithTimeout:nil
+!
+
+waitUntilFinishedWithTimeout:timeout
|processList|
- finishSema waitUncounted.
+ (finishSema waitWithTimeout:timeout) isNil ifTrue:[
+ "timed out"
+ ^ nil.
+ ].
"have to wait until the shufflers have finished their work"
- shufflerProcesses notEmptyOrNil ifTrue:[
- processList := shufflerProcesses.
+ processList := shufflerProcesses.
+ processList notEmptyOrNil ifTrue:[
processList do:[:eachProcess |
eachProcess waitUntilTerminated.
].
shufflerProcesses := nil.
].
-
- ^ exitStatus notNil and:[exitStatus success].
! !
!OSProcess class methodsFor:'documentation'!
--- a/Object.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Object.st Thu Jan 05 21:02:10 2017 +0000
@@ -257,6 +257,7 @@
"Modified: / 4.8.1999 / 08:54:06 / stefan"
! !
+
!Object class methodsFor:'Compatibility-ST80'!
rootError
@@ -495,6 +496,7 @@
InfoPrinting := aBoolean
! !
+
!Object class methodsFor:'queries'!
isAbstract
@@ -517,6 +519,10 @@
! !
+
+
+
+
!Object methodsFor:'Compatibility-Dolphin'!
stbFixup: anSTBInFiler at: newObjectIndex
@@ -688,6 +694,8 @@
"
! !
+
+
!Object methodsFor:'accessing'!
_at:index
@@ -1784,6 +1792,8 @@
"
! !
+
+
!Object methodsFor:'attributes access'!
objectAttributeAt:attributeKey
@@ -1911,6 +1921,8 @@
! !
+
+
!Object methodsFor:'change & update'!
broadcast:aSelectorSymbol
@@ -2091,6 +2103,7 @@
^ aBlock ensure:[ self addDependent:someone ]
! !
+
!Object methodsFor:'comparing'!
= anObject
@@ -2380,6 +2393,13 @@
^ Array with:self
!
+asCollectionDo:aBlock
+ "enumerate myself as a Collection.
+ Redefined in collection."
+
+ ^ aBlock value:self
+!
+
asLink
"return a valueLink for the receiver.
Used to make sure the receiver can be added to a linked list"
@@ -8180,6 +8200,7 @@
^ self
! !
+
!Object methodsFor:'secure message sending'!
?:selector
@@ -8785,6 +8806,7 @@
"
! !
+
!Object methodsFor:'synchronized evaluation'!
freeSynchronizationSemaphore
@@ -10579,6 +10601,9 @@
^ aVisitor visitObject:self with:aParameter
! !
+
+
+
!Object class methodsFor:'documentation'!
version
--- a/OrderedDictionary.st Wed Dec 28 22:58:47 2016 +0000
+++ b/OrderedDictionary.st Thu Jan 05 21:02:10 2017 +0000
@@ -144,12 +144,8 @@
!OrderedDictionary class methodsFor:'instance creation'!
-new
- ^ super new initializeOrder
-!
-
-new: anInteger
- ^(super new: anInteger) initializeOrder
+new:anInteger
+ ^ (super new:anInteger) initializeOrder:anInteger
! !
!OrderedDictionary methodsFor:'accessing'!
@@ -847,8 +843,8 @@
!OrderedDictionary methodsFor:'initialization'!
-initializeOrder
- order := OrderedCollection new
+initializeOrder:count
+ order := OrderedCollection new:count
! !
!OrderedDictionary methodsFor:'private'!
--- a/OrderedSet.st Wed Dec 28 22:58:47 2016 +0000
+++ b/OrderedSet.st Thu Jan 05 21:02:10 2017 +0000
@@ -108,16 +108,8 @@
!OrderedSet class methodsFor:'instance creation'!
-new
- ^super new initializeOrder
-
- "Created: / 16.11.2001 / 10:10:37 / cg"
-!
-
-new: anInteger
- ^(super new: anInteger) initializeOrder
-
- "Created: / 16.11.2001 / 10:10:07 / cg"
+new:anInteger
+ ^ (super new:anInteger) initializeOrder:anInteger
! !
!OrderedSet methodsFor:'accessing'!
@@ -259,7 +251,7 @@
"remove all elements from the receiver. Returns the receiver."
super removeAll.
- self initializeOrder.
+ self initializeOrder:0.
"Created: / 16.11.2001 / 10:21:40 / cg"
!
@@ -413,10 +405,8 @@
!OrderedSet methodsFor:'initialization'!
-initializeOrder
- order := OrderedCollection new
-
- "Created: / 16.11.2001 / 10:06:05 / cg"
+initializeOrder:count
+ order := OrderedCollection new:count
! !
!OrderedSet methodsFor:'searching'!
--- a/PipeStream.st Wed Dec 28 22:58:47 2016 +0000
+++ b/PipeStream.st Thu Jan 05 21:02:10 2017 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -14,7 +16,7 @@
"{ NameSpace: Smalltalk }"
NonPositionableExternalStream subclass:#PipeStream
- instanceVariableNames:'commandString pid exitStatus exitSema exitAction'
+ instanceVariableNames:'commandString osProcess'
classVariableNames:'BrokenPipeSignal'
poolDictionaries:''
category:'Streams-External'
@@ -222,7 +224,7 @@
|p|
p := PipeStream bidirectionalFor:'cat -u'.
- p nextPutAll:'Wer ist der Bürgermeister von Wesel'; cr.
+ p nextPutAll:'Wer ist der Bürgermeister von Wesel'; cr.
Transcript showCR:p nextLine.
p close
"
@@ -275,48 +277,53 @@
The commands error output is send to my own error output."
^ self
- readingFrom:commandString
- errorDisposition:#stderr
- inDirectory:nil
+ readingFrom:commandString
+ errorDisposition:#stderr
+ inDirectory:nil
"unix:
- PipeStream readingFrom:'ls -l'.
- "
-
- "
- |p|
-
- p := PipeStream readingFrom:'ls -l'.
- Transcript showCR:p nextLine.
- p close
+ PipeStream readingFrom:'ls -l'.
"
"
- |s|
- s := PipeStream readingFrom:'sh -c sleep\ 600'.
- (Delay forSeconds:2) wait.
- s shutDown
+ |p|
+
+ p := PipeStream readingFrom:'ls -l'.
+ Transcript showCR:p nextLine.
+ p close
"
- "vms:
- PipeStream readingFrom:'dir'.
+
+ "
+ |p|
+
+ p := PipeStream readingFrom:'echo error >&2'.
+ Transcript showCR:p nextLine.
+ p close
"
"
- |p|
- p := PipeStream readingFrom:'dir'.
- Transcript showCR:p nextLine.
- p close
+ |s|
+ s := PipeStream readingFrom:'sh -c sleep\ 600'.
+ (Delay forSeconds:2) wait.
+ s abortAndClose
"
- "msdos:
- PipeStream readingFrom:'dir'.
+ "
+ |p|
+ p := PipeStream readingFrom:'dir'.
+ Transcript showCR:p nextLine.
+ p close
+ "
+
+ "Windows:
+ PipeStream readingFrom:'dir'.
"
"
- |p|
- p := PipeStream readingFrom:'dir'.
- Transcript showCR:p nextLine.
- p close
+ |p|
+ p := PipeStream readingFrom:'dir'.
+ Transcript showCR:p nextLine.
+ p close
"
"Modified: 24.4.1996 / 09:09:25 / stefan"
@@ -334,10 +341,27 @@
Nil is treated like #stderr"
^ self basicNew
- openPipeFor:commandString
- withMode:#r
- errorDisposition:errorDisposition
- inDirectory:aDirectory
+ openPipeFor:commandString
+ withMode:#r
+ errorDisposition:errorDisposition
+ inDirectory:aDirectory
+
+
+ "
+ |p|
+
+ p := PipeStream readingFrom:'bla' errorDisposition:Transcript inDirectory:nil.
+ Transcript showCR:p nextLine.
+ p close
+ "
+
+ "
+ |p|
+
+ p := PipeStream readingFrom:'bla' errorDisposition:#inline inDirectory:nil.
+ Transcript showCR:p nextLine.
+ p close
+ "
!
readingFrom:commandString inDirectory:aDirectory
@@ -472,15 +496,21 @@
exitStatus
"return the exitStatus"
- ^ exitStatus
-
+ osProcess isNil ifTrue:[
+ ^ nil.
+ ].
+ ^ osProcess exitStatus.
+
"Created: 28.12.1995 / 14:54:41 / stefan"
!
pid
"return pid"
- ^ pid
+ osProcess isNil ifTrue:[
+ ^ nil.
+ ].
+ ^ osProcess pid.
"Created: 28.12.1995 / 14:54:30 / stefan"
! !
@@ -511,10 +541,8 @@
handle notNil ifTrue:[
super close.
- pid notNil ifTrue:[
- "/ wait for the pipe-command to terminate.
- self waitForPipeCommandWithTimeout:nil.
- ].
+ "/ wait for the pipe-command to terminate.
+ self waitForPipeCommandWithTimeout:nil.
].
"Modified: / 12.9.1998 / 16:51:04 / cg"
@@ -568,37 +596,24 @@
int retVal;
if ((fp = __INST(handle)) != nil) {
- __INST(handle) = nil;
- f = __FILEVal(fp);
- if (@global(FileOpenTrace) == true) {
- console_fprintf(stderr, "close [PipeStream] %"_lx_" fd=%d\n", (INT)f, fileno(f));
- }
+ __INST(handle) = nil;
+ f = __FILEVal(fp);
+ if (@global(FileOpenTrace) == true) {
+ console_fprintf(stderr, "close [PipeStream] %"_lx_" fd=%d\n", (INT)f, fileno(f));
+ }
#ifdef __win32__
- do {
- __threadErrno = 0;
- retVal = __STX_C_NOINT_CALL1( "close", (void*)close, (void*)fileno(f) );
- } while ((retVal < 0) && (__threadErrno == EINTR));
+ do {
+ __threadErrno = 0;
+ retVal = __STX_C_NOINT_CALL1( "close", (void*)close, (void*)fileno(f) );
+ } while ((retVal < 0) && (__threadErrno == EINTR));
#else
- __BEGIN_INTERRUPTABLE__
- close(fileno(f));
- __END_INTERRUPTABLE__
+ __BEGIN_INTERRUPTABLE__
+ close(fileno(f));
+ __END_INTERRUPTABLE__
#endif
}
#endif /* not transputer */
%}.
- exitAction notNil ifTrue:[
- action := exitAction.
- exitAction := nil.
- action value.
- ]
-!
-
-exitAction:aBlock
- "define a block to be evaluated when the pipe is closed.
- This is only used with VMS, to remove any temporary COM file.
- (see readingFrom:inDirectory:)"
-
- exitAction := aBlock
!
openPipeFor:aCommandString withMode:rwMode errorDisposition:errorDisposition inDirectory:aDirectory
@@ -611,9 +626,7 @@
#stderr causes it to be written to smalltalks own stderr.
Nil is treated like #stderr"
- |blocked pipeFdArray execFdArray execFd myFd shellAndArgs
- shellPath shellArgs mbx mbxName
- realCmd execDirectory tmpComFile nullOutput resultPid errorNumber|
+ |pipeArray remotePipeEnd nullOutput errorNumber myPipeEnd result|
handle notNil ifTrue:[
"the pipe was already open ...
@@ -632,185 +645,95 @@
]].
lastErrorNumber := nil.
- exitStatus := nil.
- exitSema := Semaphore new name:'pipe exitSema'.
-
- realCmd := aCommandString.
- execDirectory := aDirectory.
- execFdArray := #(0 1 2) copy.
+ commandString := aCommandString.
+ "stdio lib does not work with blocking pipes and interrupts
+ for WIN, Linux, Solaris and probably any other UNIX"
+ buffered := false.
+ hitEOF := false.
+ binary := false.
- OperatingSystem isVMSlike ifTrue:[
- "/
- "/ the generated COM-file includes a 'set default'
- "/
- tmpComFile := OperatingSystem createCOMFileForVMSCommand:aCommandString in:aDirectory.
- realCmd := '@' , tmpComFile osName.
- execDirectory := nil.
+ osProcess := OSProcess new
+ command:aCommandString;
+ directory:aDirectory.
- mbx := OperatingSystem createMailBox.
- mbx isNil ifTrue:[
+ mode == #readwrite ifTrue:[
+ pipeArray := self class makeBidirectionalPipe.
+ pipeArray isNil ifTrue:[
lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
- tmpComFile delete.
^ self openError:errorNumber.
].
- mbxName := OperatingSystem mailBoxNameOf:mbx.
-
- "/ 'mailBox is ' print. mbx print. ' name is ' print. mbxName printCR.
- shellPath := ''.
- shellArgs := realCmd.
-
- rwMode = #r ifTrue:[
- "redirect stdout of subprocess to write to mailbox"
- execFdArray at:2 put:mbx.
- ] ifFalse:[
- "redirect stdin of subprocess to read from mailbox"
- execFdArray at:1 put:mbx.
+ myPipeEnd := pipeArray at:1.
+ remotePipeEnd := pipeArray at:2.
+ osProcess inStream:remotePipeEnd.
+ osProcess outStream:remotePipeEnd.
+ ] ifFalse:[
+ pipeArray := self class makePipe.
+ pipeArray isNil ifTrue:[
+ lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
+ ^ self openError:errorNumber.
].
- ] ifFalse:[
- shellAndArgs := OperatingSystem commandAndArgsForOSCommand:realCmd.
- shellPath := shellAndArgs at:1.
- shellArgs := shellAndArgs at:2.
- mode == #readwrite ifTrue:[
- pipeFdArray := OperatingSystem makeBidirectionalPipe.
- pipeFdArray isNil ifTrue:[
- lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
- ^ self openError:errorNumber.
- ].
- myFd := pipeFdArray at:1.
- execFd := pipeFdArray at:2.
- execFdArray at:1 put:execFd.
- execFdArray at:2 put:execFd.
+ mode == #readonly ifTrue:[
+ "redirect stdout of subprocess to write to pipe"
+ myPipeEnd := pipeArray at:1.
+ remotePipeEnd := pipeArray at:2.
+ osProcess outStream:remotePipeEnd.
] ifFalse:[
- pipeFdArray := OperatingSystem makePipe.
- pipeFdArray isNil ifTrue:[
- lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
- ^ self openError:errorNumber.
- ].
-
- mode == #readonly ifTrue:[
- "redirect stdout of subprocess to write to pipe"
- myFd := pipeFdArray at:1.
- execFd := pipeFdArray at:2.
- execFdArray at:2 put:execFd.
- ] ifFalse:[
- "redirect stdin of subprocess to read from pipe"
- myFd := pipeFdArray at:2.
- execFd := pipeFdArray at:1.
- execFdArray at:1 put:execFd.
- ].
+ "redirect stdin of subprocess to read from pipe"
+ myPipeEnd := pipeArray at:2.
+ remotePipeEnd := pipeArray at:1.
+ osProcess inStream:remotePipeEnd.
].
].
errorDisposition == #discard ifTrue:[
nullOutput := Filename nullDevice writeStream.
- execFdArray at:3 put:nullOutput fileDescriptor
- ] ifFalse:[
- (errorDisposition == #inline or:[errorDisposition == #stdout]) ifTrue:[
- execFdArray at:3 put:1
- ] ifFalse:[
-"/ errorDisposition isStream ifTrue:[
-"/self halt.
-"/ ].
- ].
- ].
-
- "/ must block here, to avoid races due to early finishing
- "/ subprocesses ...
-
- blocked := OperatingSystem blockInterrupts.
+ osProcess errorStream:nullOutput.
+ ] ifFalse:[(errorDisposition == #inline or:[errorDisposition == #stdout]) ifTrue:[
+ osProcess errorStream:osProcess outStream.
+ ] ifFalse:[(errorDisposition == #stderr or:[errorDisposition isNil]) ifTrue:[
+ osProcess errorStream:Stderr.
+ ] ifFalse:[errorDisposition isStream ifTrue:[
+ osProcess errorStream:errorDisposition.
+ ]]]].
- "beware: pid may change if subprocess is fast"
- pid := resultPid := Processor
- monitor:[
- OperatingSystem
- exec:shellPath
- withArguments:shellArgs
- environment:nil
- fileDescriptors:execFdArray
- fork:true
- newPgrp:true
- inDirectory:execDirectory
- showWindow:false.
- ]
- action:[:status |
- status stillAlive ifFalse:[
- exitStatus := status.
+ osProcess terminateActionBlock:[
+ "writing doesn't make sense - there is no reader any longer"
+ mode == #readwrite ifTrue:[
+ "... but allow to read the rest of the command's output"
+ self shutDownOutput.
+ ] ifFalse:[mode == #writeonly ifTrue:[
+ self closeFileDescriptor.
+ ]].
+ ].
- "writing doesn't make sense - there is no reader any longer"
- mode == #readwrite ifTrue:[
- "... but allow to read the rest of the command's output"
- self shutDownOutput.
- ] ifFalse:[mode == #writeonly ifTrue:[
- self closeFileDescriptor.
- ]].
-
- OperatingSystem closePid:pid.
- pid := nil.
- exitSema signal.
- ].
- ].
+ result := osProcess startProcess.
"subprocess has been created.
close unused filedescriptors"
-
- execFd notNil ifTrue:[
- OperatingSystem closeFd:execFd.
+ remotePipeEnd notNil ifTrue:[
+ remotePipeEnd close.
].
-
nullOutput notNil ifTrue:[
nullOutput close
].
- resultPid notNil ifTrue:[
+ result ifTrue:[
"successfull creation of subprocesss"
- OperatingSystem isVMSlike ifTrue:[
- "/
- "/ reopen the mailbox as a file ...
- "/
- mbxName := OperatingSystem mailBoxNameOf:mbx.
- mbxName notNil ifTrue:[
- super open:mbxName withMode:rwMode.
- exitAction := [tmpComFile delete].
- ].
- ] ifFalse:[
- self setFileHandle:myFd mode:rwMode.
- handleType := #pipeFilePointer.
- ]
+ self setFileHandle:myPipeEnd fileHandle mode:rwMode.
+ myPipeEnd unregisterForFinalization. "make sure filedesciptor is not closed by finalizer"
+ myPipeEnd := nil.
+ handleType := #pipeFilePointer.
] ifFalse:[
- "creation of subprocesss failed"
- lastErrorNumber := OperatingSystem currentErrorNumber.
- OperatingSystem isVMSlike ifTrue:[
- OperatingSystem destroyMailBox:mbx.
- tmpComFile delete.
- ] ifFalse:[
- OperatingSystem closeFd:myFd.
- ].
- ].
-
- blocked ifFalse:[
- OperatingSystem unblockInterrupts
- ].
-
- (resultPid isNil or:[lastErrorNumber notNil]) ifTrue:[
- "
- the pipe open failed for some reason ...
+ "the pipe open failed for some reason ...
... this may be either due to an invalid command string,
or due to the system running out of memory (when forking
- the unix process)
- "
- exitAction value.
+ the unix process)"
+ lastErrorNumber := OperatingSystem lastErrorNumber.
+ myPipeEnd close.
^ self openError:lastErrorNumber.
].
- commandString := realCmd.
-
- "stdio lib does not work with blocking pipes and interrupts
- for WIN, Linux, Solaris and probably any other UNIX"
- buffered := false.
- position := 0.
- hitEOF := false.
- binary := false.
self registerForFinalization.
"Modified: / 23.4.1996 / 17:05:59 / stefan"
@@ -819,11 +742,8 @@
!
terminatePipeCommand
- |tpid|
-
- (tpid := pid) notNil ifTrue:[
- OperatingSystem terminateProcessGroup:tpid.
- OperatingSystem terminateProcess:tpid.
+ osProcess notNil ifTrue:[
+ osProcess terminateGroup.
].
!
@@ -831,14 +751,10 @@
"wait for the pipe command to terminate itself.
Return true, if a timeout occurred."
- pid notNil ifTrue:[
- [
- pid notNil ifTrue:[
- exitSema waitWithTimeout:seconds.
- ]
- ] valueUninterruptably
+ osProcess notNil ifTrue:[
+ ^ osProcess finishSema waitWithTimeout:seconds.
].
- ^ pid notNil
+ ^ false
! !
!PipeStream class methodsFor:'documentation'!
--- a/RecursionLock.st Wed Dec 28 22:58:47 2016 +0000
+++ b/RecursionLock.st Thu Jan 05 21:02:10 2017 +0000
@@ -183,7 +183,6 @@
|wasBlocked|
process ~~ Processor activeProcess ifTrue:[
- "I have already got the lock"
self error:'RecursionLock - signaling process doesn''t own the lock'.
].
--- a/Semaphore.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Semaphore.st Thu Jan 05 21:02:10 2017 +0000
@@ -410,17 +410,17 @@
NOTE: must be called with blocked interrupts"
- "for now"
waitingProcesses isNil ifTrue:[
- waitingProcesses := Array with:aProcess
+ "for now - assume that there is probably only one waiter"
+ waitingProcesses := Array with:aProcess
] ifFalse:[
- waitingProcesses isArray ifTrue:[
- "add 2 to reserve space for additional waiters"
- waitingProcesses := (OrderedCollection new:waitingProcesses size + 2)
- addAll:waitingProcesses;
- yourself.
- ].
- waitingProcesses add:aProcess.
+ waitingProcesses isArray ifTrue:[
+ "add 2 to reserve space for additional waiters"
+ waitingProcesses := (OrderedCollection new:waitingProcesses size + 2)
+ addAll:waitingProcesses;
+ yourself.
+ ].
+ waitingProcesses add:aProcess.
].
"/ "Sort, so that higher priority process are resumed first.
--- a/Smalltalk.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Smalltalk.st Thu Jan 05 21:02:10 2017 +0000
@@ -2754,7 +2754,11 @@
AbstractSourceCodeManager notNil ifTrue:[
sourceCodeManager := AbstractSourceCodeManager sourceCodeManagerForPackage:packageString.
sourceCodeManager notNil ifTrue:[
- ^ sourceCodeManager loadPackageWithId:packageString fromRepositoryAsAutoloaded:doLoadAsAutoloaded
+ PackageLoadError handle:[:ex2 |
+ ex reject
+ ] do:[
+ ^ sourceCodeManager loadPackageWithId:packageString fromRepositoryAsAutoloaded:doLoadAsAutoloaded
+ ].
].
].
].
--- a/SomeNumber.st Wed Dec 28 22:58:47 2016 +0000
+++ b/SomeNumber.st Thu Jan 05 21:02:10 2017 +0000
@@ -11,6 +11,8 @@
"
"{ Package: 'stx:libbasic' }"
+"{ NameSpace: Smalltalk }"
+
MetaNumber subclass:#SomeNumber
instanceVariableNames:'realNumber'
classVariableNames:''
@@ -86,6 +88,15 @@
as the receiver, false otherwise."
^ something equalFromSomeNumber:self
+
+ "
+ Float infinity = Infinity positive
+ Infinity positive = Float infinity
+ Float negativeInfinity = Infinity negative
+ Infinity negative = Float negativeInfinity
+ Float negativeInfinity = Infinity positive
+ Infinity positive = Float negativeInfinity
+ "
! !
!SomeNumber methodsFor:'printing'!
@@ -106,6 +117,10 @@
!SomeNumber methodsFor:'queries'!
+isInfinite
+ ^ realNumber isInfinite
+!
+
sign
"return the sign of the receiver (-1, 0 or 1)"
@@ -115,6 +130,6 @@
!SomeNumber class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/SomeNumber.st,v 1.4 2014-06-30 14:27:34 stefan Exp $'
+ ^ '$Header$'
! !
--- a/UnixOperatingSystem.st Wed Dec 28 22:58:47 2016 +0000
+++ b/UnixOperatingSystem.st Thu Jan 05 21:02:10 2017 +0000
@@ -3184,42 +3184,6 @@
!UnixOperatingSystem class methodsFor:'executing OS commands-implementation'!
exec:aCommandPathArg withArguments:argColl environment:environmentDictionary
- fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory
-
- ^ self
- exec:aCommandPathArg withArguments:argColl environment:environmentDictionary
- fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory showWindow:nil
-
- "
- |id|
-
- id := OperatingSystem fork.
- id == 0 ifTrue:[
- 'I am the child'.
- OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp').
- 'not reached'.
- ]
- "
- "
- |id|
-
- id := OperatingSystem fork.
- id == 0 ifTrue:[
- 'I am the child'.
- OperatingSystem
- exec:'/bin/sh'
- withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2').
- 'not reached'.
- ].
- id printNL.
- (Delay forSeconds:3.5) wait.
- 'killing ...' printNL.
- OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id.
- OperatingSystem sendSignal:(OperatingSystem sigKILL) to:id
- "
-!
-
-exec:aCommandPathArg withArguments:argColl environment:environmentDictionary
fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory showWindow:ignoredHere
"Internal lowLevel entry for combined fork & exec;
@@ -3575,245 +3539,28 @@
].
'Parent t=' print. (Timestamp now - t1) printCR.
"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
- environment:anEvironmentDictionary inDirectory:dir
-
- ^ self
- startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
- environment:anEvironmentDictionary inDirectory:dir showWindow:nil
-
- "blocking at current prio (i.e. only higher prio threads execute):
-
- OperatingSystem executeCommand:'ls -l > out'.
- OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
- "
-
- "non-blocking (lower prio threads continue):
-
- |in out err pid sema|
-
- in := 'out' asFilename readStream.
- out := 'out2' asFilename writeStream.
- err := 'err' asFilename writeStream.
-
- sema := Semaphore new.
- pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
-
- The following will no longer work. monitorPid has disappeared
-
- pid notNil ifTrue:[
- Processor monitorPid:pid action:[:osStatus | sema signal ].
- ].
- in close.
- out close.
- err close.
- sema wait.
- Transcript showCR:'finished'
- "
-
- "
- |pid sema|
-
- sema := Semaphore new.
-
- Processor
- monitor:[
- pid := OperatingSystem startProcess:'(sleep 2; ls -l) > out 2>err'
- ]
- action:[:osStatus | sema signal ].
-
- sema wait.
- Transcript showCR:'finished'
- "
-
- "
- |pid sema|
-
- sema := Semaphore new.
-
- Processor
- monitor:[
- pid := OperatingSystem startProcess:'(sleep 1; echo 1; sleep 9; ls -l) > out 2>err'
- ]
- action:[:osStatus | sema signal ].
-
- Delay waitForSeconds:2.
- OperatingSystem terminateProcess:pid.
- Transcript showCR:'terminated'
- "
-
- "Modified: / 21.3.1997 / 10:04:35 / dq"
- "Modified: / 15.7.1997 / 16:03:51 / stefan"
- "Modified: / 5.6.1998 / 19:03:51 / cg"
- "Created: / 12.11.1998 / 14:39:20 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
- environment:anEvironmentDictionary inDirectory:dir newPgrp:newPgrp showWindow:ignoredHere
-
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- If aCommandString is a String, the commandString is passed to a shell for execution
- - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- If aCommandString is an Array, the first element is the command to be executed,
- and the other elements are the arguments to the command. No shell is invoked in this case.
- The command gets stdIn, stdOut and stdErr assigned from the arguments;
- each may be nil.
- Return the processId if successful, nil otherwise.
- Use #monitorPid:action: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- |nullStream in out err shellAndArgs rslt auxFd|
-
- aCommandString isNil ifTrue:[^ nil].
-
- (in := anExternalInStream) isNil ifTrue:[
- nullStream := Filename nullDevice readWriteStream.
- in := nullStream.
- ].
- (out := anExternalOutStream) isNil ifTrue:[
- nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
- out := nullStream.
- ].
- (err := anExternalErrStream) isNil ifTrue:[
- err := out
- ].
- anAuxiliaryStream notNil ifTrue:[
- auxFd := anAuxiliaryStream fileDescriptor
- ].
-
- shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
-
- rslt := self
- exec:(shellAndArgs at:1)
- withArguments:(shellAndArgs at:2)
- environment:anEvironmentDictionary
- fileDescriptors:(Array with:in fileDescriptor
- with:out fileDescriptor
- with:err fileDescriptor
- with:auxFd)
- fork:true
- newPgrp:newPgrp
- inDirectory:dir.
-
- nullStream notNil ifTrue:[
- nullStream close.
- ].
-
- ^ rslt
-
- "blocking at current prio (i.e. only higher prio threads execute):
-
- OperatingSystem executeCommand:'ls -l > out'.
- OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
- "
-
- "non-blocking (lower prio threads continue):
-
- |in out err pid sema|
-
- in := 'out' asFilename readStream.
- out := 'out2' asFilename writeStream.
- err := 'err' asFilename writeStream.
-
- sema := Semaphore new.
- pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
-
- The following will no longer work. monitorPid has disappeared
-
- pid notNil ifTrue:[
- Processor monitorPid:pid action:[:osStatus | sema signal ].
- ].
- in close.
- out close.
- err close.
- sema wait.
- Transcript showCR:'finished'
- "
-
- "
- |pid sema|
-
- sema := Semaphore new.
-
- Processor
- monitor:[
- pid := OperatingSystem startProcess:'(sleep 2; ls -l) > out 2>err'
- ]
- action:[:osStatus | sema signal ].
-
- sema wait.
- Transcript showCR:'finished'
- "
-
- "
- |pid sema|
-
- sema := Semaphore new.
-
- Processor
- monitor:[
- pid := OperatingSystem startProcess:'(sleep 1; echo 1; sleep 9; ls -l) > out 2>err'
- ]
- action:[:osStatus | sema signal ].
-
- Delay waitForSeconds:2.
- OperatingSystem terminateProcess:pid.
- Transcript showCR:'terminated'
- "
-
- "Modified: / 21.3.1997 / 10:04:35 / dq"
- "Modified: / 15.7.1997 / 16:03:51 / stefan"
- "Modified: / 5.6.1998 / 19:03:51 / cg"
- "Created: / 12.11.1998 / 14:39:20 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
- environment:anEvironmentDictionary inDirectory:dir showWindow:ignoredHere
-
- "start executing the OS command as specified by the argument, aCommandString
- as a separate process; do not wait for the command to finish.
- If aCommandString is a String, the commandString is passed to a shell for execution
- - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- If aCommandString is an Array, the first element is the command to be executed,
- and the other elements are the arguments to the command. No shell is invoked in this case.
- The command gets stdIn, stdOut and stdErr assigned from the arguments;
- each may be nil.
- Return the processId if successful, nil otherwise.
- Use #monitorPid:action: for synchronization and exec status return,
- or #killProcess: to stop it."
-
- ^ self
- startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
- errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
- environment:anEvironmentDictionary inDirectory:dir newPgrp:true showWindow:ignoredHere
! !
!UnixOperatingSystem class methodsFor:'executing OS commands-queries'!
commandAndArgsForOSCommand:aCommandStringOrArray
"get a shell and shell arguments for command execution.
- If aCommandString is a String, the commandString is passed to a shell for execution
+ If aCommandStringOrArray is a String, the commandString is passed to a shell for execution
- see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
- If aCommandString is an Array, the first element is the command to be executed,
- and the other elements are the arguments to the command. No shell is invoked in this case."
+ If aCommandStringOrArray is an Array, the first element is the command to be executed,
+ and the other elements are the arguments to the command. No shell is invoked in this case.
+ The third element is nil - here for windows compatibility (showWindow in windows)"
aCommandStringOrArray isNonByteCollection ifTrue:[
- "if an array is passed, the command string has already been parsed an no shell is invoked"
- ^ Array with:aCommandStringOrArray first with:aCommandStringOrArray.
+ "if an array is passed, the command string has already been parsed an no shell is invoked"
+ ^ Array with:aCommandStringOrArray first with:aCommandStringOrArray with:nil.
].
"/
"/ '/bin/sh -c <command>'
"/
- ^ Array with:'/bin/sh' with:(Array with:'sh' with:'-c' with:aCommandStringOrArray)
+ ^ Array with:'/bin/sh' with:(Array with:'sh' with:'-c' with:aCommandStringOrArray) with:nil.
"Modified: / 20.1.1998 / 16:57:19 / md"
"Modified: / 5.6.1998 / 17:40:48 / cg"
@@ -5392,40 +5139,40 @@
%{
#ifdef __SCHTEAM__
if (encodedPathName.isStringLike()) {
- java.io.File file = new java.io.File( encodedPathName.asString() );
- int _mode;
-
- if (file.exists() && file.isDirectory()) {
- return __c__._RETURN_true();
- }
- return __c__._RETURN_false();
+ java.io.File file = new java.io.File( encodedPathName.asString() );
+ int _mode;
+
+ if (file.exists() && file.isDirectory()) {
+ return __c__._RETURN_true();
+ }
+ return __c__._RETURN_false();
}
#else
int ret;
if (__isStringLike(encodedPathName)) {
- struct stat buf;
+ struct stat buf;
# ifdef TRACE_STAT_CALLS
- printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
-# endif
- __BEGIN_INTERRUPTABLE__
- do {
- ret = stat((char *) __stringVal(encodedPathName), &buf);
- } while ((ret < 0) && (errno == EINTR));
- __END_INTERRUPTABLE__
- if (ret < 0) {
- @global(LastErrorNumber) = __mkSmallInteger(errno);
- RETURN ( false );
- }
- RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
+ printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
+# endif
+ __BEGIN_INTERRUPTABLE__
+ do {
+ ret = stat((char *) __stringVal(encodedPathName), &buf);
+ } while ((ret < 0) && (errno == EINTR));
+ __END_INTERRUPTABLE__
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(errno);
+ RETURN ( false );
+ }
+ RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
}
#endif /* not SCHTEAM */
%}.
^ self primitiveFailed
"an alternative implementation would be:
- ^ (self infoOf:aPathName) type == #directory
+ ^ (self infoOf:aPathName) type == #directory
"
!
--- a/Win32OperatingSystem.st Wed Dec 28 22:58:47 2016 +0000
+++ b/Win32OperatingSystem.st Thu Jan 05 21:02:10 2017 +0000
@@ -4297,18 +4297,6 @@
"Created: / 15-11-2016 / 19:39:49 / cg"
!
-primExec:commandPath commandLine:commandLine fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
- inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
- showWindow:showWindowBooleanOrNil
- "obsolete internal lowLevel entry for combined fork & exec for WIN32"
-
- ^ self
- primExec:commandPath commandLine:commandLine environment:nil
- fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
- inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
- showWindow:showWindowBooleanOrNil
-!
-
shellExecute:hwndArg lpOperation:lpOperationArg lpFile:lpFileArg lpParameters:lpParametersArg lpDirectory:lpDirectoryArg nShowCmd:nShowCmd
"Opens or prints the specified file, which can be an executable, document file, or directory.
If its a directory, an explorer window is opened (see example below).
--- a/abbrev.stc Wed Dec 28 22:58:47 2016 +0000
+++ b/abbrev.stc Thu Jan 05 21:02:10 2017 +0000
@@ -71,6 +71,7 @@
CompiledCode CompiledCode stx:libbasic 'Kernel-Methods' 0
ControlInterrupt ControlInterrupt stx:libbasic 'Kernel-Exceptions-Control' 1
Date Date stx:libbasic 'Magnitude-Time' 0
+EventSemaphore EventSemaphore stx:libbasic 'Kernel-Processes' 0
Exception Exception stx:libbasic 'Kernel-Exceptions' 1
ExternalFunction ExternalFunction stx:libbasic 'System-Support' 0
False False stx:libbasic 'Kernel-Objects' 0
@@ -87,7 +88,6 @@
NoHandlerError NoHandlerError stx:libbasic 'Kernel-Exceptions-Errors' 1
Notification Notification stx:libbasic 'Kernel-Exceptions' 1
OSHandle OSHandle stx:libbasic 'Compatibility-VisualWorks' 0
-PCFilename PCFilename stx:libbasic 'OS-Windows' 0
PeekableStream PeekableStream stx:libbasic 'Streams' 0
Process Process stx:libbasic 'Kernel-Processes' 0
QuerySignal QuerySignal stx:libbasic 'Kernel-Exceptions' 0
@@ -100,7 +100,6 @@
True True stx:libbasic 'Kernel-Objects' 0
UnixFilename UnixFilename stx:libbasic 'OS-Unix' 0
WeakInterestConverter WeakInterestConverter stx:libbasic 'Interface-Support-Models' 0
-Win32Constants Win32Constants stx:libbasic 'OS-Windows' 0
ArrayedCollection ArrayedCollection stx:libbasic 'Collections-Abstract' 0
Association Association stx:libbasic 'Collections-Support' 0
Block Block stx:libbasic 'Kernel-Methods' 0
@@ -170,7 +169,6 @@
UserConfirmation UserConfirmation stx:libbasic 'Kernel-Exceptions-Notifications' 1
UserInterrupt UserInterrupt stx:libbasic 'Kernel-Exceptions-Control' 1
UserNotification UserNotification stx:libbasic 'Kernel-Exceptions-Notifications' 1
-Win32Handle Win32Handle stx:libbasic 'OS-Windows' 0
YesToAllConfirmation YesToAllConfirmation stx:libbasic 'Kernel-Exceptions-Notifications' 1
stx_libbasic stx_libbasic stx:libbasic '* Projects & Packages *' 3
AbortAllOperationRequest AbortAllOperationRequest stx:libbasic 'Kernel-Exceptions-Control' 1
@@ -220,6 +218,9 @@
TerminateProcessRequest TerminateProcessRequest stx:libbasic 'Kernel-Exceptions-Control' 1
TimeDuration TimeDuration stx:libbasic 'Magnitude-Time' 0
UninterpretedBytes UninterpretedBytes stx:libbasic 'Collections-Abstract' 0
+UnixFileDescriptorHandle UnixFileDescriptorHandle stx:libbasic 'OS-Unix' 0
+UnixFileHandle UnixFileHandle stx:libbasic 'OS-Unix' 0
+UnixOperatingSystem UnixOperatingSystem stx:libbasic 'OS-Unix' 0
UserInformation UserInformation stx:libbasic 'Kernel-Exceptions-Notifications' 1
UtcTimestamp UtcTimestamp stx:libbasic 'Magnitude-Time' 0
VMInternalError VMInternalError stx:libbasic 'Kernel-Exceptions-Errors' 1
@@ -228,7 +229,6 @@
WeakArray WeakArray stx:libbasic 'Collections-Weak' 0
WeakIdentitySet WeakIdentitySet stx:libbasic 'Collections-Weak' 0
WeakValueDictionary WeakValueDictionary stx:libbasic 'Collections-Weak' 0
-Win32FILEHandle Win32FILEHandle stx:libbasic 'OS-Windows' 0
WriteStream WriteStream stx:libbasic 'Streams' 0
AbortOperationRequest AbortOperationRequest stx:libbasic 'Kernel-Exceptions-Control' 1
AbstractNumberVector AbstractNumberVector stx:libbasic 'Collections-Arrayed' 0
@@ -254,6 +254,7 @@
LargeInteger LargeInteger stx:libbasic 'Magnitude-Numbers' 0
LongFloat LongFloat stx:libbasic 'Magnitude-Numbers' 0
OSSignalInterrupt OSSignalInterrupt stx:libbasic 'Kernel-Exceptions-Control' 1
+OSXOperatingSystem OSXOperatingSystem stx:libbasic 'OS-Unix' 0
OsIllegalOperation OsIllegalOperation stx:libbasic 'OS-Support' 1
OsInaccessibleError OsInaccessibleError stx:libbasic 'OS-Support' 1
OsInvalidArgumentsError OsInvalidArgumentsError stx:libbasic 'OS-Support' 1
@@ -322,7 +323,6 @@
UnimplementedFunctionalityError UnimplementedFunctionalityError stx:libbasic 'Kernel-Exceptions-Errors' 1
UnprotectedExternalBytes UnprotectedExternalBytes stx:libbasic 'System-Support' 0
WeakDependencyDictionary WeakDependencyDictionary stx:libbasic 'Collections-Weak' 0
-Win32OperatingSystem Win32OperatingSystem stx:libbasic 'OS-Windows' 0
WriteError WriteError stx:libbasic 'Kernel-Exceptions-Errors' 1
AbstractClassInstantiationError AbstractClassInstantiationError stx:libbasic 'Kernel-Exceptions-ExecutionErrors' 1
BadLiteralsError BadLiteralsError stx:libbasic 'Kernel-Exceptions-ExecutionErrors' 1
@@ -373,10 +373,11 @@
UnderflowError UnderflowError stx:libbasic 'Kernel-Exceptions-Errors' 1
ZeroDivide ZeroDivide stx:libbasic 'Kernel-Exceptions-Errors' 1
BadRomanNumberFormatError BadRomanNumberFormatError stx:libbasic 'Magnitude-Numbers' 1
-UnixFileDescriptorHandle UnixFileDescriptorHandle stx:libbasic 'unknownCategory' 0
-UnixFileHandle UnixFileHandle stx:libbasic 'unknownCategory' 0
-UnixOperatingSystem UnixOperatingSystem stx:libbasic 'unknownCategory' 0
-OSXOperatingSystem OSXOperatingSystem stx:libbasic 'unknownCategory' 0
+PCFilename PCFilename stx:libbasic 'unknownCategory' 0
+Win32Constants Win32Constants stx:libbasic 'unknownCategory' 0
+Win32Handle Win32Handle stx:libbasic 'unknownCategory' 0
+Win32FILEHandle Win32FILEHandle stx:libbasic 'unknownCategory' 0
+Win32OperatingSystem Win32OperatingSystem stx:libbasic 'unknownCategory' 0
OpenVMSFileHandle OpenVMSFileHandle stx:libbasic 'unknownCategory' 0
OpenVMSFilename OpenVMSFilename stx:libbasic 'unknownCategory' 0
OpenVMSOperatingSystem OpenVMSOperatingSystem stx:libbasic 'unknownCategory' 0
--- a/bc.mak Wed Dec 28 22:58:47 2016 +0000
+++ b/bc.mak Thu Jan 05 21:02:10 2017 +0000
@@ -140,6 +140,7 @@
$(OUTDIR)CompiledCode.$(O) CompiledCode.$(C) CompiledCode.$(H): CompiledCode.st $(INCLUDE_TOP)\stx\libbasic\ExecutableFunction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)ControlInterrupt.$(O) ControlInterrupt.$(C) ControlInterrupt.$(H): ControlInterrupt.st $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)Date.$(O) Date.$(C) Date.$(H): Date.st $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)EventSemaphore.$(O) EventSemaphore.$(C) EventSemaphore.$(H): EventSemaphore.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\Semaphore.$(H) $(STCHDR)
$(OUTDIR)Exception.$(O) Exception.$(C) Exception.$(H): Exception.st $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)ExternalFunction.$(O) ExternalFunction.$(C) ExternalFunction.$(H): ExternalFunction.st $(INCLUDE_TOP)\stx\libbasic\ExecutableFunction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)False.$(O) False.$(C) False.$(H): False.st $(INCLUDE_TOP)\stx\libbasic\Boolean.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -437,10 +438,10 @@
$(OUTDIR)UnderflowError.$(O) UnderflowError.$(C) UnderflowError.$(H): UnderflowError.st $(INCLUDE_TOP)\stx\libbasic\ArithmeticError.$(H) $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\ExecutionError.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProceedableError.$(H) $(INCLUDE_TOP)\stx\libbasic\RangeError.$(H) $(STCHDR)
$(OUTDIR)ZeroDivide.$(O) ZeroDivide.$(C) ZeroDivide.$(H): ZeroDivide.st $(INCLUDE_TOP)\stx\libbasic\ArithmeticError.$(H) $(INCLUDE_TOP)\stx\libbasic\DomainError.$(H) $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\ExecutionError.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProceedableError.$(H) $(STCHDR)
$(OUTDIR)BadRomanNumberFormatError.$(O) BadRomanNumberFormatError.$(C) BadRomanNumberFormatError.$(H): BadRomanNumberFormatError.st $(INCLUDE_TOP)\stx\libbasic\ConversionError.$(H) $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\NumberConversionError.$(H) $(INCLUDE_TOP)\stx\libbasic\NumberFormatError.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProceedableError.$(H) $(INCLUDE_TOP)\stx\libbasic\RomanNumberFormatError.$(H) $(STCHDR)
-$(OUTDIR)PCFilename.$(O) PCFilename.$(C) PCFilename.$(H): PCFilename.st $(INCLUDE_TOP)\stx\libbasic\Filename.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)Win32Constants.$(O) Win32Constants.$(C) Win32Constants.$(H): Win32Constants.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
-$(OUTDIR)Win32FILEHandle.$(O) Win32FILEHandle.$(C) Win32FILEHandle.$(H): Win32FILEHandle.st $(INCLUDE_TOP)\stx\libbasic\ExternalAddress.$(H) $(INCLUDE_TOP)\stx\libbasic\OSFileHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\OSHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)Win32Handle.$(O) Win32Handle.$(C) Win32Handle.$(H): Win32Handle.st $(INCLUDE_TOP)\stx\libbasic\ExternalAddress.$(H) $(INCLUDE_TOP)\stx\libbasic\OSHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)Win32OperatingSystem.$(O) Win32OperatingSystem.$(C) Win32OperatingSystem.$(H): Win32OperatingSystem.st $(INCLUDE_TOP)\stx\libbasic\AbstractOperatingSystem.$(H) $(INCLUDE_TOP)\stx\libbasic\ArrayedCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\ByteArray.$(H) $(INCLUDE_TOP)\stx\libbasic\Collection.$(H) $(INCLUDE_TOP)\stx\libbasic\ExternalAddress.$(H) $(INCLUDE_TOP)\stx\libbasic\OSHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SequenceableCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(INCLUDE_TOP)\stx\libbasic\UninterpretedBytes.$(H) $(INCLUDE_TOP)\stx\libbasic\Win32Constants.$(H) $(INCLUDE_TOP)\stx\libbasic\Win32Handle.$(H) $(STCHDR)
+$(OUTDIR)PCFilename.$(O) PCFilename.$(C) PCFilename.$(H): PCFilename.st $(STCHDR)
+$(OUTDIR)Win32Constants.$(O) Win32Constants.$(C) Win32Constants.$(H): Win32Constants.st $(STCHDR)
+$(OUTDIR)Win32Handle.$(O) Win32Handle.$(C) Win32Handle.$(H): Win32Handle.st $(STCHDR)
+$(OUTDIR)Win32FILEHandle.$(O) Win32FILEHandle.$(C) Win32FILEHandle.$(H): Win32FILEHandle.st $(STCHDR)
+$(OUTDIR)Win32OperatingSystem.$(O) Win32OperatingSystem.$(C) Win32OperatingSystem.$(H): Win32OperatingSystem.st $(STCHDR)
# ENDMAKEDEPEND --- do not remove this line
--- a/libInit.cc Wed Dec 28 22:58:47 2016 +0000
+++ b/libInit.cc Thu Jan 05 21:02:10 2017 +0000
@@ -86,6 +86,7 @@
extern void _CompiledCode_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
extern void _ControlInterrupt_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
extern void _Date_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
+extern void _EventSemaphore_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
extern void _Exception_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
extern void _ExternalFunction_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
extern void _False_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
@@ -484,6 +485,7 @@
_CompiledCode_Init(pass,__pRT__,snd);
_ControlInterrupt_Init(pass,__pRT__,snd);
_Date_Init(pass,__pRT__,snd);
+ _EventSemaphore_Init(pass,__pRT__,snd);
_Exception_Init(pass,__pRT__,snd);
_ExternalFunction_Init(pass,__pRT__,snd);
_False_Init(pass,__pRT__,snd);
--- a/stx_libbasic.st Wed Dec 28 22:58:47 2016 +0000
+++ b/stx_libbasic.st Thu Jan 05 21:02:10 2017 +0000
@@ -248,6 +248,7 @@
CompiledCode
ControlInterrupt
Date
+ EventSemaphore
Exception
ExternalFunction
False
@@ -264,7 +265,6 @@
NoHandlerError
Notification
OSHandle
- (PCFilename win32)
PeekableStream
Process
QuerySignal
@@ -277,7 +277,6 @@
True
UnixFilename
WeakInterestConverter
- (Win32Constants win32)
ArrayedCollection
Association
Block
@@ -347,7 +346,6 @@
UserConfirmation
UserInterrupt
UserNotification
- (Win32Handle win32)
YesToAllConfirmation
#'stx_libbasic'
AbortAllOperationRequest
@@ -397,6 +395,9 @@
TerminateProcessRequest
TimeDuration
UninterpretedBytes
+ (UnixFileDescriptorHandle unix)
+ (UnixFileHandle unix)
+ (UnixOperatingSystem unix)
UserInformation
UtcTimestamp
VMInternalError
@@ -405,7 +406,6 @@
WeakArray
WeakIdentitySet
WeakValueDictionary
- (Win32FILEHandle win32)
WriteStream
AbortOperationRequest
AbstractNumberVector
@@ -431,6 +431,7 @@
LargeInteger
LongFloat
OSSignalInterrupt
+ (OSXOperatingSystem unix)
OsIllegalOperation
OsInaccessibleError
OsInvalidArgumentsError
@@ -499,7 +500,6 @@
UnimplementedFunctionalityError
UnprotectedExternalBytes
WeakDependencyDictionary
- (Win32OperatingSystem win32)
WriteError
AbstractClassInstantiationError
BadLiteralsError
@@ -550,10 +550,11 @@
UnderflowError
ZeroDivide
BadRomanNumberFormatError
- (UnixFileDescriptorHandle unix)
- (UnixFileHandle unix)
- (UnixOperatingSystem unix)
- (OSXOperatingSystem unix)
+ (PCFilename win32)
+ (Win32Constants win32)
+ (Win32Handle win32)
+ (Win32FILEHandle win32)
+ (Win32OperatingSystem win32)
(OpenVMSFileHandle vms)
(OpenVMSFilename vms)
(OpenVMSOperatingSystem vms)
--- a/stx_libbasicWINrc.rc Wed Dec 28 22:58:47 2016 +0000
+++ b/stx_libbasicWINrc.rc Thu Jan 05 21:02:10 2017 +0000
@@ -3,7 +3,7 @@
// automagically generated from the projectDefinition: stx_libbasic.
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 7,1,1,170
+ FILEVERSION 7,1,1,171
PRODUCTVERSION 7,1,0,0
#if (__BORLANDC__)
FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE
@@ -20,12 +20,12 @@
BEGIN
VALUE "CompanyName", "Claus Gittinger / eXept Software AG\0"
VALUE "FileDescription", "Smalltalk/X Basic Classes (LIB)\0"
- VALUE "FileVersion", "7.1.1.170\0"
+ VALUE "FileVersion", "7.1.1.171\0"
VALUE "InternalName", "stx:libbasic\0"
VALUE "LegalCopyright", "Copyright Claus Gittinger 1988\nCopyright eXept Software AG 2013\0"
VALUE "ProductName", "Smalltalk/X\0"
VALUE "ProductVersion", "7.1.0.0\0"
- VALUE "ProductDate", "Thu, 22 Dec 2016 13:56:45 GMT\0"
+ VALUE "ProductDate", "Tue, 27 Dec 2016 10:27:37 GMT\0"
END
END