1#!/usr/bin/env -S porch -f 2-- 3-- Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org> 4-- 5-- SPDX-License-Identifier: BSD-2-Clause 6-- 7 8timeout(3) 9 10local TTYINQ_DATASIZE = 128 11local scream = string.rep("A", TTYINQ_DATASIZE - 1) 12 13local function ncanon() 14 stty("lflag", nil, tty.lflag.ICANON) 15end 16 17local function canon() 18 stty("lflag", tty.lflag.ICANON) 19end 20 21spawn("readsz", "-e") 22ncanon() 23 24-- Fill up a whole block with screaming + VEOF; when it gets recanonicalized, 25-- the next line should be pointing to the beginning of the next block. 26write(scream .. "^D") 27 28canon() 29match(scream .. "$") 30 31-- The same as above, but spilling VEOF over to the next block. 32spawn("readsz", "-e") 33ncanon() 34 35write(scream .. "A^D") 36 37canon() 38match(scream .. "A$") 39 40-- We'll do it again, except with one character spilled over to the next block 41-- before we recanonicalize. We should then have the scream, followed by a 42-- partial line containing the spill over. 43spawn("cat") 44ncanon() 45 46write(scream .. "^DZ") 47 48canon() 49match(scream .. "$") 50 51-- Sending "B^D" should give us "ZB" to make sure that we didn't lose anything 52-- at the beginning of the next block. 53 54write("B^D") 55match("^ZB$") 56 57-- Next we'll VEOF at the beginning. 58spawn("readsz", "-e") 59ncanon() 60 61write("^D") 62match("^$") 63 64-- Finally, we'll trigger recanonicalization with an empty buffer. This one is 65-- just about avoiding a panic. 66spawn("true") 67 68ncanon() 69canon() 70release() 71eof() 72 73spawn("readsz", "-c", "1") 74 75write("Test^Dfoo") 76ncanon() 77 78match("^Test\x04foo$") 79 80-- Finally, swap VEOF out with ^F; before recent changes, we would remain 81-- canonicalized at Test^D and the kernel would block on it unless a short 82-- buffer was used since VEOF would not appear within the canonicalized bit. 83spawn("readsz", "-c", 1) 84 85write("Test^DLine^F") 86stty("cc", { 87 VEOF = "^F" 88}) 89 90match("^Test\x04Line$") 91