#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Fri, 11 Aug 2017 14:07:53 +0200
changeset 22198 c81fce52627d
parent 22197 444d71c29720
child 22199 4638d345471d
#FEATURE by cg class: OSProcess preps for remote processes
OSProcess.st
--- a/OSProcess.st	Fri Aug 11 12:46:09 2017 +0200
+++ b/OSProcess.st	Fri Aug 11 14:07:53 2017 +0200
@@ -11,6 +11,13 @@
 	category:'System-Support'
 !
 
+OSProcess subclass:#RemoteOSProcess
+	instanceVariableNames:'host'
+	classVariableNames:'MethodPerHost'
+	poolDictionaries:''
+	privateIn:OSProcess
+!
+
 !OSProcess class methodsFor:'documentation'!
 
 documentation
@@ -36,64 +43,64 @@
 examples
 "
                                                             [exBegin]
-        |outStream|
+    |outStream|
 
-        outStream := '' writeStream.
+    outStream := '' writeStream.
 
-        OSProcess new 
-            command:'ls -l';
-            inStream:'abc' readStream;
-            outStream:outStream;
-            lineWise:true;
-            execute.
+    OSProcess new 
+        command:'ls -l';
+        inStream:'abc' readStream;
+        outStream:outStream;
+        lineWise:true;
+        execute.
 
-        outStream contents
+    outStream contents
                                                             [exEnd]
 
                                                             [exBegin]
-        |outStream|
+    |outStream|
 
-        outStream := '' writeStream.
+    outStream := '' writeStream.
 
-        OSProcess new 
-            command:'ls -l; sleep 10; echo =================================; echo hallo after 10s; echo >&2 +++++++++++++++++++++; cat >&2';
-            inStream:'abc' readStream;
-            outStream:outStream;
-            errorStream:outStream;
-            startProcess.
+    OSProcess new 
+        command:'ls -l; sleep 10; echo =================================; echo hallo after 10s; echo >&2 +++++++++++++++++++++; cat >&2';
+        inStream:'abc' readStream;
+        outStream:outStream;
+        errorStream:outStream;
+        startProcess.
 
-        outStream inspect
+    outStream inspect
                                                             [exEnd]
 
                                                             [exBegin]
-        |outStream|
+    |outStream|
 
-        outStream := '' writeStream.
+    outStream := '' writeStream.
 
-        OSProcess new 
-            command:'ls -l & ls -l >&2';
-            inStream:'abc' readStream;
-            outStream:outStream;
-            errorStream:outStream;
-            startProcess.
+    OSProcess new 
+        command:'ls -l & ls -l >&2';
+        inStream:'abc' readStream;
+        outStream:outStream;
+        errorStream:outStream;
+        startProcess.
 
-        outStream inspect
+    outStream inspect
                                                             [exEnd]
 
     Execute commands in shell/cmd.exe and read them from stdin:
                                                             [exBegin]
-        |outStream|
+    |outStream|
 
-        outStream := '' writeStream.
+    outStream := '' writeStream.
 
-        OSProcess new 
-            command:'';
-            inStream:'ls -l' readStream;
-            outStream:outStream;
-            lineWise:true;
-            execute.
+    OSProcess new 
+        command:'';
+        inStream:'ls -l' readStream;
+        outStream:outStream;
+        lineWise:true;
+        execute.
 
-        outStream contents inspect
+    outStream contents inspect
                                                             [exEnd]
 "
 ! !
@@ -101,9 +108,23 @@
 !OSProcess class methodsFor:'instance creation'!
 
 new
-    "return an initialized instance"
+    "return an initialized instance for a local process"
 
     ^ self basicNew initialize.
+!
+
+onHost:aHost
+    "return an initialized instance for a remote process running on another host"
+
+    (SocketAddress hostName:aHost) isLocal ifTrue:[
+        ^ self basicNew initialize.
+    ].
+    ^ RemoteOSProcess basicNew host:aHost; initialize.
+
+    "
+     OSProcess onHost:'localhost'
+     OSProcess onHost:'exeptn'
+    "
 ! !
 
 !OSProcess class methodsFor:'initialize'!
@@ -361,7 +382,8 @@
 
     "/ start a reader process, shuffling data from the given
     "/ inStream to the pipe (which is connected to the commands input)
-    shufflerProcess := [
+    shufflerProcess := 
+        [
             [
                 lineWise ifTrue:[
                     "shuffle until end-of-input"
@@ -413,7 +435,8 @@
         shuffledStream binary.
     ].
 
-    shufflerProcess := [
+    shufflerProcess := 
+        [
             [
                 "shuffle until the pipe closes"
                 lineWise ifTrue:[
@@ -445,6 +468,13 @@
     ^ externalStream
 
     "Modified: / 31-01-2017 / 16:57:25 / stefan"
+!
+
+startCommand
+    "the 'real' command to be executed.
+     Redefined for remote processes (eg. to construct a remote command string)"
+    
+    ^ command
 ! !
 
 !OSProcess methodsFor:'queries'!
@@ -513,6 +543,7 @@
     externalInStream := self setupShufflerForInput:inStream.
     externalAuxStream := self setupShufflerForInput:auxStream.
     externalOutStream := self setupShufflerForOutput:outStream.
+
     errorStream == outStream ifTrue:[
         externalErrorStream := externalOutStream.
     ] ifFalse:[
@@ -525,7 +556,7 @@
     Processor 
         monitor:[
             pid := OperatingSystem
-                        startProcess:command
+                        startProcess:(self startCommand)
                         inputFrom:externalInStream
                         outputTo:externalOutStream
                         errorTo:externalErrorStream
@@ -541,11 +572,12 @@
                 pid notNil ifTrue:[
                     OperatingSystem closePid:pid.
                 ].
-"/                shufflerProcesses do:[:eachProcess|
-"/                    "terminate the shuffler processes.
-"/                     They close the local side of the pipe when being terminated"
-"/                    eachProcess terminate.
-"/                ].
+                "/ shufflerProcesses do:[:eachProcess|
+                "/     "terminate the shuffler processes.
+                "/      They close the local side of the pipe when being terminated"
+                "/    eachProcess terminate.
+                "/ ].
+                
                 finishSema signal.
                 terminateActionBlock value.
             ].
@@ -645,6 +677,63 @@
     ].
 ! !
 
+!OSProcess::RemoteOSProcess class methodsFor:'documentation'!
+
+documentation
+"
+    Instances of OSProcess represent operating system processes that can be executed.
+    (as opposed to Smalltalk processes).
+
+    [author:]
+        cg
+
+    [instance variables:]
+        host        String          the host on which to execute the command
+
+    [class variables:]
+
+    [see also:]
+        Process
+"
+!
+
+examples
+"
+                                                            [exBegin]
+    |outStream|
+
+    outStream := '' writeStream.
+
+    (OSProcess onHost:'exeptn') 
+        command:'ls -l';
+        inStream:'abc' readStream;
+        outStream:outStream;
+        lineWise:true;
+        execute.
+
+    outStream contents
+                                                            [exEnd]
+"
+! !
+
+!OSProcess::RemoteOSProcess methodsFor:'accessing'!
+
+host
+    ^ host
+!
+
+host:aHostName
+    host := aHostName.
+! !
+
+!OSProcess::RemoteOSProcess methodsFor:'private'!
+
+startCommand
+    "the 'real' command"
+    
+    ^ 'ssh %1 "%2"' bindWith:host with:command
+! !
+
 !OSProcess class methodsFor:'documentation'!
 
 version