Cleanup filedescriptor closing on #exec:withArguments:....
authorStefan Vogel <sv@exept.de>
Thu, 27 Feb 2003 15:38:51 +0100
changeset 2449 b16aece32285
parent 2448 6d912d8ec69d
child 2450 ac2ab4cbfb79
Cleanup filedescriptor closing on #exec:withArguments:....
TerminalView.st
--- a/TerminalView.st	Wed Feb 26 15:49:51 2003 +0100
+++ b/TerminalView.st	Thu Feb 27 15:38:51 2003 +0100
@@ -946,7 +946,7 @@
      Also fork a reader process, to read the shells output and
      tell me, whenever something arrives"
 
-    |p slaveFD execFdArray closeFdArray blocked exitStatus 
+    |pty slaveFD execFdArray blocked exitStatus 
      stxToCommandPipe commandToStxPipe cmd shell args env shellAndArgs|
 
     shellCommand := aCommand.
@@ -955,62 +955,52 @@
     self create.  "/ need my windowID (to pass down in environment)
 
     OperatingSystem isMSWINDOWSlike ifTrue:[
-        "/ must use another mechanism
-
-        stxToCommandPipe := OperatingSystem makePipe.
-        (stxToCommandPipe isNil
-        or:[(stxToCommandPipe at:2) < 0
-        or:[(stxToCommandPipe at:2) < 0]]) ifTrue:[
+        "use two pipes to COMMAND.COM"
+        stxToCommandPipe := ExternalStream makePipe.
+        stxToCommandPipe isNil ifTrue:[
             ^ self warn:'Could not create pipe to COMMAND.COM.'.
         ].
 
-        commandToStxPipe := OperatingSystem makePipe.
-        (commandToStxPipe isNil 
-        or:[(commandToStxPipe at:2) < 0
-        or:[(commandToStxPipe at:2) < 0]]) ifTrue:[
+        commandToStxPipe := ExternalStream makePipe.
+        commandToStxPipe isNil ifTrue:[
             ^ self warn:'Could not create pipe from COMMAND.COM.'.
         ].
 
-        shellAndArgs := OperatingSystem commandAndArgsForOSCommand:aCommand.
-        shell := shellAndArgs at:1.
-        args  := (shellAndArgs at:2) ? ''.
-
         "/ pipe readSide is p at:1;
         "/      writeSide is p at:2
 
+        slaveFD := (commandToStxPipe at:2) fileDescriptor.
         execFdArray := Array 
-                         with:(stxToCommandPipe at:1)
-                         with:(commandToStxPipe at:2)
-                         with:(commandToStxPipe at:2).
+                         with:(stxToCommandPipe at:1) fileDescriptor        "stdin"
+                         with:slaveFD                                       "stdout"
+                         with:slaveFD.                                      "stderr"
 
-        closeFdArray := #(). 
-
-        outStream := ExternalStream forReadingFromFileDescriptor:(commandToStxPipe at:1).
-        inStream := ExternalStream forWritingToFileDescriptor:(stxToCommandPipe at:2).
+        outStream := commandToStxPipe at:1.
+        inStream  := stxToCommandPipe at:2.
         outStream buffered:false.
         inStream buffered:false.
+
+        shellAndArgs := OperatingSystem commandAndArgsForOSCommand:aCommand.
+        shell := shellAndArgs at:1.
+        args  := (shellAndArgs at:2) ? ''.
     ] ifFalse:[
-        p := ExternalStream makePTYPair.
-        p isNil ifTrue:[
+        "Use a pseudo-tty"
+        pty := ExternalStream makePTYPair.
+        pty isNil ifTrue:[
             self warn:'Cannot open pty.'.
             ^ self.
         ].
 
-        "/ p at:1 is the master;
-        "/ p at:2 is the slave
-        inStream := outStream := (p at:1).
+        "/ pty at:1 is the master;
+        "/ pty at:2 is the slave
+        inStream := outStream := (pty at:1).
         inStream buffered:false.
 
         self defineWindowSize.
         "/ fork a shell process on the slave-side
-        slaveFD := (p at:2) fileDescriptor.
+        slaveFD := (pty at:2) fileDescriptor.
         execFdArray := Array with:slaveFD with:slaveFD with:slaveFD.
 
-        "have to close unused filedescriptors.
-         Otherwise, listening sockets may be inherited by child processes"
-
-        closeFdArray := 3 to:OperatingSystem maxNumberOfOpenFiles-1. "close anything but stdin, stdout, stderr"
-        
         aCommand isNil ifTrue:[
             shell := OperatingSystem getEnvironment:'SHELL'.
             shell size == 0 ifTrue:[
@@ -1022,43 +1012,28 @@
             shell := '/bin/sh'.
             args := (Array with:'sh' with:'-c' with:aCommand).
         ].
+        env := Dictionary new.
+        env at:'SHELL'    put:shell.
+        env at:'TERM'     put:(self terminalType).
+        env at:'LINES'    put:(numberOfLines printString).
+        env at:'COLUMNS'  put:(numberOfColumns printString).
+        (device platformName = 'X11' and:[drawableId notNil]) ifTrue:[
+            env at:'WINDOWID' put:(drawableId address printString).
+        ].
     ].
 
     blocked := OperatingSystem blockInterrupts.
 
     shellPid := Processor
                monitor:[
-                  OperatingSystem isMSWINDOWSlike ifTrue:[
-                      OperatingSystem
-                          exec:shell
-                          withArguments:args
-                          fileDescriptors:execFdArray
-                          closeDescriptors:closeFdArray
-                          fork:true
-                          newPgrp:true
-                          inDirectory:aDirectory.
-                  ] ifFalse:[
-                      env := Dictionary new.
-                      env at:'TERM'     put:(self terminalType).
-                      env at:'LINES'    put:(numberOfLines printString).
-                      env at:'COLUMNS'  put:(numberOfColumns printString).
-                      device platformName = 'X11' ifTrue:[  
-                          drawableId notNil ifTrue:[
-                              env at:'WINDOWID' put:(drawableId address printString).
-                          ].
-                      ].
-                      env at:'SHELL'  put:shell.
-
-                      OperatingSystem
-                          exec:shell
-                          withArguments:args
-                          environment:env
-                          fileDescriptors:execFdArray
-                          closeDescriptors:closeFdArray
-                          fork:true
-                          newPgrp:true
-                          inDirectory:aDirectory.
-                  ]
+                  OperatingSystem
+                      exec:shell
+                      withArguments:args
+                      environment:env
+                      fileDescriptors:execFdArray
+                      fork:true
+                      newPgrp:true
+                      inDirectory:aDirectory.
                ]
                action:[:status |
                     Debug ifTrue:[
@@ -1079,12 +1054,22 @@
         OperatingSystem unblockInterrupts
     ].
 
+    "close the slave side of the pty/pipes (only used by the child)"
+    pty notNil ifTrue:[
+        (pty at:2) close.
+    ].
+
+    commandToStxPipe notNil ifTrue:[
+        (commandToStxPipe at:2) close.
+        (stxToCommandPipe at:1) close.
+    ].
+
     shellPid isNil ifTrue:[
         self warn:'Cannot start shell'.
-        p notNil ifTrue:[
-            (p at:1) close.
-            (p at:2) close.
-        ]
+        outStream close.
+        inStream close.
+        inStream := outStream := nil.
+        ^ self.
     ].
 
     self startReaderProcess.
@@ -1833,7 +1818,7 @@
 !TerminalView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.110 2003-02-26 14:49:51 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/TerminalView.st,v 1.111 2003-02-27 14:38:51 stefan Exp $'
 ! !
 
 TerminalView initialize!