x/ref: Add internal packages for rps and tunnel.

examples/rps/common        -> examples/rps/internal
examples/tunnel/tunnelutil -> examples/tunnel/internal

Change-Id: Ie1e721cc7b0b89a3cc2dfe3d9df892955b0f0ea4
diff --git a/examples/tunnel/internal/terminal.go b/examples/tunnel/internal/terminal.go
new file mode 100644
index 0000000..db08dba
--- /dev/null
+++ b/examples/tunnel/internal/terminal.go
@@ -0,0 +1,105 @@
+// Copyright 2015 The Vanadium 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 internal defines common types and functions used by both tunnel
+// clients and servers.
+package internal
+
+import (
+	"errors"
+	"os/exec"
+	"strings"
+	"syscall"
+	"unsafe"
+
+	"v.io/x/lib/vlog"
+)
+
+// Winsize defines the window size used by ioctl TIOCGWINSZ and TIOCSWINSZ.
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+// SetWindowSize sets the terminal's window size.
+func SetWindowSize(fd uintptr, ws Winsize) error {
+	vlog.Infof("Setting window size: %v", ws)
+	ret, _, _ := syscall.Syscall(
+		syscall.SYS_IOCTL,
+		fd,
+		uintptr(syscall.TIOCSWINSZ),
+		uintptr(unsafe.Pointer(&ws)))
+	if int(ret) == -1 {
+		return errors.New("ioctl(TIOCSWINSZ) failed")
+	}
+	return nil
+}
+
+// GetWindowSize gets the terminal's window size.
+func GetWindowSize() (*Winsize, error) {
+	ws := &Winsize{}
+	ret, _, _ := syscall.Syscall(
+		syscall.SYS_IOCTL,
+		uintptr(syscall.Stdin),
+		uintptr(syscall.TIOCGWINSZ),
+		uintptr(unsafe.Pointer(ws)))
+	if int(ret) == -1 {
+		return nil, errors.New("ioctl(TIOCGWINSZ) failed")
+	}
+	return ws, nil
+}
+
+// EnterRawTerminalMode uses stty to enter the terminal into raw mode; stdin is
+// unbuffered, local echo of input characters is disabled, and special signal
+// characters are disabled.  Returns a string which may be passed to
+// RestoreTerminalSettings to restore to the original terminal settings.
+func EnterRawTerminalMode() string {
+	var savedBytes []byte
+	var err error
+	if savedBytes, err = exec.Command("stty", "-F", "/dev/tty", "-g").Output(); err != nil {
+		vlog.Infof("Failed to save terminal settings: %q (%v)", savedBytes, err)
+	}
+	saved := strings.TrimSpace(string(savedBytes))
+
+	args := []string{
+		"-F", "/dev/tty",
+		// Don't buffer stdin. Read characters as they are typed.
+		"-icanon", "min", "1", "time", "0",
+		// Turn off local echo of input characters.
+		"-echo", "-echoe", "-echok", "-echonl",
+		// Disable interrupt, quit, and suspend special characters.
+		"-isig",
+		// Ignore characters with parity errors.
+		"ignpar",
+		// Disable translate newline to carriage return.
+		"-inlcr",
+		// Disable ignore carriage return.
+		"-igncr",
+		// Disable translate carriage return to newline.
+		"-icrnl",
+		// Disable flow control.
+		"-ixon", "-ixany", "-ixoff",
+		// Disable non-POSIX special characters.
+		"-iexten",
+	}
+	if out, err := exec.Command("stty", args...).CombinedOutput(); err != nil {
+		vlog.Infof("stty failed (%v) (%q)", err, out)
+	}
+
+	return string(saved)
+}
+
+// RestoreTerminalSettings uses stty to restore the terminal to the original
+// settings, taking the saved settings returned by EnterRawTerminalMode.
+func RestoreTerminalSettings(saved string) {
+	args := []string{
+		"-F", "/dev/tty",
+		saved,
+	}
+	if out, err := exec.Command("stty", args...).CombinedOutput(); err != nil {
+		vlog.Infof("stty failed (%v) (%q)", err, out)
+	}
+}