123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
- package tui
- import (
- "errors"
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "strconv"
- "strings"
- "sync"
- "time"
- "github.com/shirou/gopsutil/v3/process"
- "golang.org/x/sys/unix"
- "kitty/tools/utils"
- )
- var _ = fmt.Print
- var TmuxExe = sync.OnceValue(func() string {
- return utils.FindExe("tmux")
- })
- func tmux_socket_address() (socket string) {
- socket = os.Getenv("TMUX")
- if socket == "" {
- return ""
- }
- addr, pid_str, found := strings.Cut(socket, ",")
- if !found {
- return ""
- }
- if unix.Access(addr, unix.R_OK|unix.W_OK) != nil {
- return ""
- }
- pid_str, _, _ = strings.Cut(pid_str, ",")
- pid, err := strconv.ParseInt(pid_str, 10, 32)
- if err != nil {
- return ""
- }
- p, err := process.NewProcess(int32(pid))
- if err != nil {
- return ""
- }
- cmd, err := p.CmdlineSlice()
- if err != nil {
- return ""
- }
- if len(cmd) > 0 && strings.ToLower(filepath.Base(cmd[0])) != "tmux" {
- return ""
- }
- return socket
- }
- var TmuxSocketAddress = sync.OnceValue(tmux_socket_address)
- func tmux_command(args ...string) (c *exec.Cmd, stderr *strings.Builder) {
- c = exec.Command(TmuxExe(), args...)
- stderr = &strings.Builder{}
- c.Stderr = stderr
- return c, stderr
- }
- func tmux_allow_passthrough() error {
- c, stderr := tmux_command("show", "-Ap", "allow-passthrough")
- allowed, not_allowed := errors.New("allowed"), errors.New("not allowed")
- get_result := make(chan error)
- go func() {
- output, err := c.Output()
- if err != nil {
- get_result <- fmt.Errorf("Running %#v failed with error: %w. STDERR: %s", c.Args, err, stderr.String())
- } else {
- q := strings.TrimSpace(utils.UnsafeBytesToString(output))
- if strings.HasSuffix(q, " on") || strings.HasSuffix(q, " all") {
- get_result <- allowed
- } else {
- get_result <- not_allowed
- }
- }
- }()
- select {
- case r := <-get_result:
- if r == allowed {
- return nil
- }
- if r != not_allowed {
- return r
- }
- c, stderr = tmux_command("set", "-p", "allow-passthrough", "on")
- err := c.Run()
- if err != nil {
- err = fmt.Errorf("Running %#v failed with error: %w. STDERR: %s", c.Args, err, stderr.String())
- }
- return err
- case <-time.After(2 * time.Second):
- return fmt.Errorf("Tmux command timed out. This often happens when the version of tmux on your PATH is older than the version of the running tmux server")
- }
- }
- var TmuxAllowPassthrough = sync.OnceValue(tmux_allow_passthrough)
|