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  }