WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit b66f5bb

Browse files
Reset fds in stdio handler
1 parent 106ba9a commit b66f5bb

File tree

2 files changed

+50
-20
lines changed

2 files changed

+50
-20
lines changed

executable/executable.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func (e *Executable) Start(args ...string) error {
196196
e.stdioHandler.CloseDuplicatedStreamsOfChild()
197197

198198
if err != nil {
199-
e.stdioHandler.CleanupStreamsOnFailedStart()
199+
e.stdioHandler.CleanupStreamsOnStartFailure()
200200
return err
201201
}
202202

@@ -266,7 +266,7 @@ func (e *Executable) Wait() (ExecutableResult, error) {
266266
defer func() {
267267
e.ctxCancelFunc()
268268
// We finally close the FDs used by the parent
269-
e.stdioHandler.CloseParentsEndOfChildStreams()
269+
e.stdioHandler.CleanupStreamsAfterWait()
270270
e.atleastOneReadDone = false
271271
e.cmd = nil
272272
e.ctxCancelFunc = nil

executable/stdio_handler.go

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,22 @@ type stdioHandler interface {
2828
// GetStderr returns stderr on the parent's end
2929
GetStderr() io.ReadCloser
3030

31-
// Sets up child process' stdio streams
31+
// SetupStreams sets up child process' stdio streams
3232
SetupStreams(cmd *exec.Cmd) error
3333

34-
// closeStreamsOfChild closes the streams on the parent which were duplicated for the child's stdio streams
34+
// CloseStreamsOfChild closes the streams on the parent which were duplicated for the child's stdio streams
3535
CloseDuplicatedStreamsOfChild() error
3636

37-
// cleanupOnFailedStart cleans up any FDs on the parent side if *exec.cmd.Start() fails
38-
CleanupStreamsOnFailedStart() error
37+
// CleanupStreamsOnStartFailure cleans up any FDs on the parent side if *exec.cmd.Start() fails
38+
CleanupStreamsOnStartFailure() error
3939

40-
// CloseParentsEndOfChildStreams closes the parent's end of the child's stdio streams
41-
CloseParentsEndOfChildStreams() error
40+
// CleanupStreamsAfterWait closes the parent's end of the child's stdio streams
41+
CleanupStreamsAfterWait() error
4242

43-
// writeToStdinStream writes to child's stdin stream
43+
// WriteToStdinStream writes to child's stdin stream
4444
WriteToStdin(input []byte) (int, error)
4545

46-
// Sends EOF to the child's stdin stream
46+
// SendEofToStdin sends EOF to the child's stdin stream
4747
SendEofToStdin() error
4848
}
4949

@@ -52,7 +52,6 @@ type pipeStdioHandler struct {
5252
stdinPipe io.WriteCloser
5353
stdoutPipe io.ReadCloser
5454
stderrPipe io.ReadCloser
55-
wasEofSent bool
5655
}
5756

5857
func (h *pipeStdioHandler) GetStdin() io.WriteCloser {
@@ -90,20 +89,30 @@ func (h *pipeStdioHandler) CloseDuplicatedStreamsOfChild() error {
9089
return nil
9190
}
9291

93-
func (h *pipeStdioHandler) CleanupStreamsOnFailedStart() error {
92+
func (h *pipeStdioHandler) CleanupStreamsOnStartFailure() error {
9493
if err := h.stdoutPipe.Close(); err != nil {
9594
return err
9695
}
96+
h.stdoutPipe = nil
9797

9898
if err := h.stderrPipe.Close(); err != nil {
9999
return err
100100
}
101+
h.stderrPipe = nil
101102

102-
return h.stdinPipe.Close()
103+
if err := h.stdinPipe.Close(); err != nil {
104+
return err
105+
}
106+
h.stdinPipe = nil
107+
108+
return nil
103109
}
104110

105-
func (h *pipeStdioHandler) CloseParentsEndOfChildStreams() error {
106-
// No implementation; this is automatically handled by *exec.Cmd.Wait()
111+
func (h *pipeStdioHandler) CleanupStreamsAfterWait() error {
112+
// No need to close pipes; this is automatically handled by *exec.Cmd.Wait()
113+
h.stdinPipe = nil
114+
h.stdoutPipe = nil
115+
h.stderrPipe = nil
107116
return nil
108117
}
109118

@@ -116,7 +125,6 @@ func (h *pipeStdioHandler) SendEofToStdin() error {
116125
return err
117126
}
118127

119-
h.wasEofSent = true
120128
return nil
121129
}
122130

@@ -156,12 +164,23 @@ func (h *ptyStdioHandler) CloseDuplicatedStreamsOfChild() error {
156164
return h.closeSlaves()
157165
}
158166

159-
func (h *ptyStdioHandler) CleanupStreamsOnFailedStart() error {
160-
return h.closeMasters()
167+
func (h *ptyStdioHandler) CleanupStreamsOnStartFailure() error {
168+
if err := h.closeMasters(); err != nil {
169+
return err
170+
}
171+
172+
h.resetAll()
173+
return nil
161174
}
162175

163-
func (h *ptyStdioHandler) CloseParentsEndOfChildStreams() error {
164-
return h.closeMasters()
176+
func (h *ptyStdioHandler) CleanupStreamsAfterWait() error {
177+
if err := h.closeMasters(); err != nil {
178+
return err
179+
}
180+
181+
h.resetAll()
182+
183+
return nil
165184
}
166185

167186
func (h *ptyStdioHandler) WriteToStdin(input []byte) (int, error) {
@@ -174,6 +193,15 @@ func (h *ptyStdioHandler) SendEofToStdin() error {
174193
return err
175194
}
176195

196+
func (h *ptyStdioHandler) resetAll() {
197+
h.stdinMaster = nil
198+
h.stdoutMaster = nil
199+
h.stderrMaster = nil
200+
h.stdinSlave = nil
201+
h.stdoutSlave = nil
202+
h.stderrSlave = nil
203+
}
204+
177205
// openAll attempts to open all three PTY pairs.
178206
// Returns an error if any PTY fails to open, and automatically cleans up any successfully opened PTYs.
179207
func (r *ptyStdioHandler) openAll() error {
@@ -187,12 +215,14 @@ func (r *ptyStdioHandler) openAll() error {
187215
r.stdoutMaster, r.stdoutSlave, err = pty.Open()
188216
if err != nil {
189217
r.closeAll()
218+
r.resetAll()
190219
return err
191220
}
192221

193222
r.stderrMaster, r.stderrSlave, err = pty.Open()
194223
if err != nil {
195224
r.closeAll()
225+
r.resetAll()
196226
return err
197227
}
198228

0 commit comments

Comments
 (0)