Source file src/cmd/vendor/golang.org/x/term/term_unix.go

     1  // Copyright 2019 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 aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
     6  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
     7  
     8  package term
     9  
    10  import (
    11  	"golang.org/x/sys/unix"
    12  )
    13  
    14  type state struct {
    15  	termios unix.Termios
    16  }
    17  
    18  func isTerminal(fd int) bool {
    19  	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
    20  	return err == nil
    21  }
    22  
    23  func makeRaw(fd int) (*State, error) {
    24  	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  
    29  	oldState := State{state{termios: *termios}}
    30  
    31  	// This attempts to replicate the behaviour documented for cfmakeraw in
    32  	// the termios(3) manpage.
    33  	termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
    34  	termios.Oflag &^= unix.OPOST
    35  	termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
    36  	termios.Cflag &^= unix.CSIZE | unix.PARENB
    37  	termios.Cflag |= unix.CS8
    38  	termios.Cc[unix.VMIN] = 1
    39  	termios.Cc[unix.VTIME] = 0
    40  	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, termios); err != nil {
    41  		return nil, err
    42  	}
    43  
    44  	return &oldState, nil
    45  }
    46  
    47  func getState(fd int) (*State, error) {
    48  	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	return &State{state{termios: *termios}}, nil
    54  }
    55  
    56  func restore(fd int, state *State) error {
    57  	return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios)
    58  }
    59  
    60  func getSize(fd int) (width, height int, err error) {
    61  	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
    62  	if err != nil {
    63  		return -1, -1, err
    64  	}
    65  	return int(ws.Col), int(ws.Row), nil
    66  }
    67  
    68  // passwordReader is an io.Reader that reads from a specific file descriptor.
    69  type passwordReader int
    70  
    71  func (r passwordReader) Read(buf []byte) (int, error) {
    72  	return unix.Read(int(r), buf)
    73  }
    74  
    75  func readPassword(fd int) ([]byte, error) {
    76  	termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	newState := *termios
    82  	newState.Lflag &^= unix.ECHO
    83  	newState.Lflag |= unix.ICANON | unix.ISIG
    84  	newState.Iflag |= unix.ICRNL
    85  	if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newState); err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	defer unix.IoctlSetTermios(fd, ioctlWriteTermios, termios)
    90  
    91  	return readPasswordLine(passwordReader(fd))
    92  }
    93  

View as plain text