github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/readline/raw_solaris.go (about)

     1  // Copyright 2015 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 solaris
     6  // +build solaris
     7  
     8  package readline
     9  
    10  import (
    11  	"syscall"
    12  
    13  	"golang.org/x/sys/unix"
    14  )
    15  
    16  // State contains the state of a terminal.
    17  type State struct {
    18  	state *unix.Termios
    19  }
    20  
    21  // IsTerminal returns true if the given file descriptor is a terminal.
    22  func IsTerminal(fd int) bool {
    23  	_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
    24  	return err == nil
    25  }
    26  
    27  // MakeRaw puts the terminal connected to the given file descriptor into raw
    28  // mode and returns the previous state of the terminal so that it can be
    29  // restored.
    30  // see http://cr.illumos.org/~webrev/andy_js/1060/
    31  func MakeRaw(fd int) (*State, error) {
    32  	oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	oldTermios := *oldTermiosPtr
    37  
    38  	newTermios := oldTermios
    39  	newTermios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
    40  	//newTermios.Oflag &^= syscall.OPOST
    41  	newTermios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
    42  	newTermios.Cflag &^= syscall.CSIZE | syscall.PARENB
    43  	newTermios.Cflag |= syscall.CS8
    44  	newTermios.Cc[unix.VMIN] = 1
    45  	newTermios.Cc[unix.VTIME] = 0
    46  
    47  	if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	return &State{
    52  		state: oldTermiosPtr,
    53  	}, nil
    54  }
    55  
    56  // Restore restores the terminal connected to the given file descriptor to a
    57  // previous state.
    58  func Restore(fd int, oldState *State) error {
    59  	return unix.IoctlSetTermios(fd, unix.TCSETS, oldState.state)
    60  }
    61  
    62  // GetState returns the current state of a terminal which may be useful to
    63  // restore the terminal after a signal.
    64  func GetState(fd int) (*State, error) {
    65  	oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	return &State{
    71  		state: oldTermiosPtr,
    72  	}, nil
    73  }
    74  
    75  // GetSize returns the dimensions of the given terminal.
    76  func GetSize(fd int) (width, height int, err error) {
    77  	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
    78  	if err != nil {
    79  		return 0, 0, err
    80  	}
    81  	return int(ws.Col), int(ws.Row), nil
    82  }