Cleanup filedescriptor closing on #exec:withArguments:....
--- 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!