github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/raw_unix.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build darwin || dragonfly || freebsd || (linux && !appengine) || netbsd || openbsd 6 // +build darwin dragonfly freebsd linux,!appengine netbsd openbsd 7 8 package readline 9 10 import ( 11 "golang.org/x/sys/unix" 12 ) 13 14 // State contains the state of a terminal. 15 type State struct { 16 termios unix.Termios 17 } 18 19 // IsTerminal returns true if the given file descriptor is a terminal. 20 func IsTerminal(fd int) bool { 21 _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) 22 return err == nil 23 } 24 25 // MakeRaw put the terminal connected to the given file descriptor into raw 26 // mode and returns the previous state of the terminal so that it can be 27 // restored. 28 func MakeRaw(fd int) (*State, error) { 29 termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) 30 if err != nil { 31 return nil, err 32 } 33 34 oldState := State{termios: *termios} 35 36 // This attempts to replicate the behaviour documented for cfmakeraw in 37 // the termios(3) manpage. 38 termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON 39 //termios.Oflag &^= unix.OPOST 40 //termios.Oflag &^= OXTABS 41 termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN 42 termios.Cflag &^= unix.CSIZE | unix.PARENB 43 termios.Cflag |= unix.CS8 44 termios.Cc[unix.VMIN] = 1 45 termios.Cc[unix.VTIME] = 0 46 if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil { 47 return nil, err 48 } 49 50 return &oldState, nil 51 } 52 53 // GetState returns the current state of a terminal which may be useful to 54 // restore the terminal after a signal. 55 func GetState(fd int) (*State, error) { 56 termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) 57 if err != nil { 58 return nil, err 59 } 60 61 return &State{termios: *termios}, nil 62 } 63 64 // Restore restores the terminal connected to the given file descriptor to a 65 // previous state. 66 func Restore(fd int, state *State) error { 67 return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios) 68 } 69 70 // GetSize returns the dimensions of the given terminal. 71 func GetSize(fd int) (width, height int, err error) { 72 ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) 73 if err != nil { 74 return -1, -1, err 75 } 76 return int(ws.Col), int(ws.Row), nil 77 }