1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

[pkg/term] switch syscall to x/sys

Switches calls to syscall to x/sys, which is more up to date.
This is fixes a number of possible bugs on other architectures
where ioctl tcget and tcset aren't implemented correctly.

There are a few remaining syscall references, because x/sys doesn't
have an Errno implementation yet.

Also removes a ppc64le and cgo build tag that fixes building on
ppc64le without cgo

Signed-off-by: Christopher Jones <tophj@linux.vnet.ibm.com>
This commit is contained in:
Christopher Jones 2017-05-04 20:52:19 -04:00
parent 2c45392b8f
commit f30b072b81
No known key found for this signature in database
GPG key ID: 9675B4D446658DE9
16 changed files with 121 additions and 165 deletions

View file

@ -1,51 +0,0 @@
// +build linux,cgo
package term
import (
"syscall"
"unsafe"
)
// #include <termios.h>
import "C"
// Termios is the Unix API for terminal I/O.
// It is passthrough for syscall.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
type Termios syscall.Termios
// 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 uintptr) (*State, error) {
var oldState State
if err := tcget(fd, &oldState.termios); err != 0 {
return nil, err
}
newState := oldState.termios
C.cfmakeraw((*C.struct_termios)(unsafe.Pointer(&newState)))
newState.Oflag = newState.Oflag | C.OPOST
if err := tcset(fd, &newState); err != 0 {
return nil, err
}
return &oldState, nil
}
func tcget(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcgetattr(C.int(fd), (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
ret, err := C.tcsetattr(C.int(fd), C.TCSANOW, (*C.struct_termios)(unsafe.Pointer(p)))
if ret != 0 {
return err.(syscall.Errno)
}
return 0
}

View file

@ -1,6 +1,4 @@
// +build !windows
// +build !linux !cgo
// +build !linux !ppc64le
// +build !solaris !cgo
package term
@ -8,14 +6,16 @@ package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
func tcget(fd uintptr, p *Termios) syscall.Errno {
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
return err
}
func tcset(fd uintptr, p *Termios) syscall.Errno {
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
return err
}

View file

@ -5,6 +5,8 @@ package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
// #include <termios.h>
@ -13,7 +15,7 @@ import "C"
// Termios is the Unix API for terminal I/O.
// It is passthrough for syscall.Termios in order to make it portable with
// other platforms where it is not available or handled differently.
type Termios syscall.Termios
type Termios unix.Termios
// 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

View file

@ -10,7 +10,8 @@ import (
"io"
"os"
"os/signal"
"syscall"
"golang.org/x/sys/unix"
)
var (
@ -79,7 +80,7 @@ func SaveState(fd uintptr) (*State, error) {
// descriptor, with echo disabled.
func DisableEcho(fd uintptr, state *State) error {
newState := state.termios
newState.Lflag &^= syscall.ECHO
newState.Lflag &^= unix.ECHO
if err := tcset(fd, &newState); err != 0 {
return err

View file

@ -3,8 +3,9 @@
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
/*
@ -22,7 +23,7 @@ import "C"
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCGWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return ws, nil
@ -32,7 +33,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
ret, err := C.my_ioctl(C.int(fd), C.int(syscall.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
ret, err := C.my_ioctl(C.int(fd), C.int(unix.TIOCSWINSZ), (*C.struct_winsize)(unsafe.Pointer(ws)))
// Skip retval = 0
if ret == 0 {
return nil

View file

@ -3,14 +3,15 @@
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
// GetWinsize returns the window size based on the specified file descriptor.
func GetWinsize(fd uintptr) (*Winsize, error) {
ws := &Winsize{}
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
// Skipp errno = 0
if err == 0 {
return ws, nil
@ -20,7 +21,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
// SetWinsize tries to set the specified window size for the specified file descriptor.
func SetWinsize(fd uintptr, ws *Winsize) error {
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
// Skipp errno = 0
if err == 0 {
return nil

View file

@ -6,10 +6,10 @@ import (
"io"
"os"
"os/signal"
"syscall"
"github.com/Azure/go-ansiterm/winterm"
"github.com/docker/docker/pkg/term/windows"
"golang.org/x/sys/windows"
)
// State holds the console mode for the terminal.
@ -79,19 +79,19 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
}
if emulateStdin {
stdIn = windows.NewAnsiReader(syscall.STD_INPUT_HANDLE)
stdIn = windowsconsole.NewAnsiReader(windows.STD_INPUT_HANDLE)
} else {
stdIn = os.Stdin
}
if emulateStdout {
stdOut = windows.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
stdOut = windowsconsole.NewAnsiWriter(windows.STD_OUTPUT_HANDLE)
} else {
stdOut = os.Stdout
}
if emulateStderr {
stdErr = windows.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
stdErr = windowsconsole.NewAnsiWriter(windows.STD_ERROR_HANDLE)
} else {
stdErr = os.Stderr
}
@ -101,7 +101,7 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
func GetFdInfo(in interface{}) (uintptr, bool) {
return windows.GetHandleInfo(in)
return windowsconsole.GetHandleInfo(in)
}
// GetWinsize returns the window size based on the specified file descriptor.
@ -121,7 +121,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd uintptr) bool {
return windows.IsConsole(fd)
return windowsconsole.IsConsole(fd)
}
// RestoreTerminal restores the terminal connected to the given file descriptor

View file

@ -1,35 +1,36 @@
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
getTermios = unix.TIOCGETA
setTermios = unix.TIOCSETA
)
// Termios magic numbers, passthrough to the ones defined in syscall.
// Termios magic numbers, passthrough to the ones defined in unix.
const (
IGNBRK = syscall.IGNBRK
PARMRK = syscall.PARMRK
INLCR = syscall.INLCR
IGNCR = syscall.IGNCR
ECHONL = syscall.ECHONL
CSIZE = syscall.CSIZE
ICRNL = syscall.ICRNL
ISTRIP = syscall.ISTRIP
PARENB = syscall.PARENB
ECHO = syscall.ECHO
ICANON = syscall.ICANON
ISIG = syscall.ISIG
IXON = syscall.IXON
BRKINT = syscall.BRKINT
INPCK = syscall.INPCK
OPOST = syscall.OPOST
CS8 = syscall.CS8
IEXTEN = syscall.IEXTEN
IGNBRK = unix.IGNBRK
PARMRK = unix.PARMRK
INLCR = unix.INLCR
IGNCR = unix.IGNCR
ECHONL = unix.ECHONL
CSIZE = unix.CSIZE
ICRNL = unix.ICRNL
ISTRIP = unix.ISTRIP
PARENB = unix.PARENB
ECHO = unix.ECHO
ICANON = unix.ICANON
ISIG = unix.ISIG
IXON = unix.IXON
BRKINT = unix.BRKINT
INPCK = unix.INPCK
OPOST = unix.OPOST
CS8 = unix.CS8
IEXTEN = unix.IEXTEN
)
// Termios is the Unix API for terminal I/O.
@ -48,7 +49,7 @@ type Termios struct {
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
@ -58,10 +59,10 @@ func MakeRaw(fd uintptr) (*State, error) {
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
newState.Cflag &^= (CSIZE | PARENB)
newState.Cflag |= CS8
newState.Cc[syscall.VMIN] = 1
newState.Cc[syscall.VTIME] = 0
newState.Cc[unix.VMIN] = 1
newState.Cc[unix.VTIME] = 0
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}

View file

@ -1,35 +1,36 @@
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
getTermios = unix.TIOCGETA
setTermios = unix.TIOCSETA
)
// Termios magic numbers, passthrough to the ones defined in syscall.
// Termios magic numbers, passthrough to the ones defined in unix.
const (
IGNBRK = syscall.IGNBRK
PARMRK = syscall.PARMRK
INLCR = syscall.INLCR
IGNCR = syscall.IGNCR
ECHONL = syscall.ECHONL
CSIZE = syscall.CSIZE
ICRNL = syscall.ICRNL
ISTRIP = syscall.ISTRIP
PARENB = syscall.PARENB
ECHO = syscall.ECHO
ICANON = syscall.ICANON
ISIG = syscall.ISIG
IXON = syscall.IXON
BRKINT = syscall.BRKINT
INPCK = syscall.INPCK
OPOST = syscall.OPOST
CS8 = syscall.CS8
IEXTEN = syscall.IEXTEN
IGNBRK = unix.IGNBRK
PARMRK = unix.PARMRK
INLCR = unix.INLCR
IGNCR = unix.IGNCR
ECHONL = unix.ECHONL
CSIZE = unix.CSIZE
ICRNL = unix.ICRNL
ISTRIP = unix.ISTRIP
PARENB = unix.PARENB
ECHO = unix.ECHO
ICANON = unix.ICANON
ISIG = unix.ISIG
IXON = unix.IXON
BRKINT = unix.BRKINT
INPCK = unix.INPCK
OPOST = unix.OPOST
CS8 = unix.CS8
IEXTEN = unix.IEXTEN
)
// Termios is the Unix API for terminal I/O.
@ -48,7 +49,7 @@ type Termios struct {
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
@ -58,10 +59,10 @@ func MakeRaw(fd uintptr) (*State, error) {
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
newState.Cflag &^= (CSIZE | PARENB)
newState.Cflag |= CS8
newState.Cc[syscall.VMIN] = 1
newState.Cc[syscall.VTIME] = 0
newState.Cc[unix.VMIN] = 1
newState.Cc[unix.VTIME] = 0
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}

View file

@ -1,15 +1,14 @@
// +build !cgo
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
const (
getTermios = syscall.TCGETS
setTermios = syscall.TCSETS
getTermios = unix.TCGETS
setTermios = unix.TCSETS
)
// Termios is the Unix API for terminal I/O.
@ -28,19 +27,19 @@ type Termios struct {
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
newState := oldState.termios
newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
newState.Oflag |= syscall.OPOST
newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
newState.Cflag |= syscall.CS8
newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
newState.Oflag |= unix.OPOST
newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
newState.Cflag &^= (unix.CSIZE | unix.PARENB)
newState.Cflag |= unix.CS8
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}
return &oldState, nil

View file

@ -1,35 +1,36 @@
package term
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
const (
getTermios = syscall.TIOCGETA
setTermios = syscall.TIOCSETA
getTermios = unix.TIOCGETA
setTermios = unix.TIOCSETA
)
// Termios magic numbers, passthrough to the ones defined in syscall.
// Termios magic numbers, passthrough to the ones defined in unix.
const (
IGNBRK = syscall.IGNBRK
PARMRK = syscall.PARMRK
INLCR = syscall.INLCR
IGNCR = syscall.IGNCR
ECHONL = syscall.ECHONL
CSIZE = syscall.CSIZE
ICRNL = syscall.ICRNL
ISTRIP = syscall.ISTRIP
PARENB = syscall.PARENB
ECHO = syscall.ECHO
ICANON = syscall.ICANON
ISIG = syscall.ISIG
IXON = syscall.IXON
BRKINT = syscall.BRKINT
INPCK = syscall.INPCK
OPOST = syscall.OPOST
CS8 = syscall.CS8
IEXTEN = syscall.IEXTEN
IGNBRK = unix.IGNBRK
PARMRK = unix.PARMRK
INLCR = unix.INLCR
IGNCR = unix.IGNCR
ECHONL = unix.ECHONL
CSIZE = unix.CSIZE
ICRNL = unix.ICRNL
ISTRIP = unix.ISTRIP
PARENB = unix.PARENB
ECHO = unix.ECHO
ICANON = unix.ICANON
ISIG = unix.ISIG
IXON = unix.IXON
BRKINT = unix.BRKINT
INPCK = unix.INPCK
OPOST = unix.OPOST
CS8 = unix.CS8
IEXTEN = unix.IEXTEN
)
// Termios is the Unix API for terminal I/O.
@ -48,7 +49,7 @@ type Termios struct {
// restored.
func MakeRaw(fd uintptr) (*State, error) {
var oldState State
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
return nil, err
}
@ -58,10 +59,10 @@ func MakeRaw(fd uintptr) (*State, error) {
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
newState.Cflag &^= (CSIZE | PARENB)
newState.Cflag |= CS8
newState.Cc[syscall.VMIN] = 1
newState.Cc[syscall.VTIME] = 0
newState.Cc[unix.VMIN] = 1
newState.Cc[unix.VTIME] = 0
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
return nil, err
}

View file

@ -1,6 +1,6 @@
// +build windows
package windows
package windowsconsole
import (
"bytes"

View file

@ -1,6 +1,6 @@
// +build windows
package windows
package windowsconsole
import (
"io"

View file

@ -1,6 +1,6 @@
// +build windows
package windows
package windowsconsole
import (
"os"

View file

@ -2,7 +2,7 @@
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
package windows
package windowsconsole
import (
"io/ioutil"

View file

@ -1,3 +1,3 @@
// This file is necessary to pass the Docker tests.
package windows
package windowsconsole