a geicko-2 based round robin ranking system designed to test c++ battleship submissions
battleship.dunkirk.sh
1//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
2// +build darwin dragonfly freebsd linux netbsd openbsd solaris
3
4package ssh
5
6import (
7 "os"
8 "os/exec"
9
10 "github.com/charmbracelet/x/termios"
11 "github.com/creack/pty"
12 "golang.org/x/crypto/ssh"
13 "golang.org/x/sys/unix"
14)
15
16type impl struct {
17 // Master is the master PTY file descriptor.
18 Master *os.File
19
20 // Slave is the slave PTY file descriptor.
21 Slave *os.File
22}
23
24func (i *impl) IsZero() bool {
25 return i.Master == nil && i.Slave == nil
26}
27
28// Name returns the name of the slave PTY.
29func (i *impl) Name() string {
30 return i.Slave.Name()
31}
32
33// Read implements ptyInterface.
34func (i *impl) Read(p []byte) (n int, err error) {
35 return i.Master.Read(p)
36}
37
38// Write implements ptyInterface.
39func (i *impl) Write(p []byte) (n int, err error) {
40 return i.Master.Write(p)
41}
42
43func (i *impl) Close() error {
44 if err := i.Master.Close(); err != nil {
45 return err
46 }
47 return i.Slave.Close()
48}
49
50func (i *impl) Resize(w int, h int) (rErr error) {
51 conn, err := i.Master.SyscallConn()
52 if err != nil {
53 return err
54 }
55
56 return conn.Control(func(fd uintptr) {
57 rErr = termios.SetWinsize(int(fd), &unix.Winsize{
58 Row: uint16(h),
59 Col: uint16(w),
60 })
61 })
62}
63
64func (i *impl) start(c *exec.Cmd) error {
65 c.Stdin, c.Stdout, c.Stderr = i.Slave, i.Slave, i.Slave
66 return c.Start()
67}
68
69func newPty(_ Context, _ string, win Window, modes ssh.TerminalModes) (_ impl, rErr error) {
70 ptm, pts, err := pty.Open()
71 if err != nil {
72 return impl{}, err
73 }
74
75 conn, err := ptm.SyscallConn()
76 if err != nil {
77 return impl{}, err
78 }
79
80 if err := conn.Control(func(fd uintptr) {
81 rErr = applyTerminalModesToFd(fd, win.Width, win.Height, modes)
82 }); err != nil {
83 return impl{}, err
84 }
85
86 return impl{Master: ptm, Slave: pts}, rErr
87}
88
89func applyTerminalModesToFd(fd uintptr, width int, height int, modes ssh.TerminalModes) error {
90 var ispeed, ospeed uint32
91 ccs := map[termios.CC]uint8{}
92 iflag := map[termios.I]bool{}
93 oflag := map[termios.O]bool{}
94 cflag := map[termios.C]bool{}
95 lflag := map[termios.L]bool{}
96
97 for op, value := range modes {
98 switch op {
99 case ssh.TTY_OP_ISPEED:
100 ispeed = value
101 case ssh.TTY_OP_OSPEED:
102 ospeed = value
103 default:
104 cc, ok := sshToCc[op]
105 if ok {
106 ccs[cc] = uint8(value)
107 continue
108 }
109 i, ok := sshToIflag[op]
110 if ok {
111 iflag[i] = value > 0
112 continue
113 }
114 o, ok := sshToOflag[op]
115 if ok {
116 oflag[o] = value > 0
117 continue
118 }
119
120 c, ok := sshToCflag[op]
121 if ok {
122 cflag[c] = value > 0
123 continue
124 }
125 l, ok := sshToLflag[op]
126 if ok {
127 lflag[l] = value > 0
128 continue
129 }
130 }
131 }
132 if err := termios.SetTermios(
133 int(fd),
134 ispeed,
135 ospeed,
136 ccs,
137 iflag,
138 oflag,
139 cflag,
140 lflag,
141 ); err != nil {
142 return err
143 }
144 return termios.SetWinsize(int(fd), &unix.Winsize{
145 Row: uint16(height),
146 Col: uint16(width),
147 })
148}
149
150var sshToCc = map[uint8]termios.CC{
151 ssh.VINTR: termios.INTR,
152 ssh.VQUIT: termios.QUIT,
153 ssh.VERASE: termios.ERASE,
154 ssh.VKILL: termios.KILL,
155 ssh.VEOF: termios.EOF,
156 ssh.VEOL: termios.EOL,
157 ssh.VEOL2: termios.EOL2,
158 ssh.VSTART: termios.START,
159 ssh.VSTOP: termios.STOP,
160 ssh.VSUSP: termios.SUSP,
161 ssh.VWERASE: termios.WERASE,
162 ssh.VREPRINT: termios.RPRNT,
163 ssh.VLNEXT: termios.LNEXT,
164 ssh.VDISCARD: termios.DISCARD,
165 ssh.VSTATUS: termios.STATUS,
166 ssh.VSWTCH: termios.SWTCH,
167 ssh.VFLUSH: termios.FLUSH,
168 ssh.VDSUSP: termios.DSUSP,
169}
170
171var sshToIflag = map[uint8]termios.I{
172 ssh.IGNPAR: termios.IGNPAR,
173 ssh.PARMRK: termios.PARMRK,
174 ssh.INPCK: termios.INPCK,
175 ssh.ISTRIP: termios.ISTRIP,
176 ssh.INLCR: termios.INLCR,
177 ssh.IGNCR: termios.IGNCR,
178 ssh.ICRNL: termios.ICRNL,
179 ssh.IUCLC: termios.IUCLC,
180 ssh.IXON: termios.IXON,
181 ssh.IXANY: termios.IXANY,
182 ssh.IXOFF: termios.IXOFF,
183 ssh.IMAXBEL: termios.IMAXBEL,
184}
185
186var sshToOflag = map[uint8]termios.O{
187 ssh.OPOST: termios.OPOST,
188 ssh.OLCUC: termios.OLCUC,
189 ssh.ONLCR: termios.ONLCR,
190 ssh.OCRNL: termios.OCRNL,
191 ssh.ONOCR: termios.ONOCR,
192 ssh.ONLRET: termios.ONLRET,
193}
194
195var sshToCflag = map[uint8]termios.C{
196 ssh.CS7: termios.CS7,
197 ssh.CS8: termios.CS8,
198 ssh.PARENB: termios.PARENB,
199 ssh.PARODD: termios.PARODD,
200}
201
202var sshToLflag = map[uint8]termios.L{
203 ssh.IUTF8: termios.IUTF8,
204 ssh.ISIG: termios.ISIG,
205 ssh.ICANON: termios.ICANON,
206 ssh.ECHO: termios.ECHO,
207 ssh.ECHOE: termios.ECHOE,
208 ssh.ECHOK: termios.ECHOK,
209 ssh.ECHONL: termios.ECHONL,
210 ssh.NOFLSH: termios.NOFLSH,
211 ssh.TOSTOP: termios.TOSTOP,
212 ssh.IEXTEN: termios.IEXTEN,
213 ssh.ECHOCTL: termios.ECHOCTL,
214 ssh.ECHOKE: termios.ECHOKE,
215 ssh.PENDIN: termios.PENDIN,
216 ssh.XCASE: termios.XCASE,
217}