#FEATURE by cg
class: OSProcess
who gets the terminateAction callback:
interrupt the caller of startProcess, iff still alive.
comment/format in: #terminateActionBlock:
changed: #startProcess
class: OSProcess class
comment/format in: #examples
--- a/OSProcess.st Tue May 22 12:24:27 2018 +0200
+++ b/OSProcess.st Tue May 22 12:43:11 2018 +0200
@@ -1,21 +1,23 @@
+"{ Encoding: utf8 }"
+
"{ Package: 'stx:libbasic' }"
"{ NameSpace: Smalltalk }"
Object subclass:#OSProcess
- instanceVariableNames:'pid command environment directory inStream outStream errorStream
- auxStream showWindow lineWise newPgrp exitStatus finishSema
- shufflerProcesses streamsToClose terminateActionBlock'
- classVariableNames:''
- poolDictionaries:''
- category:'System-Support'
+ instanceVariableNames:'pid command environment directory inStream outStream errorStream
+ auxStream showWindow lineWise newPgrp exitStatus finishSema
+ shufflerProcesses streamsToClose terminateActionBlock'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'System-Support'
!
OSProcess subclass:#RemoteOSProcess
- instanceVariableNames:'host'
- classVariableNames:'MethodPerHost'
- poolDictionaries:''
- privateIn:OSProcess
+ instanceVariableNames:'host'
+ classVariableNames:'MethodPerHost'
+ poolDictionaries:''
+ privateIn:OSProcess
!
!OSProcess class methodsFor:'documentation'!
@@ -59,10 +61,11 @@
send command's output to the Transcript:
[exBegin]
OSProcess new
- command:'ls -l';
+ terminateActionBlock:[:status | Transcript showCR:status. Transcript showCR:status isError];
+ command:'lsxxxx -l';
outStream:Transcript;
lineWise:true;
- execute.
+ startProcess.
[exEnd]
send command's output to my stdout (see console):
@@ -476,11 +479,16 @@
terminateActionBlock:aBlock
"set the callback block,
that will be called when the command has finished or was terminated.
- If non-nil, it will be called with optional argument:status and:self, the OSProcess."
+ If non-nil, it will be called with optional argument:status and:self, the OSProcess.
+ WARNING:
+ if the active-process calling #startProcess is already dead (i.e. terminated),
+ this callback will be called by the scheduler;
+ otherwise, the calling process will be interrupted to perform this callback.
+ Therefore: do not open any GUI or other blocking actions in it."
terminateActionBlock := aBlock.
- "Modified (comment): / 22-05-2018 / 12:21:12 / Claus Gittinger"
+ "Modified (comment): / 22-05-2018 / 12:42:21 / Claus Gittinger"
! !
!OSProcess methodsFor:'initialization'!
@@ -683,7 +691,7 @@
Answer true if the command could be started, false if not.
Return immediately (do not wait until the command is finished)."
- |externalInStream externalAuxStream externalErrorStream externalOutStream|
+ |externalInStream externalAuxStream externalErrorStream externalOutStream callingProcess|
shufflerProcesses := OrderedCollection new:4.
streamsToClose := OrderedCollection new:2.
@@ -705,6 +713,8 @@
UserPreferences current logExecutedOSCommands ifTrue:[
Transcript showCR:('OS command: ',self startCommand printString).
].
+
+ callingProcess := Processor activeProcess.
Processor
monitor:[
@@ -733,7 +743,14 @@
finishSema signal.
terminateActionBlock notNil ifTrue:[
- terminateActionBlock valueWithOptionalArgument:status and:self.
+ callingProcess isDead ifTrue:[
+ terminateActionBlock valueWithOptionalArgument:status and:self.
+ ] ifFalse:[
+ callingProcess
+ interruptWith:[
+ terminateActionBlock valueWithOptionalArgument:status and:self.
+ ]
+ ].
].
].
].
@@ -755,7 +772,7 @@
^ true.
- "Modified: / 22-05-2018 / 12:23:48 / Claus Gittinger"
+ "Modified: / 22-05-2018 / 12:39:18 / Claus Gittinger"
! !
!OSProcess methodsFor:'terminating'!