blob: d8ca950d873cb1837a9df392497231a0acc54bce [file] [log] [blame]
Jiri Simsad7616c92015-03-24 23:44:30 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Todd Wangaffd04d2015-04-08 10:25:35 -07005// Package internal defines common types and functions used by both tunnel
6// clients and servers.
7package internal
Jiri Simsad5aae832014-05-10 09:56:38 -07008
9import (
10 "errors"
11 "os/exec"
12 "strings"
13 "syscall"
14 "unsafe"
15
Cosmos Nicolaoue6fbf982015-06-18 16:37:19 -070016 "v.io/x/ref/internal/logger"
Jiri Simsad5aae832014-05-10 09:56:38 -070017)
18
Todd Wangaffd04d2015-04-08 10:25:35 -070019// Winsize defines the window size used by ioctl TIOCGWINSZ and TIOCSWINSZ.
Jiri Simsad5aae832014-05-10 09:56:38 -070020type Winsize struct {
21 Row uint16
22 Col uint16
23 Xpixel uint16
Jiri Simsad5aae832014-05-10 09:56:38 -070024}
25
26// SetWindowSize sets the terminal's window size.
27func SetWindowSize(fd uintptr, ws Winsize) error {
Cosmos Nicolaoue6fbf982015-06-18 16:37:19 -070028 logger.Global().Infof("Setting window size: %v", ws)
Jiri Simsad5aae832014-05-10 09:56:38 -070029 ret, _, _ := syscall.Syscall(
30 syscall.SYS_IOCTL,
31 fd,
32 uintptr(syscall.TIOCSWINSZ),
33 uintptr(unsafe.Pointer(&ws)))
34 if int(ret) == -1 {
35 return errors.New("ioctl(TIOCSWINSZ) failed")
36 }
37 return nil
38}
39
40// GetWindowSize gets the terminal's window size.
41func GetWindowSize() (*Winsize, error) {
42 ws := &Winsize{}
43 ret, _, _ := syscall.Syscall(
44 syscall.SYS_IOCTL,
45 uintptr(syscall.Stdin),
46 uintptr(syscall.TIOCGWINSZ),
47 uintptr(unsafe.Pointer(ws)))
48 if int(ret) == -1 {
49 return nil, errors.New("ioctl(TIOCGWINSZ) failed")
50 }
51 return ws, nil
52}
53
Todd Wangaffd04d2015-04-08 10:25:35 -070054// EnterRawTerminalMode uses stty to enter the terminal into raw mode; stdin is
55// unbuffered, local echo of input characters is disabled, and special signal
56// characters are disabled. Returns a string which may be passed to
57// RestoreTerminalSettings to restore to the original terminal settings.
Jiri Simsad5aae832014-05-10 09:56:38 -070058func EnterRawTerminalMode() string {
59 var savedBytes []byte
60 var err error
61 if savedBytes, err = exec.Command("stty", "-F", "/dev/tty", "-g").Output(); err != nil {
Cosmos Nicolaoue6fbf982015-06-18 16:37:19 -070062 logger.Global().Infof("Failed to save terminal settings: %q (%v)", savedBytes, err)
Jiri Simsad5aae832014-05-10 09:56:38 -070063 }
64 saved := strings.TrimSpace(string(savedBytes))
65
66 args := []string{
67 "-F", "/dev/tty",
68 // Don't buffer stdin. Read characters as they are typed.
69 "-icanon", "min", "1", "time", "0",
70 // Turn off local echo of input characters.
71 "-echo", "-echoe", "-echok", "-echonl",
72 // Disable interrupt, quit, and suspend special characters.
73 "-isig",
74 // Ignore characters with parity errors.
75 "ignpar",
76 // Disable translate newline to carriage return.
77 "-inlcr",
78 // Disable ignore carriage return.
79 "-igncr",
80 // Disable translate carriage return to newline.
81 "-icrnl",
82 // Disable flow control.
83 "-ixon", "-ixany", "-ixoff",
84 // Disable non-POSIX special characters.
85 "-iexten",
86 }
87 if out, err := exec.Command("stty", args...).CombinedOutput(); err != nil {
Cosmos Nicolaoue6fbf982015-06-18 16:37:19 -070088 logger.Global().Infof("stty failed (%v) (%q)", err, out)
Jiri Simsad5aae832014-05-10 09:56:38 -070089 }
90
91 return string(saved)
92}
93
Todd Wangaffd04d2015-04-08 10:25:35 -070094// RestoreTerminalSettings uses stty to restore the terminal to the original
95// settings, taking the saved settings returned by EnterRawTerminalMode.
Jiri Simsad5aae832014-05-10 09:56:38 -070096func RestoreTerminalSettings(saved string) {
97 args := []string{
98 "-F", "/dev/tty",
99 saved,
100 }
101 if out, err := exec.Command("stty", args...).CombinedOutput(); err != nil {
Cosmos Nicolaoue6fbf982015-06-18 16:37:19 -0700102 logger.Global().Infof("stty failed (%v) (%q)", err, out)
Jiri Simsad5aae832014-05-10 09:56:38 -0700103 }
104}