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 <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Andrea Barisani <lcars.net@gmail.com>
Reviewed-by: Katie Hockman <katie@golang.org>
Trust: Filippo Valsorda <filippo@golang.org>
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 @@
 	"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 @@
 	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 @@
 )
 
 // State contains the state of a terminal.
-type State struct {
+type state struct {
 	termios unix.Termios
 }
 
@@ -21,10 +21,7 @@
 	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 @@
 	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 @@
 	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 @@
 import (
 	"io/ioutil"
 	"os"
+	"runtime"
 	"testing"
 
 	"golang.org/x/term"
@@ -24,3 +25,18 @@
 		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 @@
 	"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 @@
 	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 @@
 	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 @@
 	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 @@
 	"golang.org/x/sys/windows"
 )
 
-type State struct {
+type state struct {
 	mode uint32
 }
 
@@ -20,10 +20,7 @@
 	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 @@
 	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 @@
 	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 @@
 	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 {