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)
|
return nil, fmt.Errorf("Failed to call git for-each-ref: %v", err)
|
||||||
}
|
}
|
||||||
cmd.Start()
|
cmd.Start()
|
||||||
defer func() {
|
defer cmd.Wait()
|
||||||
outp.Close()
|
|
||||||
cmd.Wait()
|
|
||||||
}()
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(outp)
|
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
|
// 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 := exec.Command(name, arg...)
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
return cmd
|
return newCmd(cmd)
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ExecCommand is a small platform specific wrapper around os/exec.Command
|
// 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 := exec.Command(name, arg...)
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
return cmd
|
return newCmd(cmd)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@ -52,7 +51,7 @@ func (t *traceWriter) Flush() {
|
|||||||
|
|
||||||
type customAdapterWorkerContext struct {
|
type customAdapterWorkerContext struct {
|
||||||
workerNum int
|
workerNum int
|
||||||
cmd *exec.Cmd
|
cmd *subprocess.Cmd
|
||||||
stdout io.ReadCloser
|
stdout io.ReadCloser
|
||||||
bufferedOut *bufio.Reader
|
bufferedOut *bufio.Reader
|
||||||
stdin io.WriteCloser
|
stdin io.WriteCloser
|
||||||
@ -70,7 +69,8 @@ func NewCustomAdapterInitRequest(op string, concurrent bool, concurrentTransfers
|
|||||||
return &customAdapterInitRequest{"init", op, concurrent, 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"`
|
Event string `json:"event"`
|
||||||
Oid string `json:"oid"`
|
Oid string `json:"oid"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
|
Loading…
Reference in New Issue
Block a user