On Thu, Oct 26, 2023 at 9:03 PM Theo de Raadt <[email protected]> wrote:
> > Crystal Kolipe <[email protected]> wrote: > > > On Thu, Oct 26, 2023 at 12:20:08PM -0400, Morgan Aldridge wrote: > > > Yes, your assumption was correct, every keypress acts as if I had > pressed > > > enter. Thanks for confirming! > > > > Getty re-displays the login prompt when it sees either 0x00 or 0x80 on > the > > serial line. In fact, you can do it from the normal framebuffer console > too, > > just hit control-@ at the login prompt and it should repeat. > > > > (This is a historic behaviour which was once used for semi-automatic > baud rate > > selection where you hit 'BREAK' a few times to get the remote end to > cycle > > through all the speeds it supported until you, (hopefully), got a login > > prompt). > > > > So in your case, it seems that either the terminal is putting something > on the > > serial data lines that the USB serial adaptor is interpreting as nulls, > or > > possibly it's doing something with the handshaking lines that makes the > > USB serial adaptor generate the equivalent internally. > > > > Any extra nulls added as padding bytes probably wouldn't show up in the > > loopback test either, because the terminal would just happily ignore > them. > > ktrace -di of the process will show what is going on > Thank you both! Confirmed with `ktrace -di -g $(pgrep -f "getty std.9600 ttyU")` and pressing a single character ('l'; a lower-case el... in hindsight, I should have used a more recognizable character) on the connected terminal: 14294 getty CALL read(0,0x78e711dd4246,0x1) 14294 getty GIO fd 0 read 1 bytes "\0" 14294 getty RET read 1 So, yeah, there's the null being received. The 'l' never is, but that jives with what you've described regarding getty(8). I disabled getty(8) on ttyU1, ran `cu -dr -l ttyU1 -s 9600`, then `ktrace -di -g $(pgrep -f "cu -dr -l ttyU")`, and again pressed a single character ('l' again) on the connected terminal: 62099 cu CALL read(3,0x2f26a7f400,0x2) 62099 cu GIO fd 3 read 2 bytes "\0l" 62099 cu RET read 2 Confirmed: there's the null being received before the 'l'. As you mentioned was likely, cu(1) just ignores the null byte. Performing the same cu(1) & ktrace(1) test with the TX/RX pins shorted and pressing a single character ('l' again) in cu(1): 72982 cu CALL write(3,0xbf9b0baf900,0x1) 72982 cu GIO fd 3 wrote 1 bytes "l" 72982 cu RET write 1 72982 cu CALL kevent(4,0,0,0xbf9b0b8d000,64,0) 72982 cu STRU struct kevent { ident=3, filter=EVFILT_READ, flags=0x11<EV_ADD|EV_ONESHOT>, fflags=0<>, data=2, udata=0xbf9b0bb3c08 } 72982 cu RET kevent 1 72982 cu CALL ioctl(3,FIONREAD,0x74351e9ae74c) 72982 cu RET ioctl 0 72982 cu CALL read(3,0xbf9b0babd00,0x2) 72982 cu GIO fd 3 read 2 bytes "\0l" 72982 cu RET read 2 So, there it is, a single 'l' is written, but a null is read prior to the 'l'. So, it's the Keyspan/Tripp-Lite USA-19HS which is adding the null byte. Again, I suspect the lack of flow-control implementation in ukspan(4) is the culprit. This weekend I'll do some more analysis with ktrace(1), especially loopback tests with flow control lines shorted. I'll use my findings to work on updating ukspan(4)'s ukspan_param() to handle flow control related c_cflag masks such as CLOCAL, CCTS_OFLOW, CRTS_IFLOW, and MDMBUF, as described in termios(4). Morgan

