Try to respond to signals sent to elvish-stub.

Doesn't always work, but the behavior is consistent in a session (if it works,
then it works in this session; vice versa). Likely some race in startup code.
This commit is contained in:
Qi Xiao 2016-02-22 17:39:03 +01:00
parent 4d567f406f
commit 940dc16bb1
3 changed files with 41 additions and 5 deletions

View File

@ -109,6 +109,7 @@ var (
ErrStoreNotConnected = errors.New("store not connected")
ErrNoMatchingDir = errors.New("no matching directory")
ErrNotInSameGroup = errors.New("not in the same process group")
ErrInterrupted = errors.New("interrupted")
)
var (
@ -638,7 +639,12 @@ func fg(ec *EvalCtx, pids ...int) {
}
func _sleep(ec *EvalCtx, t float64) {
time.Sleep(time.Duration(t) * time.Second)
d := time.Duration(float64(time.Second) * t)
select {
case <-ec.intCh:
throw(ErrInterrupted)
case <-time.After(d):
}
}
func _stack(ec *EvalCtx) {

View File

@ -36,6 +36,7 @@ type Evaler struct {
modules map[string]Namespace
store *store.Store
Stub *stub.Stub
intCh <-chan struct{}
}
// EvalCtx maintains an Evaler along with its runtime context. After creation
@ -56,7 +57,7 @@ func (ec *EvalCtx) evaling(n parse.Node) {
// NewEvaler creates a new Evaler.
func NewEvaler(st *store.Store) *Evaler {
ev := &Evaler{nil, map[string]Namespace{}, st, nil}
ev := &Evaler{nil, map[string]Namespace{}, st, nil, nil}
// Construct initial global namespace
pid := String(strconv.Itoa(syscall.Getpid()))
@ -180,6 +181,35 @@ func (ev *Evaler) EvalInteractive(text string, n *parse.Chunk) error {
if err != nil {
fmt.Println("failed to put stub in foreground:", err)
}
intCh := make(chan struct{})
cancelCh := make(chan struct{})
exhaustSigs:
for {
select {
case <-ev.Stub.Signals():
default:
break exhaustSigs
}
}
go func() {
sigch := ev.Stub.Signals()
for {
select {
case sig := <-sigch:
fmt.Println(sig)
if sig == syscall.SIGINT {
close(intCh)
return
}
case <-cancelCh:
return
}
}
}()
defer close(cancelCh)
ev.intCh = intCh
defer func() { ev.intCh = nil }()
}
err := ev.Eval("[interactive]", text, n, ports)

View File

@ -116,10 +116,10 @@ func relaySignals(reader io.Reader, sigch chan<- os.Signal) {
var signum int
_, err := fmt.Fscanf(reader, "%d", &signum)
if err != nil {
// XXX Swallow error.
return
sigch <- BadSignal{err}
} else {
sigch <- syscall.Signal(signum)
}
sigch <- syscall.Signal(signum)
}
}