FAQ
Reviewers: golang-dev_googlegroups.com,

Message:
Hello golang-dev@googlegroups.com (cc: golang-dev@googlegroups.com),

I'd like you to review this change to
https://code.google.com/p/go.crypto


Description:
ssh/terminal: add darwin support.

terminal contains a number of utility functions that are currently only
implemented for Linux. This change also implements them for Darwin.
However, Darwin doesn't provide two of the ioctls that Linux does:
TCGETS and TCSETS. Rather we have to use cgo to call the libc functions
that implement the same behaviour.

Please review this at https://codereview.appspot.com/7286043/

Affected files:
M ssh/terminal/util.go
A ssh/terminal/util_darwin.go
A ssh/terminal/util_linux.go


Index: ssh/terminal/util.go
===================================================================
--- a/ssh/terminal/util.go
+++ b/ssh/terminal/util.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 linux,!appengine
+// +build linux,!appengine darwin

// Package terminal provides support functions for dealing with terminals,
as
// commonly found on UNIX systems.
@@ -29,9 +29,8 @@

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
- var termios syscall.Termios
- _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
- return err == 0
+ _, err := tcgetattr(fd)
+ return err == nil
}

// MakeRaw put the terminal connected to the given file descriptor into raw
@@ -39,17 +38,17 @@
// restored.
func MakeRaw(fd int) (*State, error) {
var oldState State
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0,
0); err != 0 {
+ termios, err := tcgetattr(fd)
+ if err != nil {
return nil, err
}
+ oldState.termios = *termios

- newState := oldState.termios
- newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL |
syscall.IGNCR | syscall.IXON | syscall.IXOFF
- newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0);
err != 0 {
+ termios.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL |
syscall.IGNCR | syscall.IXON | syscall.IXOFF
+ termios.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
+ if err := tcsetattr(fd, termios); err != nil {
return nil, err
}
-
return &oldState, nil
}

@@ -57,18 +56,18 @@
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
var oldState State
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0,
0); err != 0 {
+ termios, err := tcgetattr(fd)
+ if err != nil {
return nil, err
}
-
+ oldState.termios = *termios
return &oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to
a
// previous state.
func Restore(fd int, state *State) error {
- _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
- return err
+ return tcsetattr(fd, &state.termios)
}

// GetSize returns the dimensions of the given terminal.
@@ -85,21 +84,21 @@
// is commonly used for inputting passwords and other sensitive data. The
slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
- var oldState syscall.Termios
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0);
err != 0 {
+ oldState, err := tcgetattr(fd)
+ if err != nil {
return nil, err
}

- newState := oldState
+ newState := *oldState
newState.Lflag &^= syscall.ECHO
newState.Lflag |= syscall.ICANON | syscall.ISIG
newState.Iflag |= syscall.ICRNL
- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0);
err != 0 {
+ if err := tcsetattr(fd, &newState); err != nil {
return nil, err
}

defer func() {
- syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
+ tcsetattr(fd, oldState)
}()

var buf [16]byte
Index: ssh/terminal/util_darwin.go
===================================================================
new file mode 100644
--- /dev/null
+++ b/ssh/terminal/util_darwin.go
@@ -0,0 +1,31 @@
+// 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.
+
+package terminal
+
+/*
+#include <termios.h>
+*/
+import "C"
+
+import (
+ "errors"
+ "syscall"
+ "unsafe"
+)
+
+func tcgetattr(fd int) (*syscall.Termios, error) {
+ var termios syscall.Termios
+ if C.tcgetattr(C.int(fd),
(*C.struct_termios)(unsafe.Pointer(&termios))) != 0 {
+ return nil, errors.New("terminal: tcgetattr failed")
+ }
+ return &termios, nil
+}
+
+func tcsetattr(fd int, termios *syscall.Termios) error {
+ if C.tcsetattr(C.int(fd), 0,
(*C.struct_termios)(unsafe.Pointer(termios))) != 0 {
+ return errors.New("terminal: tcsetattr failed")
+ }
+ return nil
+}
Index: ssh/terminal/util_linux.go
===================================================================
new file mode 100644
--- /dev/null
+++ b/ssh/terminal/util_linux.go
@@ -0,0 +1,29 @@
+// 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 linux,!appengine
+
+package terminal
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func tcgetattr(fd int) (*syscall.Termios, error) {
+ var termios syscall.Termios
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+ if err != 0 {
+ return nil, err
+ }
+ return &termios, nil
+}
+
+func tcsetattr(fd int, termios *syscall.Termios) error {
+ _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd),
uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(termios)), 0, 0, 0)
+ if err != 0 {
+ return err
+ }
+ return nil
+}


--

---
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Minux at Feb 2, 2013 at 8:09 pm

    On Sunday, February 3, 2013, agl wrote:
    Description:
    ssh/terminal: add darwin support.

    terminal contains a number of utility functions that are currently only
    implemented for Linux. This change also implements them for Darwin.
    However, Darwin doesn't provide two of the ioctls that Linux does:
    TCGETS and TCSETS. Rather we have to use cgo to call the libc functions
    that implement the same behaviour.
    use TIOCGETA for tcgetattr().

    --

    ---
    You received this message because you are subscribed to the Google Groups "golang-dev" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Adam Langley at Feb 2, 2013 at 8:23 pm

    On Sat, Feb 2, 2013 at 3:09 PM, minux wrote:
    use TIOCGETA for tcgetattr().
    Thanks. I wish searching had turned that up!

    CL updated.


    Cheers

    AGL

    --

    ---
    You received this message because you are subscribed to the Google Groups "golang-dev" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux Ma at Feb 2, 2013 at 8:34 pm
    code LGTM.

    i suggest rename util_darwin.go to util_bsd.go, as i think
    the all *BSD use the same constants (althrough we need to
    include Termios to syscall package for *BSD).

    https://codereview.appspot.com/7286043/

    --

    ---
    You received this message because you are subscribed to the Google Groups "golang-dev" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Adam Langley at Feb 2, 2013 at 10:28 pm

    On Sat, Feb 2, 2013 at 3:34 PM, wrote:
    i suggest rename util_darwin.go to util_bsd.go, as i think
    the all *BSD use the same constants (althrough we need to
    include Termios to syscall package for *BSD).
    You mean with a +build darwin for now? Otherwise all the BSDs will
    fail to build until their syscall has been updated, right?

    Cheers

    AGL

    --

    ---
    You received this message because you are subscribed to the Google Groups "golang-dev" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Feb 2, 2013 at 10:31 pm

    On Sun, Feb 3, 2013 at 6:28 AM, Adam Langley wrote:
    On Sat, Feb 2, 2013 at 3:34 PM, wrote:
    i suggest rename util_darwin.go to util_bsd.go, as i think
    the all *BSD use the same constants (althrough we need to
    include Termios to syscall package for *BSD).
    You mean with a +build darwin for now? Otherwise all the BSDs will
    fail to build until their syscall has been updated, right?
    yes. once we added struct Termios to syscall package for other BSDs,
    we can update the build tags.

    --

    ---
    You received this message because you are subscribed to the Google Groups "golang-dev" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-dev @
categoriesgo
postedFeb 2, '13 at 7:48p
activeFeb 2, '13 at 10:31p
posts6
users2
websitegolang.org

2 users in discussion

Adam Langley: 3 posts Minux: 3 posts

People

Translate

site design / logo © 2021 Grokbase