github.com/olljanat/moby@v1.13.1/pkg/term/tc_solaris_cgo.go (about)

     1  // +build solaris,cgo
     2  
     3  package term
     4  
     5  import (
     6  	"syscall"
     7  	"unsafe"
     8  )
     9  
    10  // #include <termios.h>
    11  import "C"
    12  
    13  // Termios is the Unix API for terminal I/O.
    14  // It is passthrough for syscall.Termios in order to make it portable with
    15  // other platforms where it is not available or handled differently.
    16  type Termios syscall.Termios
    17  
    18  // MakeRaw put the terminal connected to the given file descriptor into raw
    19  // mode and returns the previous state of the terminal so that it can be
    20  // restored.
    21  func MakeRaw(fd uintptr) (*State, error) {
    22  	var oldState State
    23  	if err := tcget(fd, &oldState.termios); err != 0 {
    24  		return nil, err
    25  	}
    26  
    27  	newState := oldState.termios
    28  
    29  	newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON | syscall.IXANY)
    30  	newState.Oflag &^= syscall.OPOST
    31  	newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
    32  	newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
    33  	newState.Cflag |= syscall.CS8
    34  
    35  	/*
    36  		VMIN is the minimum number of characters that needs to be read in non-canonical mode for it to be returned
    37  		Since VMIN is overloaded with another element in canonical mode when we switch modes it defaults to 4. It
    38  		needs to be explicitly set to 1.
    39  	*/
    40  	newState.Cc[C.VMIN] = 1
    41  	newState.Cc[C.VTIME] = 0
    42  
    43  	if err := tcset(fd, &newState); err != 0 {
    44  		return nil, err
    45  	}
    46  	return &oldState, nil
    47  }
    48  
    49  func tcget(fd uintptr, p *Termios) syscall.Errno {
    50  	ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
    51  	if ret != 0 {
    52  		return err.(syscall.Errno)
    53  	}
    54  	return 0
    55  }
    56  
    57  func tcset(fd uintptr, p *Termios) syscall.Errno {
    58  	ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
    59  	if ret != 0 {
    60  		return err.(syscall.Errno)
    61  	}
    62  	return 0
    63  }