0.16.0 --- the terminal is openkal's, and a disposition is accepted only where it is already in effect - #38
Merged
Merged
Conversation
…nly where it is already in effect Reported by a consumer as #36: a program that entered raw mode with tcgetattr, cfmakeraw and tcsetattr was ended by the interrupt keystroke, and the three fallbacks were closed too. * THE ioctl DISPATCHER REACHES openkal.terminal. TCGETS, TCSETS with its two draining forms, and TIOCGWINSZ are performed through kal_terminal_get_mode, kal_terminal_set_mode and kal_terminal_size. They were answered by a bare `return 0' and a refusal: TCGETS and TIOCGWINSZ reported success and wrote nothing into the caller's structure, so what cfmakeraw edited was the caller's own uninitialised stack, and TCSETS was refused with ENOTTY, so what it edited never reached the terminal. * THE MODE IS TAKEN FROM ISIG AND REPORTED FROM ALL THREE, WHICH IS DELIBERATE AND NOT A SLIP. KAL_TERM_PASS_CONTROL set means that NO keystroke is reserved, so the reading direction sets it only where ISIG, IXON and IEXTEN are all clear --- that is what the terminal is. Asking is a different question: a program clears ISIG because it wants the interrupt keystroke as data, and requiring all three before asking would make cfmakeraw work and a program that cleared ISIG alone silently do nothing. * WHAT THE STRUCTURE CARRIES THAT openkal DOES NOT NAME is stated rather than invented: the translations this environment really performs, the control characters at their agreed values, and a line speed --- because zero in that field is not "unknown" but "hang up". README records what a tcsetattr cannot change here, which is everything openkal does not name. * A SIGNAL DISPOSITION IS ACCEPTED ONLY WHERE IT IS THE ONE IN EFFECT. SIG_IGN was accepted for every signal and installed for none, so a program that asked not to be ended by the interrupt keystroke was told it had succeeded and was ended by it anyway. SIG_DFL now succeeds for every signal but SIGPIPE, SIG_IGN for SIGPIPE alone, and the enquiry reports SIG_IGN for SIGPIPE rather than a zeroed record. SIGPIPE is the one disposition that is not the default, and not by accident: openkal requires a write to a stream whose far end is gone to report the condition rather than end the program. * MEASURED, AND THE CRITERION IS A RELATION. examples/terminal is the reported program reduced to a transcript; tools/pty-keys.py runs it upon a pseudo-terminal and types at it once it is ready. The transcript above this port and the transcript of the same source above the system's own C library are compared line for line, and they agree: raw mode is entered, the interrupt keystroke arrives as the byte 0x03, the program survives it, and the terminal is left as it was found. Requires openkal 0.14.0 and the implementations that carry the new position.
…hat excludes is named The two transcripts agreed in every keystroke and every mode and differed in one byte per line: openkal's mode word carries what is TYPED at a terminal and names nothing about what is written to one, so the output post-processing this environment performs survives a tcsetattr over this port and is cleared by one over the system's own C library. README's limits table records the effect; the comparison excludes it and nothing else.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复消费者报告 #36 的全部四处,并跟随 openkal 0.14(mcpplibs/openkal#38)。
改了什么
tcsetattr被 ENOTTY 拒绝,进不了 raw modeTCSETS/TCSETSW/TCSETSF路由到kal_terminal_set_modetcgetattr返回 0 却不写调用者的结构TCGETS由kal_terminal_get_mode组装出真实的struct termiosTIOCGWINSZ返回 0 却不写kal_terminal_size回填;尺寸未知时写 0(串口本机就是这么答的),因为isatty只读这个调用的成败SIG_IGN报成功却不安装SIG_DFL对除SIGPIPE外的信号成功,SIG_IGN只对SIGPIPE成功,查询也不再一律答SIG_DFLSIGPIPE是唯一一个处置不是默认值的信号,而且不是偶然:openkal 要求对已断开的流写入报告而不是结束程序,所以底下的实现早已把它安排成不动作——程序请求忽略它,是在请求它已经拥有的东西。位的映射方向不对称
KAL_TERM_PASS_CONTROL只在ISIG、IXON、IEXTEN全清时报告,因为这个位的含义是「环境不保留任何按键」。ISIG。程序清ISIG就是想要中断键作为数据;要求三个全清才转达,会让cfmakeraw能用而「只清 ISIG」的程序静默无效——正是本报告的缺陷形状。struct termios里 openkal 不命名的字段(OPOST、线速、控制字符、VMIN/VTIME、以及 W/F 形式要求的排空)是陈述而非发明的,README 的限制表新增了一行说明改它们不会生效。要「会放弃的读」用kal_timeout_read。验证
examples/terminal是报告里的程序缩成一段可比对的 transcript,tools/pty-keys.py在 pty 里跑它并在它就绪后敲键。判据是关系而不是取值:本端口的 transcript 与同一份源码在宿主 C 库上的 transcript 逐行比对。本地实测两边完全一致:CI 新增一步做同样的比对,并先检查控制组里确实出现了
byte 0x03——否则这项比对什么也证明不了。依赖:openkal 0.14.0、openkal-linux 0.14.0、openkal-macos 0.11.0、openkal-windows 0.9.0、openkal-opensbi 0.8.0。分支名
openkal-0.14与各仓库一致。