mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-04 10:57:50 +08:00
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:
parent
4d567f406f
commit
940dc16bb1
|
@ -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) {
|
||||
|
|
32
eval/eval.go
32
eval/eval.go
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user