maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

 1//go:build linux
 2// +build linux
 3
 4/*
 5Maddy Mail Server - Composable all-in-one email server.
 6Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
 7
 8This program is free software: you can redistribute it and/or modify
 9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program.  If not, see <https://www.gnu.org/licenses/>.
20*/
21
22package clitools
23
24// Copied from github.com/foxcpp/ttyprompt
25// Commit 087a574, terminal/termios.go
26
27import (
28	"errors"
29	"os"
30	"syscall"
31	"unsafe"
32)
33
34type Termios struct {
35	Iflag  uint32
36	Oflag  uint32
37	Cflag  uint32
38	Lflag  uint32
39	Cc     [20]byte
40	Ispeed uint32
41	Ospeed uint32
42}
43
44/*
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 := *termios
54
55	termios.Lflag &^= syscall.ECHO
56	termios.Lflag &^= syscall.ICANON
57	termios.Iflag &^= syscall.IXON
58	termios.Lflag &^= syscall.ISIG
59	termios.Iflag |= syscall.IUTF8
60	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, nil
65}
66
67func 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 err
71	}
72	return nil
73}
74
75func 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, err
80	}
81	return termios, nil
82}