term: add IsTerminal function

Extracted from golang.org/x/crypto/ssh/terminal

The implementation for plan9 is based on IsTerminal from
github.com/mattn/go-isatty

Change-Id: Id7bf2d6595639ff08e5fd5f786a145d340bbed08
Reviewed-on: https://go-review.googlesource.com/c/term/+/200681
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Tobias Klauser
2019-10-14 11:17:45 +02:00
committed by Tobias Klauser
parent 4b5627afda
commit c3296ef303
13 changed files with 183 additions and 9 deletions

View File

@@ -1,9 +0,0 @@
// Copyright 2016 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.
// Temporary file to make the builders happy so there's
// something buildable in this repo. This can be deleted
// when other code is added here.
package builders_test

2
go.mod
View File

@@ -1,3 +1,5 @@
module golang.org/x/term
go 1.11
require golang.org/x/sys v0.0.0-20191010194322-b09406accb47

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

12
term.go Normal file
View File

@@ -0,0 +1,12 @@
// 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 provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
package term
// IsTerminal returns whether the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
return isTerminal(fd)
}

11
term_aix.go Normal file
View File

@@ -0,0 +1,11 @@
// 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
import (
"golang.org/x/sys/unix"
)
const ioctlReadTermios = unix.TCGETS

13
term_bsd.go Normal file
View File

@@ -0,0 +1,13 @@
// Copyright 2013 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.
// +build darwin dragonfly freebsd netbsd openbsd
package term
import (
"golang.org/x/sys/unix"
)
const ioctlReadTermios = unix.TIOCGETA

11
term_linux.go Normal file
View File

@@ -0,0 +1,11 @@
// 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
import (
"golang.org/x/sys/unix"
)
const ioctlReadTermios = unix.TCGETS

42
term_linux_test.go Normal file
View File

@@ -0,0 +1,42 @@
// 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 (
"io/ioutil"
"os"
"path/filepath"
"testing"
"golang.org/x/sys/unix"
"golang.org/x/term"
)
func TestIsTerminalTerm(t *testing.T) {
dir, err := ioutil.TempDir("", "TestIsTerminalTerm")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
tty := filepath.Join(dir, "tty")
err = unix.Mknod(tty, unix.S_IFCHR, int(unix.Mkdev(5, 0)))
if err == unix.EPERM {
t.Skip("no permission to create terminal file, skipping test")
} else if err != nil {
t.Fatal(err)
}
file, err := os.Open(tty)
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())
}
}

17
term_plan9.go Normal file
View File

@@ -0,0 +1,17 @@
// 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
import (
"golang.org/x/sys/plan9"
)
func isTerminal(fd int) bool {
path, err := plan9.Fd2path(fd)
if err != nil {
return false
}
return path == "/dev/cons" || path == "/mnt/term/dev/cons"
}

16
term_solaris.go Normal file
View File

@@ -0,0 +1,16 @@
// 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.
// +build aix darwin dragonfly freebsd linux netbsd openbsd
package term
import (
"golang.org/x/sys/unix"
)
func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
return err == nil
}

26
term_test.go Normal file
View File

@@ -0,0 +1,26 @@
// 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 (
"io/ioutil"
"os"
"testing"
"golang.org/x/term"
)
func TestIsTerminalTempFile(t *testing.T) {
file, err := ioutil.TempFile("", "TestIsTerminalTempFile")
if err != nil {
t.Fatal(err)
}
defer os.Remove(file.Name())
defer file.Close()
if term.IsTerminal(int(file.Fd())) {
t.Fatalf("IsTerminal unexpectedly returned true for temporary file %s", file.Name())
}
}

16
term_unix.go Normal file
View File

@@ -0,0 +1,16 @@
// 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.
// +build aix darwin dragonfly freebsd linux netbsd openbsd
package term
import (
"golang.org/x/sys/unix"
)
func isTerminal(fd int) bool {
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
return err == nil
}

15
term_windows.go Normal file
View File

@@ -0,0 +1,15 @@
// 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
import (
"golang.org/x/sys/windows"
)
func isTerminal(fd int) bool {
var st uint32
err := windows.GetConsoleMode(windows.Handle(fd), &st)
return err == nil
}