From 64f346779fbe4ba9587ec65eedd0e8373f7e29c0 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Sat, 1 Jun 2013 15:51:45 -0700 Subject: [PATCH 1/4] Remove cgo from term --- term/term.go | 12 +++++------ term/termios_linux.go | 50 +++++++++++-------------------------------- 2 files changed, 19 insertions(+), 43 deletions(-) diff --git a/term/term.go b/term/term.go index 290bf174ad..ab90a3ef73 100644 --- a/term/term.go +++ b/term/term.go @@ -8,13 +8,13 @@ import ( ) type Termios struct { - Iflag uintptr - Oflag uintptr - Cflag uintptr - Lflag uintptr + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 Cc [20]byte - Ispeed uintptr - Ospeed uintptr + Ispeed uint32 + Ospeed uint32 } const ( diff --git a/term/termios_linux.go b/term/termios_linux.go index 92f21edde2..31a10a307c 100644 --- a/term/termios_linux.go +++ b/term/termios_linux.go @@ -5,26 +5,6 @@ import ( "unsafe" ) -// #include -// #include -/* -void MakeRaw(int fd) { - struct termios t; - - // FIXME: Handle errors? - ioctl(fd, TCGETS, &t); - - t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - t.c_oflag &= ~OPOST; - t.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); - t.c_cflag &= ~(CSIZE | PARENB); - t.c_cflag |= CS8; - - ioctl(fd, TCSETS, &t); -} -*/ -import "C" - const ( getTermios = syscall.TCGETS setTermios = syscall.TCSETS @@ -35,24 +15,20 @@ const ( // restored. func MakeRaw(fd int) (*State, error) { var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(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 + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { return nil, err } - C.MakeRaw(C.int(fd)) return &oldState, nil - - // FIXME: post on goland issues this: very same as the C function bug non-working - - // newState := oldState.termios - - // newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON) - // newState.Oflag &^= OPOST - // newState.Lflag &^= (ECHO | syscall.ECHONL | ICANON | ISIG | IEXTEN) - // newState.Cflag &^= (CSIZE | syscall.PARENB) - // newState.Cflag |= CS8 - - // if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&newState))); err != 0 { - // return nil, err - // } - // return &oldState, nil } From 31eb01ae8aac22a4d768418d3cc4da6f903a8694 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Sat, 1 Jun 2013 15:55:05 -0700 Subject: [PATCH 2/4] Use uintptr instead of int for Fd --- commands.go | 4 ++-- term/term.go | 14 +++++++------- term/termios_linux.go | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/commands.go b/commands.go index 7dd835856f..977ff12839 100644 --- a/commands.go +++ b/commands.go @@ -1414,7 +1414,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.Fi return err }) - if in != nil && setRawTerminal && term.IsTerminal(int(in.Fd())) && os.Getenv("NORAW") == "" { + if in != nil && setRawTerminal && term.IsTerminal(in.Fd()) && os.Getenv("NORAW") == "" { if oldState, err := term.SetRawTerminal(); err != nil { return err } else { @@ -1433,7 +1433,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in *os.Fi return err } - if !term.IsTerminal(int(os.Stdin.Fd())) { + if !term.IsTerminal(os.Stdin.Fd()) { if err := <-sendStdin; err != nil { return err } diff --git a/term/term.go b/term/term.go index ab90a3ef73..4e29361533 100644 --- a/term/term.go +++ b/term/term.go @@ -128,21 +128,21 @@ func SetWinsize(fd uintptr, ws *Winsize) error { } // IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd int) bool { +func IsTerminal(fd uintptr) bool { var termios Termios - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&termios))) + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&termios))) return err == 0 } // Restore restores the terminal connected to the given file descriptor to a // previous state. -func Restore(fd int, state *State) error { - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios))) +func Restore(fd uintptr, state *State) error { + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios))) return err } func SetRawTerminal() (*State, error) { - oldState, err := MakeRaw(int(os.Stdin.Fd())) + oldState, err := MakeRaw(os.Stdin.Fd()) if err != nil { return nil, err } @@ -150,12 +150,12 @@ func SetRawTerminal() (*State, error) { signal.Notify(c, os.Interrupt) go func() { _ = <-c - Restore(int(os.Stdin.Fd()), oldState) + Restore(os.Stdin.Fd(), oldState) os.Exit(0) }() return oldState, err } func RestoreTerminal(state *State) { - Restore(int(os.Stdin.Fd()), state) + Restore(os.Stdin.Fd(), state) } diff --git a/term/termios_linux.go b/term/termios_linux.go index 31a10a307c..7877cb89f8 100644 --- a/term/termios_linux.go +++ b/term/termios_linux.go @@ -13,9 +13,9 @@ const ( // 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 uintptr) (*State, error) { var oldState State - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { return nil, err } @@ -27,7 +27,7 @@ func MakeRaw(fd int) (*State, error) { newState.Cflag &^= (syscall.CSIZE | syscall.PARENB) newState.Cflag |= syscall.CS8 - if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 { return nil, err } return &oldState, nil From 3cc0963ad16a5abd67aeba22cefac34a40ac70ef Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Sat, 1 Jun 2013 15:55:52 -0700 Subject: [PATCH 3/4] Remove unused constants --- term/term.go | 88 ---------------------------------------------------- 1 file changed, 88 deletions(-) diff --git a/term/term.go b/term/term.go index 4e29361533..1f3e9d36bb 100644 --- a/term/term.go +++ b/term/term.go @@ -17,94 +17,6 @@ type Termios struct { Ospeed uint32 } -const ( - // Input flags - inpck = 0x010 - istrip = 0x020 - icrnl = 0x100 - ixon = 0x200 - - // Output flags - opost = 0x1 - - // Control flags - cs8 = 0x300 - - // Local flags - icanon = 0x100 - iexten = 0x400 -) - -const ( - HUPCL = 0x4000 - ICANON = 0x100 - ICRNL = 0x100 - IEXTEN = 0x400 - BRKINT = 0x2 - CFLUSH = 0xf - CLOCAL = 0x8000 - CREAD = 0x800 - CS5 = 0x0 - CS6 = 0x100 - CS7 = 0x200 - CS8 = 0x300 - CSIZE = 0x300 - CSTART = 0x11 - CSTATUS = 0x14 - CSTOP = 0x13 - CSTOPB = 0x400 - CSUSP = 0x1a - IGNBRK = 0x1 - IGNCR = 0x80 - IGNPAR = 0x4 - IMAXBEL = 0x2000 - INLCR = 0x40 - INPCK = 0x10 - ISIG = 0x80 - ISTRIP = 0x20 - IUTF8 = 0x4000 - IXANY = 0x800 - IXOFF = 0x400 - IXON = 0x200 - NOFLSH = 0x80000000 - OCRNL = 0x10 - OFDEL = 0x20000 - OFILL = 0x80 - ONLCR = 0x2 - ONLRET = 0x40 - ONOCR = 0x20 - ONOEOT = 0x8 - OPOST = 0x1 - RENB = 0x1000 - PARMRK = 0x8 - PARODD = 0x2000 - - TOSTOP = 0x400000 - VDISCARD = 0xf - VDSUSP = 0xb - VEOF = 0x0 - VEOL = 0x1 - VEOL2 = 0x2 - VERASE = 0x3 - VINTR = 0x8 - VKILL = 0x5 - VLNEXT = 0xe - VMIN = 0x10 - VQUIT = 0x9 - VREPRINT = 0x6 - VSTART = 0xc - VSTATUS = 0x12 - VSTOP = 0xd - VSUSP = 0xa - VT0 = 0x0 - VT1 = 0x10000 - VTDLY = 0x10000 - VTIME = 0x11 - ECHO = 0x00000008 - - PENDIN = 0x20000000 -) - type State struct { termios Termios } From a70dd65964340b5c4ccedf497a2605b13e7ac8a8 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Sat, 1 Jun 2013 16:19:50 -0700 Subject: [PATCH 4/4] Move Termios struct to os specific file --- term/term.go | 10 ---------- term/termios_darwin.go | 32 +++++++++++++++++++++++++++----- term/termios_linux.go | 10 ++++++++++ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/term/term.go b/term/term.go index 1f3e9d36bb..0cc91ea1b6 100644 --- a/term/term.go +++ b/term/term.go @@ -7,16 +7,6 @@ import ( "unsafe" ) -type Termios struct { - Iflag uint32 - Oflag uint32 - Cflag uint32 - Lflag uint32 - Cc [20]byte - Ispeed uint32 - Ospeed uint32 -} - type State struct { termios Termios } diff --git a/term/termios_darwin.go b/term/termios_darwin.go index 7df54e7828..ac18aab692 100644 --- a/term/termios_darwin.go +++ b/term/termios_darwin.go @@ -8,23 +8,45 @@ import ( const ( getTermios = syscall.TIOCGETA setTermios = syscall.TIOCSETA + + ECHO = 0x00000008 + ONLCR = 0x2 + ISTRIP = 0x20 + INLCR = 0x40 + ISIG = 0x80 + IGNCR = 0x80 + ICANON = 0x100 + ICRNL = 0x100 + IXOFF = 0x400 + IXON = 0x200 ) +type Termios struct { + Iflag uint64 + Oflag uint64 + Cflag uint64 + Lflag uint64 + Cc [20]byte + Ispeed uint64 + Ospeed uint64 +} + // 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 uintptr) (*State, error) { var oldState State - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 { return nil, err } newState := oldState.termios - newState.Iflag &^= ISTRIP | INLCR | IGNCR | IXON | IXOFF + newState.Iflag &^= (ISTRIP | INLCR | IGNCR | IXON | IXOFF) newState.Iflag |= ICRNL newState.Oflag |= ONLCR - newState.Lflag &^= ECHO | ICANON | ISIG - if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(setTermios), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { + newState.Lflag &^= (ECHO | ICANON | ISIG) + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 { return nil, err } diff --git a/term/termios_linux.go b/term/termios_linux.go index 7877cb89f8..4a717c84a7 100644 --- a/term/termios_linux.go +++ b/term/termios_linux.go @@ -10,6 +10,16 @@ const ( setTermios = syscall.TCSETS ) +type Termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Cc [20]byte + Ispeed uint32 + Ospeed uint32 +} + // 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.