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