From f5c789dd3221ff39d752ac54467d762de7cfbec6 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 29 Sep 2020 19:32:40 +0200 Subject: [PATCH] all: apply golang.org/wiki/TargetSpecific Also removed the obsolete appengine tag, switched _unsupported.go to negative tags, so that out-of-tree GOOSes compile out of the box, reduced use of build tags to reduce confusion, and renamed files that extend _unix.go to _unix_GOOS.go. Updates #31044 Change-Id: Ifb6f14c99713bb6a9edff630f90e9beffff3ed02 Reviewed-on: https://go-review.googlesource.com/c/term/+/258002 Run-TryBot: Filippo Valsorda TryBot-Result: Go Bot Reviewed-by: Andrea Barisani Reviewed-by: Katie Hockman Trust: Filippo Valsorda --- term.go | 38 +++++++++++++++++++++++++++++ term_linux_test.go | 24 ------------------ term_plan9.go | 23 +++++------------ term_solaris.go | 29 +++++++--------------- term_test.go | 16 ++++++++++++ term_unix.go | 30 +++++++---------------- term_aix.go => term_unix_aix.go | 0 term_bsd.go => term_unix_bsd.go | 0 term_linux.go => term_unix_linux.go | 0 term_zos.go => term_unix_zos.go | 0 term_unsupported.go | 29 +++++++++++++++++++++- term_windows.go | 29 ++++++---------------- terminal_test.go | 4 +-- 13 files changed, 115 insertions(+), 107 deletions(-) delete mode 100644 term_linux_test.go rename term_aix.go => term_unix_aix.go (100%) rename term_bsd.go => term_unix_bsd.go (100%) rename term_linux.go => term_unix_linux.go (100%) rename term_zos.go => term_unix_zos.go (100%) diff --git a/term.go b/term.go index 3e8e8dc..69931cc 100644 --- a/term.go +++ b/term.go @@ -14,7 +14,45 @@ // defer terminal.Restore(0, oldState) package term +// State contains the state of a terminal. +type State struct { + state +} + // IsTerminal returns whether the given file descriptor is a terminal. func IsTerminal(fd int) bool { return isTerminal(fd) } + +// MakeRaw puts the terminal connected to the given file descriptor into raw +// mode and returns the previous state of the terminal so that it can be +// restored. +func MakeRaw(fd int) (*State, error) { + return makeRaw(fd) +} + +// GetState returns the current state of a terminal which may be useful to +// restore the terminal after a signal. +func GetState(fd int) (*State, error) { + return getState(fd) +} + +// Restore restores the terminal connected to the given file descriptor to a +// previous state. +func Restore(fd int, oldState *State) error { + return restore(fd, oldState) +} + +// GetSize returns the visible dimensions of the given terminal. +// +// These dimensions don't include any scrollback buffer height. +func GetSize(fd int) (width, height int, err error) { + return getSize(fd) +} + +// ReadPassword reads a line of input from a terminal without local echo. This +// is commonly used for inputting passwords and other sensitive data. The slice +// returned does not include the \n. +func ReadPassword(fd int) ([]byte, error) { + return readPassword(fd) +} diff --git a/term_linux_test.go b/term_linux_test.go deleted file mode 100644 index 3931b8d..0000000 --- a/term_linux_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package term_test - -import ( - "os" - "testing" - - "golang.org/x/term" -) - -func TestIsTerminalTerm(t *testing.T) { - file, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) - if err != nil { - t.Fatal(err) - } - defer file.Close() - - if !term.IsTerminal(int(file.Fd())) { - t.Fatalf("IsTerminal unexpectedly returned false for terminal file %s", file.Name()) - } -} diff --git a/term_plan9.go b/term_plan9.go index 7582be5..21afa55 100644 --- a/term_plan9.go +++ b/term_plan9.go @@ -11,7 +11,7 @@ import ( "golang.org/x/sys/plan9" ) -type State struct{} +type state struct{} func isTerminal(fd int) bool { path, err := plan9.Fd2path(fd) @@ -21,33 +21,22 @@ func isTerminal(fd int) bool { return path == "/dev/cons" || path == "/mnt/term/dev/cons" } -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd int) (*State, error) { +func makeRaw(fd int) (*State, error) { return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) } -// GetState returns the current state of a terminal which may be useful to -// restore the terminal after a signal. -func GetState(fd int) (*State, error) { +func getState(fd int) (*State, error) { return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) } -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { +func restore(fd int, state *State) error { return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) } -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { +func getSize(fd int) (width, height int, err error) { return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) } -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd int) ([]byte, error) { +func readPassword(fd int) ([]byte, error) { return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) } diff --git a/term_solaris.go b/term_solaris.go index 052e722..b9da297 100644 --- a/term_solaris.go +++ b/term_solaris.go @@ -12,7 +12,7 @@ import ( ) // State contains the state of a terminal. -type State struct { +type state struct { termios unix.Termios } @@ -21,10 +21,7 @@ func isTerminal(fd int) bool { return err == nil } -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd int) ([]byte, error) { +func readPassword(fd int) ([]byte, error) { // see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c val, err := unix.IoctlGetTermios(fd, unix.TCGETS) if err != nil { @@ -68,17 +65,14 @@ func ReadPassword(fd int) ([]byte, error) { return ret, nil } -// MakeRaw puts the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -// see http://cr.illumos.org/~webrev/andy_js/1060/ -func MakeRaw(fd int) (*State, error) { +func makeRaw(fd int) (*State, error) { + // see http://cr.illumos.org/~webrev/andy_js/1060/ termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) if err != nil { return nil, err } - oldState := State{termios: *termios} + oldState := State{state{termios: *termios}} termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON termios.Oflag &^= unix.OPOST @@ -95,25 +89,20 @@ func MakeRaw(fd int) (*State, error) { return &oldState, nil } -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, oldState *State) error { +func restore(fd int, oldState *State) error { return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios) } -// GetState returns the current state of a terminal which may be useful to -// restore the terminal after a signal. -func GetState(fd int) (*State, error) { +func getState(fd int) (*State, error) { termios, err := unix.IoctlGetTermios(fd, unix.TCGETS) if err != nil { return nil, err } - return &State{termios: *termios}, nil + return &State{state{termios: *termios}}, nil } -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { +func getSize(fd int) (width, height int, err error) { ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) if err != nil { return 0, 0, err diff --git a/term_test.go b/term_test.go index aef6b51..ec1db03 100644 --- a/term_test.go +++ b/term_test.go @@ -7,6 +7,7 @@ package term_test import ( "io/ioutil" "os" + "runtime" "testing" "golang.org/x/term" @@ -24,3 +25,18 @@ func TestIsTerminalTempFile(t *testing.T) { t.Fatalf("IsTerminal unexpectedly returned true for temporary file %s", file.Name()) } } + +func TestIsTerminalTerm(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skipf("unknown terminal path for GOOS %v", runtime.GOOS) + } + file, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) + if err != nil { + t.Fatal(err) + } + defer file.Close() + + if !term.IsTerminal(int(file.Fd())) { + t.Fatalf("IsTerminal unexpectedly returned false for terminal file %s", file.Name()) + } +} diff --git a/term_unix.go b/term_unix.go index e0c2edb..4c60e45 100644 --- a/term_unix.go +++ b/term_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd linux,!appengine netbsd openbsd zos +// +build aix darwin dragonfly freebsd linux netbsd openbsd zos package term @@ -10,8 +10,7 @@ import ( "golang.org/x/sys/unix" ) -// State contains the state of a terminal. -type State struct { +type state struct { termios unix.Termios } @@ -20,16 +19,13 @@ func isTerminal(fd int) bool { return err == nil } -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd int) (*State, error) { +func makeRaw(fd int) (*State, error) { termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) if err != nil { return nil, err } - oldState := State{termios: *termios} + oldState := State{state{termios: *termios}} // This attempts to replicate the behaviour documented for cfmakeraw in // the termios(3) manpage. @@ -47,25 +43,20 @@ func MakeRaw(fd int) (*State, error) { return &oldState, nil } -// GetState returns the current state of a terminal which may be useful to -// restore the terminal after a signal. -func GetState(fd int) (*State, error) { +func getState(fd int) (*State, error) { termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) if err != nil { return nil, err } - return &State{termios: *termios}, nil + return &State{state{termios: *termios}}, nil } -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { +func restore(fd int, state *State) error { return unix.IoctlSetTermios(fd, ioctlWriteTermios, &state.termios) } -// GetSize returns the dimensions of the given terminal. -func GetSize(fd int) (width, height int, err error) { +func getSize(fd int) (width, height int, err error) { ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) if err != nil { return -1, -1, err @@ -80,10 +71,7 @@ func (r passwordReader) Read(buf []byte) (int, error) { return unix.Read(int(r), buf) } -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd int) ([]byte, error) { +func readPassword(fd int) ([]byte, error) { termios, err := unix.IoctlGetTermios(fd, ioctlReadTermios) if err != nil { return nil, err diff --git a/term_aix.go b/term_unix_aix.go similarity index 100% rename from term_aix.go rename to term_unix_aix.go diff --git a/term_bsd.go b/term_unix_bsd.go similarity index 100% rename from term_bsd.go rename to term_unix_bsd.go diff --git a/term_linux.go b/term_unix_linux.go similarity index 100% rename from term_linux.go rename to term_unix_linux.go diff --git a/term_zos.go b/term_unix_zos.go similarity index 100% rename from term_zos.go rename to term_unix_zos.go diff --git a/term_unsupported.go b/term_unsupported.go index 76ca931..8b5d1ba 100644 --- a/term_unsupported.go +++ b/term_unsupported.go @@ -2,10 +2,37 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build js,wasm nacl +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!zos,!windows,!solaris,!plan9 package term +import ( + "fmt" + "runtime" +) + +type state struct{} + func isTerminal(fd int) bool { return false } + +func makeRaw(fd int) (*State, error) { + return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +func getState(fd int) (*State, error) { + return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +func restore(fd int, state *State) error { + return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +func getSize(fd int) (width, height int, err error) { + return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} + +func readPassword(fd int) ([]byte, error) { + return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) +} diff --git a/term_windows.go b/term_windows.go index 17f25ad..465f560 100644 --- a/term_windows.go +++ b/term_windows.go @@ -10,7 +10,7 @@ import ( "golang.org/x/sys/windows" ) -type State struct { +type state struct { mode uint32 } @@ -20,10 +20,7 @@ func isTerminal(fd int) bool { return err == nil } -// MakeRaw put the terminal connected to the given file descriptor into raw -// mode and returns the previous state of the terminal so that it can be -// restored. -func MakeRaw(fd int) (*State, error) { +func makeRaw(fd int) (*State, error) { var st uint32 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { return nil, err @@ -32,29 +29,22 @@ func MakeRaw(fd int) (*State, error) { if err := windows.SetConsoleMode(windows.Handle(fd), raw); err != nil { return nil, err } - return &State{st}, nil + return &State{state{st}}, nil } -// GetState returns the current state of a terminal which may be useful to -// restore the terminal after a signal. -func GetState(fd int) (*State, error) { +func getState(fd int) (*State, error) { var st uint32 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { return nil, err } - return &State{st}, nil + return &State{state{st}}, nil } -// Restore restores the terminal connected to the given file descriptor to a -// previous state. -func Restore(fd int, state *State) error { +func restore(fd int, state *State) error { return windows.SetConsoleMode(windows.Handle(fd), state.mode) } -// GetSize returns the visible dimensions of the given terminal. -// -// These dimensions don't include any scrollback buffer height. -func GetSize(fd int) (width, height int, err error) { +func getSize(fd int) (width, height int, err error) { var info windows.ConsoleScreenBufferInfo if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil { return 0, 0, err @@ -62,10 +52,7 @@ func GetSize(fd int) (width, height int, err error) { return int(info.Window.Right - info.Window.Left + 1), int(info.Window.Bottom - info.Window.Top + 1), nil } -// ReadPassword reads a line of input from a terminal without local echo. This -// is commonly used for inputting passwords and other sensitive data. The slice -// returned does not include the \n. -func ReadPassword(fd int) ([]byte, error) { +func readPassword(fd int) ([]byte, error) { var st uint32 if err := windows.GetConsoleMode(windows.Handle(fd), &st); err != nil { return nil, err diff --git a/terminal_test.go b/terminal_test.go index a04ed52..ee9f6b5 100644 --- a/terminal_test.go +++ b/terminal_test.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd linux,!appengine netbsd openbsd windows plan9 solaris - package term import ( @@ -430,7 +428,7 @@ func TestOutputNewlines(t *testing.T) { term := NewTerminal(buf, ">") term.Write([]byte("1\n2\n")) - output := string(buf.Bytes()) + output := buf.String() const expected = "1\r\n2\r\n" if output != expected {