AbstractOperatingSystem.st
changeset 21202 d7b3c6ce03bb
parent 21068 5f3fa6858dea
child 21203 8144c04ec24f
--- a/AbstractOperatingSystem.st	Tue Dec 27 14:07:48 2016 +0100
+++ b/AbstractOperatingSystem.st	Tue Dec 27 14:12:50 2016 +0100
@@ -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:environment 
+        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'!