我最近购买了一个旧的 Heathkit 哑终端,我想让它与 colemak 键盘布局一起使用。因为终端直接通过串行发送 ascii 代码,所以我不相信类似的东西loadkeys
会起作用。 (如果有是我很想知道更改布局的简单解决方案。)
我当前的计划是过滤在一个简单的软件中接收或传输的每个字节。还有一些命令行程序仍然使用不兼容的转义码(尽管TERM
设置正确),我也想手动过滤掉它们。
本质上,我想创建一个位于agetty 和终端之间的程序,并允许我在发送或接收字节时手动过滤字节。
字节过滤非常简单,但我不确定如何创建一个可以做到这一点的agetty 接口。我需要使用创建自己的设备吗mknod
?
(我还考虑过使用位于终端和 Linux 机器之间的微控制器或树莓派来读取字节并写出新字节。这个解决方案会很笨拙,如果可能的话我想避免它。)
任何关于在哪里查看/阅读的建议都会非常有帮助。
答案1
一些“哑”终端有一个内置的设置菜单,有点像终端的“BIOS 设置”。这些设置通常包括键盘布局的选择。但Heathkit 终端(哪个模型?)可能太老派了。即使终端具有切换键盘布局的机制,它也不太可能提供 Colemak 布局,因为该布局是在 2006 年左右开发的。
agetty
- 或任何getty
进程 - 由init
(或 PID #1 的任何内容)启动以初始化 TTY 设备并向终端发送适当的重置代码,显示登录提示并接收用户名。一旦getty
完成,这将是exec()
一个login
从用户那里获取密码的过程。
但请注意:这只是exec()
,而不是fork()
+ exec()
。因此,一旦启动会话的工作完成,该getty
进程就会消失,login
并最终被用户的 shell 取代。一旦用户的会话结束,init
将检测到该 TTY 设备上不再有任何进程,并将启动另一个实例来getty
重新启动该进程。
因此,如果您想继续过滤从终端传入的任何字符,则需要在整个会话中保持不变的内容。一旦用户的会话结束,您可能希望进程消失,这样您就可init
以为下一个登录会话启动一个新的实例。
您还需要复制 TTY 设备接口,因为真正的串行端口 TTY 设备将在您的程序执行工作时被占用。尝试让两个单独的程序同时读取同一个串行端口只会导致悲剧。幸运的是,您不必从头开始:复制 TTY 界面正是伪 TTY是给。看man 3 openpty
。
您需要像那样初始化设备设置并向终端发送适当的重置代码agetty
,但随后您的程序将显示登录提示并初始化其字符过滤循环。一旦收到对用户名提示的响应,它应该请求一个伪 TTY,fork()
+exec()
一个login
连接到该伪 TTY 的“从”端的程序,并开始将过滤后的字符从真实终端传递到该伪 TTY 的主端伪 TTY 和从伪 TTY 返回到真实终端的未过滤输出。
您的程序不应通过主动等待来自 TTY 设备的数据来浪费 CPU 周期,而应使用select(2)
或poll(2)
系统调用来有效地等待数据处理。
正在阅读ttysnoop
包的源代码可能有用,因为它需要执行类似的操作来记录 TTY 会话。