PipeStr.st
changeset 2966 856dfc8a294a
parent 2961 a188727d0619
child 2969 1fcf6dfb6004
--- a/PipeStr.st	Mon Sep 22 21:04:17 1997 +0200
+++ b/PipeStr.st	Mon Sep 22 21:05:58 1997 +0200
@@ -172,8 +172,7 @@
     standard stream messages as next, nextLine etc.
 
     If a writing pipeStream is written to, after the command has finished,
-    UNIX will generate an error-signal (SIGPIPE), which will raise the
-    BrokenPipeSignal. 
+    UNIX will generate an error-signal (SIGPIPE), which will raise the BrokenPipeSignal. 
     Thus, to handle this condition correctly, the following code is suggested:
 
         |p|
@@ -191,13 +190,22 @@
 
     Notice, that iff the Stream is buffered, the Signal may occur some time after
     the write - or even at close time; to avoid a recursive signal in the exception
-    handler, a shutDown is useful there.
+    handler, a #shutDown is useful there; if you use close in the handler, this would
+    try to send any buffered output to the pipe, leading to another brokenPipe exception.
 
     Buffered pipes do not work with Linux - the stdio library seems to be
     buggy (trying to restart the read ...)
 
+    Currently, no filtering pipeStreams (i.e. both reading AND writing) are provided.
+    However, if you look at how things are setup, this can be implemented using the
+    low level primitives #mapePipe and #executeCommand from the OS class protocol.
+
     [author:]
         Claus Gittinger
+
+    [see also:]
+	ExternalStream FileStream Socket
+	OperatingSystem
 "
 ! !
 
@@ -221,15 +229,44 @@
 
     ^ (self basicNew) readingFrom:commandString
 
+    "unix:
+        PipeStream readingFrom:'ls -l'.
     "
-        PipeStream readingFrom:'ls -l'
 
+    "
+        p := PipeStream readingFrom:'ls -l'.
+	Transcript showCR:p nextLine.
+	p close
+    "
+
+    "
         |s|
         s := PipeStream readingFrom:'sh -c sleep\ 600'.
         (Delay forSeconds:2) wait.
         s shutDown
     "
 
+    "vms:
+	PipeStream readingFrom:'dir'.
+    "
+
+    "
+        |p|
+	p := PipeStream readingFrom:'dir'.
+	Transcript showCR:p nextLine.
+	p close
+    "
+
+    "msdos:
+	PipeStream readingFrom:'dir'.
+    "
+    "
+        |p|
+	p := PipeStream readingFrom:'dir'.
+	Transcript showCR:p nextLine.
+	p close
+    "
+
     "Modified: 24.4.1996 / 09:09:25 / stefan"
 !
 
@@ -239,7 +276,9 @@
 
     ^ (self basicNew) writingTo:commandString
 
-    "PipeStream writingTo:'sort'"
+    "unix:
+         PipeStream writingTo:'sort'
+    "
 ! !
 
 !PipeStream class methodsFor:'Signal constants'!
