github.com/searKing/golang/go@v1.2.117/os/exec/exec.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package exec 6 7 import ( 8 "context" 9 "io" 10 "os" 11 "os/exec" 12 ) 13 14 type commandServer struct { 15 cmd *exec.Cmd 16 handle func(reader io.Reader) 17 ctx context.Context 18 done context.CancelFunc 19 } 20 21 func newCommandServer(parent context.Context, stop context.CancelFunc, handle func(reader io.Reader), name string, args ...string) (*commandServer, error) { 22 if parent == nil { 23 parent = context.Background() 24 } 25 if stop == nil { 26 stop = func() {} 27 } 28 if handle == nil { 29 handle = func(reader io.Reader) {} 30 } 31 32 cs := &commandServer{ 33 cmd: exec.Command(name, args...), 34 handle: handle, 35 ctx: parent, 36 done: stop, 37 } 38 39 r, err := cs.cmd.StdoutPipe() 40 if err != nil { 41 cs.Stop() 42 return nil, err 43 } 44 go cs.watch(r) 45 return cs, nil 46 } 47 48 func (cs *commandServer) wait() error { 49 select { 50 case <-cs.ctx.Done(): 51 return cs.ctx.Err() 52 } 53 return nil 54 } 55 56 func (cs *commandServer) watch(r io.Reader) { 57 cs.handle(r) 58 cs.cmd.Wait() 59 cs.done() 60 } 61 func (cs *commandServer) Stop() { 62 cs.cmd.Process.Signal(os.Interrupt) 63 cs.done() 64 }