terminfo delay/padding 如何在 TTY 中实现?
how is terminfo delay/padding implemented in TTYs?
我一直在查看 terminfo,它有延迟,例如$<5>
,在功能字符串中。我试图通过 运行ning tput
在 strace
下查看延迟是如何实现的,即它是通过 nanosleep
还是通过插入 NUL
或其他字符。这是我尝试 运行 和跟踪的命令:
TERM=ansi77 strace -o log.txt tput dl1
我在 ansi77
上选择了 dl1
,因为它被定义为 dl1=\E[M$<5*/>
。但是,我在跟踪中看到的只是写入 3 个字节:
write(1, "[M", 3) = 3
- 所以,我的问题是,延迟实际是如何实施的?填充字符还是简单的 process/thread sleep?
- 我可以在终端仿真器中观察它还是需要真正的硬件终端才能看到它?
- 尝试用
tput
重现它是否有任何缺陷?
在实现延迟的地方,它是通过传输填充字符(传统上是 NUL 字符)来完成的。可以通过变量 pad 或 pc.
的 termdata/terminfo 设置更改填充字符
填充字符是必需的,因为程序无法知道先前发送的字符实际何时写入,从而开始CPU延迟。即使内核在输出刷新后完成了它们,字符可能仍会缓冲在输出设备 UART 中。
所需的填充字符数是根据波特率计算的 - 因此它取决于可用且准确的信息。
库中的 tputs 例程实现填充(参见 man 3 tputs)。我怀疑命令行工具也是如此,因为它基本上只是一个包装器。
同意@cliffordheath 的观点,即填充是通过添加填充字符来完成的,参考可用文档会有所帮助。
硬件终端并没有不复存在,它们仍然是supported by ncurses。如果没有填充,这些旧终端将无法正常工作(丢失或损坏您的输出)。 vt100
条目使用填充,xterm
条目不使用填充。
填充字符的terminfo名称是pad
; pc
是一个 termcap 名称(参见 terminfo(5)):
pad_char pad pc padding char
(instead of null)
terminfo 手册页有一个冗长的段落(在 Types of Capabilities 中)处理填充。 terminfo 格式支持两种类型的填充(advisory 和 mandatory),以它们的格式区分。 termcap 仅支持后者(当然使用不同的语法),并且与 terminfo 不同,所有延迟都同时发生(使 "flash" 的转义序列通常不起作用)。
命令行tput
program does more than act as a wrapper for the function tputs
,但它在输出字符串时使用它。命令行程序提供输出布尔值、数字,当然还有字符串功能。
库调用 tputs
有一个受影响的行数参数,在计算延迟时会考虑(如波特率)。
在 OP 的问题中
dl1=\E[M$<5*/>
指定与受影响的行数成比例的延迟(由 "*"
字符标记)。 命令行 tput
实用程序受影响的行数是 1。它调用 putp
to do this. However, that in turn calls delay_output, and that calls baudrate。最后一个函数仅在终端初始化时初始化。命令行 tput
不会 初始化终端,因此延迟对 that 不起作用。您应该看到(给定正确的速度)使用库本身的延迟。
ncurses 还提供 napms
(毫秒)的时间延迟,这与填充不同。
我一直在查看 terminfo,它有延迟,例如$<5>
,在功能字符串中。我试图通过 运行ning tput
在 strace
下查看延迟是如何实现的,即它是通过 nanosleep
还是通过插入 NUL
或其他字符。这是我尝试 运行 和跟踪的命令:
TERM=ansi77 strace -o log.txt tput dl1
我在 ansi77
上选择了 dl1
,因为它被定义为 dl1=\E[M$<5*/>
。但是,我在跟踪中看到的只是写入 3 个字节:
write(1, "[M", 3) = 3
- 所以,我的问题是,延迟实际是如何实施的?填充字符还是简单的 process/thread sleep?
- 我可以在终端仿真器中观察它还是需要真正的硬件终端才能看到它?
- 尝试用
tput
重现它是否有任何缺陷?
在实现延迟的地方,它是通过传输填充字符(传统上是 NUL 字符)来完成的。可以通过变量 pad 或 pc.
的 termdata/terminfo 设置更改填充字符填充字符是必需的,因为程序无法知道先前发送的字符实际何时写入,从而开始CPU延迟。即使内核在输出刷新后完成了它们,字符可能仍会缓冲在输出设备 UART 中。
所需的填充字符数是根据波特率计算的 - 因此它取决于可用且准确的信息。
库中的 tputs 例程实现填充(参见 man 3 tputs)。我怀疑命令行工具也是如此,因为它基本上只是一个包装器。
同意@cliffordheath 的观点,即填充是通过添加填充字符来完成的,参考可用文档会有所帮助。
硬件终端并没有不复存在,它们仍然是supported by ncurses。如果没有填充,这些旧终端将无法正常工作(丢失或损坏您的输出)。 vt100
条目使用填充,xterm
条目不使用填充。
填充字符的terminfo名称是pad
; pc
是一个 termcap 名称(参见 terminfo(5)):
pad_char pad pc padding char
(instead of null)
terminfo 手册页有一个冗长的段落(在 Types of Capabilities 中)处理填充。 terminfo 格式支持两种类型的填充(advisory 和 mandatory),以它们的格式区分。 termcap 仅支持后者(当然使用不同的语法),并且与 terminfo 不同,所有延迟都同时发生(使 "flash" 的转义序列通常不起作用)。
命令行tput
program does more than act as a wrapper for the function tputs
,但它在输出字符串时使用它。命令行程序提供输出布尔值、数字,当然还有字符串功能。
库调用 tputs
有一个受影响的行数参数,在计算延迟时会考虑(如波特率)。
在 OP 的问题中
dl1=\E[M$<5*/>
指定与受影响的行数成比例的延迟(由 "*"
字符标记)。 命令行 tput
实用程序受影响的行数是 1。它调用 putp
to do this. However, that in turn calls delay_output, and that calls baudrate。最后一个函数仅在终端初始化时初始化。命令行 tput
不会 初始化终端,因此延迟对 that 不起作用。您应该看到(给定正确的速度)使用库本身的延迟。
ncurses 还提供 napms
(毫秒)的时间延迟,这与填充不同。