@@ -302,7 +341,6 @@
 
 %{  /* NOCONTEXT */
 #if !defined(transputer) && !defined(MSDOS_LIKE)
-
     OBJ fp;
     FILE *f;
 
@@ -353,8 +391,8 @@
     "open a pipe to the unix command in commandString; 
      mode may be 'r' or 'w'"
 
-    |blocked pipeFdArray execFdArray execFd myFd osType
-     shellPath shellArgs|
+    |blocked pipeFdArray execFdArray execFd myFd 
+     osType shellPath shellArgs closeFdArray mbx mbxName|
 
     filePointer notNil ifTrue:[
         "the pipe was already open ...
@@ -365,33 +403,36 @@
     exitStatus := nil.
     exitSema := Semaphore new name:'pipe exitSema'.
 
-    pipeFdArray := OperatingSystem makePipe.
-    pipeFdArray isNil ifTrue:[
-        lastErrorNumber := OperatingSystem currentErrorNumber.
-        ^ self openError
-    ].
+    osType := OperatingSystem platformName.
+    osType == #vms ifTrue:[
+        mbx := OperatingSystem createMailBox.
+	mbx isNil ifTrue:[
+	    lastErrorNumber := OperatingSystem currentErrorNumber.
+	    ^ self openError
+	].
+'mailBox is ' print. mbx printCR.
+	shellPath := ''.
+	shellArgs := aCommandString.
 
-    mode = 'r' ifTrue:[
-        execFd := pipeFdArray at:2.
-        execFdArray := Array with:0 with:execFd with:2.
-        myFd := pipeFdArray at:1.
+	mode = 'r' ifTrue:[
+	    execFdArray := Array with:0 with:mbx with:2.
+	] ifFalse:[
+	    execFdArray := Array with:mbx with:1 with:2.
+	].
+	closeFdArray := nil.
     ] ifFalse:[
-        execFd := pipeFdArray at:1.
-        execFdArray := Array with:execFd with:1 with:2.
-        myFd := pipeFdArray at:2.
-    ].
+        pipeFdArray := OperatingSystem makePipe.
+        pipeFdArray isNil ifTrue:[
+            lastErrorNumber := OperatingSystem currentErrorNumber.
+            ^ self openError
+	].
 
-    osType := OperatingSystem platformName.
-    osType == #unix ifTrue:[
-	shellPath := '/bin/sh'.
-	shellArgs := Array with:'sh' with:'-c' with:aCommandString.
-    ] ifFalse:[
-        osType == #win32 ifTrue:[
-	    shellPath := 'C:\WINNT\System32\cmd /c'.
-	    shellArgs := aCommandString.
-	] ifFalse:[
-            osType == #vms ifTrue:[
-	        shellPath := 'DCL - ignores shellPath'.
+        osType == #unix ifTrue:[
+	    shellPath := '/bin/sh'.
+	    shellArgs := Array with:'sh' with:'-c' with:aCommandString.
+        ] ifFalse:[
+            osType == #win32 ifTrue:[
+	        shellPath := 'C:\WINNT\System32\cmd /c'.
 	        shellArgs := aCommandString.
 	    ] ifFalse:[
     		OperatingSystem closeFd:execFd; closeFd:myFd.
@@ -400,9 +441,20 @@
 		"/
                 ^ self openError
 	    ]
-	]
+	].
+        mode = 'r' ifTrue:[
+            execFd := pipeFdArray at:2.
+            execFdArray := Array with:0 with:execFd with:2.
+            myFd := pipeFdArray at:1.
+        ] ifFalse:[
+            execFd := pipeFdArray at:1.
+            execFdArray := Array with:execFd with:1 with:2.
+            myFd := pipeFdArray at:2.
+        ].
+	closeFdArray := Array with:myFd.
     ].
 
+
     "/ must block here, to avoid races due to early finishing
     "/ subprocesses ...
 
@@ -414,7 +466,7 @@
 		      exec:shellPath
                       withArguments:shellArgs
                       fileDescriptors:execFdArray
-		      closeDescriptors:(Array with:myFd)
+		      closeDescriptors:closeFdArray
                       fork:true
 		      newPgrp:true.
 	       ]
@@ -426,16 +478,33 @@
 	          ].
                ].
 
-    OperatingSystem closeFd:execFd.
+    (osType ~~ #vms) ifTrue:[
+        OperatingSystem closeFd:execFd.
+    ].
+
     pid notNil ifTrue:[
         (osType == #win32) ifTrue:[
             self setFileHandle:myFd mode:mode
 	] ifFalse:[
-            self setFileDescriptor:myFd mode:mode.
+	    (osType == #vms) ifTrue:[
+		"/
+		"/ reopen the mailbox as a file ...
+		"/
+    	        mbxName := OperatingSystem mailBoxNameOf:mbx.
+		mbxName notNil ifTrue:[
+		    super open:mbxName withMode:mode
+		].
+	    ] ifFalse:[
+                self setFileDescriptor:myFd mode:mode.
+	    ]
 	]
     ] ifFalse:[
         lastErrorNumber := OperatingSystem currentErrorNumber.
-        OperatingSystem closeFd:myFd.
+        osType ~~ #vms ifTrue:[
+            OperatingSystem closeFd:myFd.
+	] ifFalse:[
+	    OperatingSystem destroyMailBox:mbx
+	].
     ].
 
     blocked ifFalse:[
@@ -461,6 +530,7 @@
     __INST(buffered) = true;
 #endif
 %}.
+    position := 1.
     hitEOF := false.
     binary := false.
     Lobby register:self.
@@ -485,6 +555,6 @@
 !PipeStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Attic/PipeStr.st,v 1.57 1997-09-20 22:10:22 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Attic/PipeStr.st,v 1.58 1997-09-22 19:05:40 cg Exp $'
 ! !
 PipeStream initialize!