a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
at main 4.7 kB view raw
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}