...

Source file src/pkg/cmd/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go

     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	// +build windows
     6	
     7	// Package terminal provides support functions for dealing with terminals, as
     8	// commonly found on UNIX systems.
     9	//
    10	// Putting a terminal into raw mode is the most common requirement:
    11	//
    12	// 	oldState, err := terminal.MakeRaw(0)
    13	// 	if err != nil {
    14	// 	        panic(err)
    15	// 	}
    16	// 	defer terminal.Restore(0, oldState)
    17	package terminal
    18	
    19	import (
    20		"os"
    21	
    22		"golang.org/x/sys/windows"
    23	)
    24	
    25	type State struct {
    26		mode uint32
    27	}
    28	
    29	// IsTerminal returns whether the given file descriptor is a terminal.
    30	func IsTerminal(fd int) bool {
    31		var st uint32
    32		err := windows.GetConsoleMode(windows.Handle(fd), &st)
    33		return err == nil
    34	}
    35	
    36	// MakeRaw put the terminal connected to the given file descriptor into raw
    37	// mode and returns the previous state of the terminal so that it can be
    38	// restored.
    39	func MakeRaw(fd int) (*State, error) {
    40		var st uint32
    41		if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
    42			return nil, err
    43		}
    44		raw := st &^ (windows.ENABLE_ECHO_INPUT | windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
    45		if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil {
    46			return nil, err
    47		}
    48		return &State{st}, nil
    49	}
    50	
    51	// GetState returns the current state of a terminal which may be useful to
    52	// restore the terminal after a signal.
    53	func GetState(fd int) (*State, error) {
    54		var st uint32
    55		if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
    56			return nil, err
    57		}
    58		return &State{st}, nil
    59	}
    60	
    61	// Restore restores the terminal connected to the given file descriptor to a
    62	// previous state.
    63	func Restore(fd int, state *State) error {
    64		return windows.SetConsoleMode(windows.Handle(fd), state.mode)
    65	}
    66	
    67	// GetSize returns the visible dimensions of the given terminal.
    68	//
    69	// These dimensions don't include any scrollback buffer height.
    70	func GetSize(fd int) (width, height int, err error) {
    71		var info windows.ConsoleScreenBufferInfo
    72		if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
    73			return 0, 0, err
    74		}
    75		return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil
    76	}
    77	
    78	// ReadPassword reads a line of input from a terminal without local echo.  This
    79	// is commonly used for inputting passwords and other sensitive data. The slice
    80	// returned does not include the \n.
    81	func ReadPassword(fd int) ([]byte, error) {
    82		var st uint32
    83		if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil {
    84			return nil, err
    85		}
    86		old := st
    87	
    88		st &^= (windows.ENABLE_ECHO_INPUT)
    89		st |= (windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT | windows.ENABLE_PROCESSED_OUTPUT)
    90		if err := windows.SetConsoleMode(windows.Handle(fd), st); err != nil {
    91			return nil, err
    92		}
    93	
    94		defer windows.SetConsoleMode(windows.Handle(fd), old)
    95	
    96		var h windows.Handle
    97		p, _ := windows.GetCurrentProcess()
    98		if err := windows.DuplicateHandle(p, windows.Handle(fd), p, &h, 0, false, windows.DUPLICATE_SAME_ACCESS); err != nil {
    99			return nil, err
   100		}
   101	
   102		f := os.NewFile(uintptr(h), "stdin")
   103		defer f.Close()
   104		return readPasswordLine(f)
   105	}
   106	

View as plain text