diff options
Diffstat (limited to 'src/reader.go')
-rw-r--r-- | src/reader.go | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/src/reader.go b/src/reader.go index b418f549..dd68486c 100644 --- a/src/reader.go +++ b/src/reader.go @@ -4,6 +4,8 @@ import ( "bufio" "io" "os" + "os/exec" + "sync" "sync/atomic" "time" @@ -16,11 +18,16 @@ type Reader struct { eventBox *util.EventBox delimNil bool event int32 + finChan chan bool + mutex sync.Mutex + exec *exec.Cmd + command *string + killed bool } // NewReader returns new Reader object func NewReader(pusher func([]byte) bool, eventBox *util.EventBox, delimNil bool) *Reader { - return &Reader{pusher, eventBox, delimNil, int32(EvtReady)} + return &Reader{pusher, eventBox, delimNil, int32(EvtReady), make(chan bool, 1), sync.Mutex{}, nil, nil, false} } func (r *Reader) startEventPoller() { @@ -29,9 +36,10 @@ func (r *Reader) startEventPoller() { pollInterval := readerPollIntervalMin for { if atomic.CompareAndSwapInt32(ptr, int32(EvtReadNew), int32(EvtReady)) { - r.eventBox.Set(EvtReadNew, true) + r.eventBox.Set(EvtReadNew, (*string)(nil)) pollInterval = readerPollIntervalMin } else if atomic.LoadInt32(ptr) == int32(EvtReadFin) { + r.finChan <- true return } else { pollInterval += readerPollIntervalStep @@ -46,7 +54,35 @@ func (r *Reader) startEventPoller() { func (r *Reader) fin(success bool) { atomic.StoreInt32(&r.event, int32(EvtReadFin)) - r.eventBox.Set(EvtReadFin, success) + <-r.finChan + + r.mutex.Lock() + ret := r.command + if success || r.killed { + ret = nil + } + r.mutex.Unlock() + + r.eventBox.Set(EvtReadFin, ret) +} + +func (r *Reader) terminate() { + r.mutex.Lock() + defer func() { r.mutex.Unlock() }() + + r.killed = true + if r.exec != nil && r.exec.Process != nil { + util.KillCommand(r.exec) + } else { + os.Stdin.Close() + } +} + +func (r *Reader) restart(command string) { + r.event = int32(EvtReady) + r.startEventPoller() + success := r.readFromCommand(nil, command) + r.fin(success) } // ReadSource reads data from the default command or from standard input @@ -54,12 +90,13 @@ func (r *Reader) ReadSource() { r.startEventPoller() var success bool if util.IsTty() { + // The default command for *nix requires bash + shell := "bash" cmd := os.Getenv("FZF_DEFAULT_COMMAND") if len(cmd) == 0 { - // The default command for *nix requires bash - success = r.readFromCommand("bash", defaultCommand) + success = r.readFromCommand(&shell, defaultCommand) } else { - success = r.readFromCommand("sh", cmd) + success = r.readFromCommand(nil, cmd) } } else { success = r.readFromStdin() @@ -102,16 +139,25 @@ func (r *Reader) readFromStdin() bool { return true } -func (r *Reader) readFromCommand(shell string, cmd string) bool { - listCommand := util.ExecCommandWith(shell, cmd, false) - out, err := listCommand.StdoutPipe() +func (r *Reader) readFromCommand(shell *string, command string) bool { + r.mutex.Lock() + r.killed = false + r.command = &command + if shell != nil { + r.exec = util.ExecCommandWith(*shell, command, true) + } else { + r.exec = util.ExecCommand(command, true) + } + out, err := r.exec.StdoutPipe() if err != nil { + r.mutex.Unlock() return false } - err = listCommand.Start() + err = r.exec.Start() + r.mutex.Unlock() if err != nil { return false } r.feed(out) - return listCommand.Wait() == nil + return r.exec.Wait() == nil } |