1//go:build linux2// +build linux34/*5Maddy Mail Server - Composable all-in-one email server.6Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors78This program is free software: you can redistribute it and/or modify9it under the terms of the GNU General Public License as published by10the Free Software Foundation, either version 3 of the License, or11(at your option) any later version.1213This program is distributed in the hope that it will be useful,14but WITHOUT ANY WARRANTY; without even the implied warranty of15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16GNU General Public License for more details.1718You should have received a copy of the GNU General Public License19along with this program. If not, see <https://www.gnu.org/licenses/>.20*/2122package clitools2324// Copied from github.com/foxcpp/ttyprompt25// Commit 087a574, terminal/termios.go2627import (28 "errors"29 "os"30 "syscall"31 "unsafe"32)3334type Termios struct {35 Iflag uint3236 Oflag uint3237 Cflag uint3238 Lflag uint3239 Cc [20]byte40 Ispeed uint3241 Ospeed uint3242}4344/*45TurnOnRawIO sets flags suitable for raw I/O (no echo, per-character input, etc)46and returns original flags.47*/48func TurnOnRawIO(tty *os.File) (orig Termios, err error) {49 termios, err := TcGetAttr(tty.Fd())50 if err != nil {51 return Termios{}, errors.New("TurnOnRawIO: failed to get flags: " + err.Error())52 }53 termiosOrig := *termios5455 termios.Lflag &^= syscall.ECHO56 termios.Lflag &^= syscall.ICANON57 termios.Iflag &^= syscall.IXON58 termios.Lflag &^= syscall.ISIG59 termios.Iflag |= syscall.IUTF860 err = TcSetAttr(tty.Fd(), termios)61 if err != nil {62 return Termios{}, errors.New("TurnOnRawIO: flags to set flags: " + err.Error())63 }64 return termiosOrig, nil65}6667func TcSetAttr(fd uintptr, termios *Termios) error {68 _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCSETS, uintptr(unsafe.Pointer(termios)))69 if err != 0 {70 return err71 }72 return nil73}7475func TcGetAttr(fd uintptr) (*Termios, error) {76 termios := &Termios{}77 _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios)))78 if err != 0 {79 return nil, err80 }81 return termios, nil82}