This commit is contained in:
Tamir Duberstein 2017-09-18 19:44:44 -04:00
Родитель 2b5ebb1ced
Коммит a374f1cebd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 1C1E98CC8E17BB89
3 изменённых файлов: 22 добавлений и 25 удалений

13
internal/gps/cmd.go Normal file
Просмотреть файл

@ -0,0 +1,13 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gps
func (c cmd) Args() []string {
return c.Cmd.Args
}
func (c cmd) SetDir(dir string) {
c.Cmd.Dir = dir
}

Просмотреть файл

@ -21,41 +21,33 @@ type cmd struct {
ctx context.Context ctx context.Context
// cancel is called when the graceful shutdown timeout expires. // cancel is called when the graceful shutdown timeout expires.
cancel context.CancelFunc cancel context.CancelFunc
cmd *exec.Cmd Cmd *exec.Cmd
} }
func commandContext(ctx context.Context, name string, arg ...string) cmd { func commandContext(ctx context.Context, name string, arg ...string) cmd {
// Grab the caller's context and pass a derived one to CommandContext. // Grab the caller's context and pass a derived one to CommandContext.
c := cmd{ctx: ctx} c := cmd{ctx: ctx}
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
c.cmd = exec.CommandContext(ctx, name, arg...) c.Cmd = exec.CommandContext(ctx, name, arg...)
c.cancel = cancel c.cancel = cancel
return c return c
} }
func (c cmd) Args() []string {
return c.cmd.Args
}
func (c cmd) SetDir(dir string) {
c.cmd.Dir = dir
}
// CombinedOutput is like (*os/exec.Cmd).CombinedOutput except that it // CombinedOutput is like (*os/exec.Cmd).CombinedOutput except that it
// terminates subprocesses gently (via os.Interrupt), but resorts to Kill if // terminates subprocesses gently (via os.Interrupt), but resorts to Kill if
// the subprocess fails to exit after 1 minute. // the subprocess fails to exit after 1 minute.
func (c cmd) CombinedOutput() ([]byte, error) { func (c cmd) CombinedOutput() ([]byte, error) {
// Adapted from (*os/exec.Cmd).CombinedOutput // Adapted from (*os/exec.Cmd).CombinedOutput
if c.cmd.Stdout != nil { if c.Cmd.Stdout != nil {
return nil, errors.New("exec: Stdout already set") return nil, errors.New("exec: Stdout already set")
} }
if c.cmd.Stderr != nil { if c.Cmd.Stderr != nil {
return nil, errors.New("exec: Stderr already set") return nil, errors.New("exec: Stderr already set")
} }
var b bytes.Buffer var b bytes.Buffer
c.cmd.Stdout = &b c.Cmd.Stdout = &b
c.cmd.Stderr = &b c.Cmd.Stderr = &b
if err := c.cmd.Start(); err != nil { if err := c.Cmd.Start(); err != nil {
return nil, err return nil, err
} }
@ -71,7 +63,7 @@ func (c cmd) CombinedOutput() ([]byte, error) {
go func() { go func() {
select { select {
case <-c.ctx.Done(): case <-c.ctx.Done():
if err := c.cmd.Process.Signal(os.Interrupt); err != nil { if err := c.Cmd.Process.Signal(os.Interrupt); err != nil {
// If an error comes back from attempting to signal, proceed // If an error comes back from attempting to signal, proceed
// immediately to hard kill. // immediately to hard kill.
c.cancel() c.cancel()
@ -82,7 +74,7 @@ func (c cmd) CombinedOutput() ([]byte, error) {
} }
}() }()
if err := c.cmd.Wait(); err != nil { if err := c.Cmd.Wait(); err != nil {
return nil, err return nil, err
} }
return b.Bytes(), nil return b.Bytes(), nil

Просмотреть файл

@ -16,11 +16,3 @@ type cmd struct {
func commandContext(ctx context.Context, name string, arg ...string) cmd { func commandContext(ctx context.Context, name string, arg ...string) cmd {
return cmd{Cmd: exec.CommandContext(ctx, name, arg...)} return cmd{Cmd: exec.CommandContext(ctx, name, arg...)}
} }
func (c cmd) Args() []string {
return c.Cmd.Args
}
func (c cmd) SetDir(dir string) {
c.Cmd.Dir = dir
}