1//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || aix || zos
2// +build darwin dragonfly freebsd linux netbsd openbsd solaris aix zos
3
4package tea
5
6import (
7 "fmt"
8 "os"
9 "os/signal"
10 "syscall"
11
12 "github.com/charmbracelet/x/term"
13)
14
15func (p *Program) initInput() (err error) {
16 // Check if input is a terminal
17 if f, ok := p.input.(term.File); ok && term.IsTerminal(f.Fd()) {
18 p.ttyInput = f
19 p.previousTtyInputState, err = term.MakeRaw(p.ttyInput.Fd())
20 if err != nil {
21 return fmt.Errorf("error entering raw mode: %w", err)
22 }
23
24 // OPTIM: We can use hard tabs and backspaces to optimize cursor
25 // movements. This is based on termios settings support and whether
26 // they exist and enabled.
27 p.checkOptimizedMovements(p.previousTtyInputState)
28 }
29
30 if f, ok := p.output.(term.File); ok && term.IsTerminal(f.Fd()) {
31 p.ttyOutput = f
32 }
33
34 return nil
35}
36
37func openInputTTY() (*os.File, error) {
38 f, err := os.Open("/dev/tty")
39 if err != nil {
40 return nil, fmt.Errorf("could not open a new TTY: %w", err)
41 }
42 return f, nil
43}
44
45const suspendSupported = true
46
47// Send SIGTSTP to the entire process group.
48func suspendProcess() {
49 c := make(chan os.Signal, 1)
50 signal.Notify(c, syscall.SIGCONT)
51 _ = syscall.Kill(0, syscall.SIGTSTP)
52 // blocks until a CONT happens...
53 <-c
54}