mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-06 07:57:35 +00:00
Improve terminal reuse and attach
Currently attach and the editor do not share the same logic for saving and restoring the terminal, and are not suitable for nesting (when the caller wants to create something, attach, and then delete something when the attach is over). This commit moves the interrupt protection logic to a util package and supports nesting interrupt handlers.
This commit is contained in:
@@ -23,13 +23,13 @@ import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/term"
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/term"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -125,7 +125,7 @@ func (e Editor) Launch(path string) error {
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdin = os.Stdin
|
||||
glog.V(5).Infof("Opening file with editor %v", args)
|
||||
if err := withSafeTTYAndInterrupts(cmd.Run); err != nil {
|
||||
if err := (term.TTY{In: os.Stdin, TryDev: true}).Safe(cmd.Run); err != nil {
|
||||
if err, ok := err.(*exec.Error); ok {
|
||||
if err.Err == exec.ErrNotFound {
|
||||
return fmt.Errorf("unable to launch the editor %q", strings.Join(e.Args, " "))
|
||||
@@ -160,40 +160,6 @@ func (e Editor) LaunchTempFile(prefix, suffix string, r io.Reader) ([]byte, stri
|
||||
return bytes, path, err
|
||||
}
|
||||
|
||||
// withSafeTTYAndInterrupts invokes the provided function after the terminal
|
||||
// state has been stored, and then on any error or termination attempts to
|
||||
// restore the terminal state to its prior behavior. It also eats signals
|
||||
// for the duration of the function.
|
||||
func withSafeTTYAndInterrupts(fn func() error) error {
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, childSignals...)
|
||||
defer signal.Stop(ch)
|
||||
|
||||
inFd := os.Stdin.Fd()
|
||||
if !term.IsTerminal(inFd) {
|
||||
if f, err := os.Open("/dev/tty"); err == nil {
|
||||
defer f.Close()
|
||||
inFd = f.Fd()
|
||||
}
|
||||
}
|
||||
|
||||
if term.IsTerminal(inFd) {
|
||||
state, err := term.SaveState(inFd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
if _, ok := <-ch; !ok {
|
||||
return
|
||||
}
|
||||
term.RestoreTerminal(inFd, state)
|
||||
}()
|
||||
defer term.RestoreTerminal(inFd, state)
|
||||
return fn()
|
||||
}
|
||||
return fn()
|
||||
}
|
||||
|
||||
func tempFile(prefix, suffix string) (f *os.File, err error) {
|
||||
dir := os.TempDir()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user