Fix for #1874
Created subprocess.Cmd wrapper to autoclose any created pipes Removing original fix for #1860
This commit is contained in:
parent
dd19c1b9c2
commit
be73bc08dd
@ -445,10 +445,7 @@ func RecentBranches(since time.Time, includeRemoteBranches bool, onlyRemote stri
|
||||
return nil, fmt.Errorf("Failed to call git for-each-ref: %v", err)
|
||||
}
|
||||
cmd.Start()
|
||||
defer func() {
|
||||
outp.Close()
|
||||
cmd.Wait()
|
||||
}()
|
||||
defer cmd.Wait()
|
||||
|
||||
scanner := bufio.NewScanner(outp)
|
||||
|
||||
|
46
subprocess/cmd.go
Normal file
46
subprocess/cmd.go
Normal file
@ -0,0 +1,46 @@
|
||||
package subprocess
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// Thin wrapper around exec.Cmd. Takes care of pipe shutdown by
|
||||
// keeping an internal reference to any created pipes. Whenever
|
||||
// Cmd.Wait() is called, all created pipes are closed.
|
||||
type Cmd struct {
|
||||
*exec.Cmd
|
||||
|
||||
pipes []io.Closer
|
||||
}
|
||||
|
||||
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
|
||||
stdout, err := c.Cmd.StdoutPipe()
|
||||
c.pipes = append(c.pipes, stdout)
|
||||
return stdout, err
|
||||
}
|
||||
|
||||
func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
|
||||
stderr, err := c.Cmd.StderrPipe()
|
||||
c.pipes = append(c.pipes, stderr)
|
||||
return stderr, err
|
||||
}
|
||||
|
||||
func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
|
||||
stdin, err := c.Cmd.StdinPipe()
|
||||
c.pipes = append(c.pipes, stdin)
|
||||
return stdin, err
|
||||
}
|
||||
|
||||
func (c *Cmd) Wait() error {
|
||||
for _, pipe := range c.pipes {
|
||||
pipe.Close()
|
||||
}
|
||||
|
||||
return c.Cmd.Wait()
|
||||
}
|
||||
|
||||
func newCmd(cmd *exec.Cmd) *Cmd {
|
||||
wrapped := &Cmd{Cmd: cmd}
|
||||
return wrapped
|
||||
}
|
@ -7,8 +7,8 @@ import (
|
||||
)
|
||||
|
||||
// ExecCommand is a small platform specific wrapper around os/exec.Command
|
||||
func ExecCommand(name string, arg ...string) *exec.Cmd {
|
||||
func ExecCommand(name string, arg ...string) *Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.Env = env
|
||||
return cmd
|
||||
return newCmd(cmd)
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ import (
|
||||
)
|
||||
|
||||
// ExecCommand is a small platform specific wrapper around os/exec.Command
|
||||
func ExecCommand(name string, arg ...string) *exec.Cmd {
|
||||
func ExecCommand(name string, arg ...string) *Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
cmd.Env = env
|
||||
return cmd
|
||||
return newCmd(cmd)
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
@ -52,7 +51,7 @@ func (t *traceWriter) Flush() {
|
||||
|
||||
type customAdapterWorkerContext struct {
|
||||
workerNum int
|
||||
cmd *exec.Cmd
|
||||
cmd *subprocess.Cmd
|
||||
stdout io.ReadCloser
|
||||
bufferedOut *bufio.Reader
|
||||
stdin io.WriteCloser
|
||||
@ -70,7 +69,8 @@ func NewCustomAdapterInitRequest(op string, concurrent bool, concurrentTransfers
|
||||
return &customAdapterInitRequest{"init", op, concurrent, concurrentTransfers}
|
||||
}
|
||||
|
||||
type customAdapterTransferRequest struct { // common between upload/download
|
||||
type customAdapterTransferRequest struct {
|
||||
// common between upload/download
|
||||
Event string `json:"event"`
|
||||
Oid string `json:"oid"`
|
||||
Size int64 `json:"size"`
|
||||
|
Loading…
Reference in New Issue
Block a user