Immediately close standard output of the child process

Fix #3828
This commit is contained in:
Junegunn Choi 2024-06-01 15:22:05 +09:00
parent 7c613d0d9b
commit e042143e3f
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

View File

@ -25,6 +25,7 @@ type Reader struct {
finChan chan bool finChan chan bool
mutex sync.Mutex mutex sync.Mutex
exec *exec.Cmd exec *exec.Cmd
execOut io.ReadCloser
command *string command *string
killed bool killed bool
wait bool wait bool
@ -32,7 +33,7 @@ type Reader struct {
// NewReader returns new Reader object // NewReader returns new Reader object
func NewReader(pusher func([]byte) bool, eventBox *util.EventBox, executor *util.Executor, delimNil bool, wait bool) *Reader { func NewReader(pusher func([]byte) bool, eventBox *util.EventBox, executor *util.Executor, delimNil bool, wait bool) *Reader {
return &Reader{pusher, executor, eventBox, delimNil, int32(EvtReady), make(chan bool, 1), sync.Mutex{}, nil, nil, false, wait} return &Reader{pusher, executor, eventBox, delimNil, int32(EvtReady), make(chan bool, 1), sync.Mutex{}, nil, nil, nil, false, wait}
} }
func (r *Reader) startEventPoller() { func (r *Reader) startEventPoller() {
@ -79,6 +80,7 @@ func (r *Reader) terminate() {
r.mutex.Lock() r.mutex.Lock()
r.killed = true r.killed = true
if r.exec != nil && r.exec.Process != nil { if r.exec != nil && r.exec.Process != nil {
r.execOut.Close()
util.KillCommand(r.exec) util.KillCommand(r.exec)
} else { } else {
os.Stdin.Close() os.Stdin.Close()
@ -263,16 +265,23 @@ func (r *Reader) readFromCommand(command string, environ []string) bool {
if environ != nil { if environ != nil {
r.exec.Env = environ r.exec.Env = environ
} }
out, err := r.exec.StdoutPipe()
var err error
r.execOut, err = r.exec.StdoutPipe()
if err != nil { if err != nil {
r.exec = nil
r.mutex.Unlock() r.mutex.Unlock()
return false return false
} }
err = r.exec.Start() err = r.exec.Start()
r.mutex.Unlock()
if err != nil { if err != nil {
r.exec = nil
r.mutex.Unlock()
return false return false
} }
r.feed(out)
r.mutex.Unlock()
r.feed(r.execOut)
return r.exec.Wait() == nil return r.exec.Wait() == nil
} }