`stty line NUMBER` 到底在做什么?

`stty line NUMBER` 到底在做什么?

根据页面中,此字段描述“行规则”,它确定当用户按退格键或 ^C 时会发生什么。本质上,当程序调用read(2).

不过设置好像没有什么效果。在我的 Linux 机器上,我有两条线路规则:

$ cat /proc/tty/ldiscs
n_tty       0
n_null     27

$ stty line 27似乎没有影响任何事情。退格键仍然正常工作。

然而,如果我这样做$ stty -icanon,我确实会看到一个变化——退格键不再正常工作,程序会逐个字符地读取内容(read(2)似乎总是只返回 1 个字符)。

这里发生了什么?

答案1

线路规则是 tty 驱动程序和 tty 核心之间的一层(参见这张图片,来自这里): 在此输入图像描述

如果将其设置为 27 (tty_null),您的日期将穿过图表的左侧(跳过行规则)。如果将其设置为 0,则它会通过默认的线路规则,可以处理原始输入和煮熟的输入。

TTY(0)
    The default line discipline, providing transparent operation (raw mode)
    as well as the habitual terminal line editing capabilities (cooked mode).

其他学科的列表是这里

您可以自己编写,也可以使用现有的。如果您拥有该slip模块并将其插入modprobe slip,您会注意到这一点:

$ cat /proc/tty/ldiscs 
n_tty       0
slip        1
n_null     27

当您这样做时,$ stty line 27您删除了线路规则(您将其设置为空线路规则),当您这样做时,$ stty -icanon您在原始模式下设置了默认线路规则。

答案2

stty line N没有做太多事情。

要更改 Linux 上的线路规则,应该调用ioctl(TIOCSETD),但它并没有这样做;stty line N只是更改 termios 结构的(非标准)c_line字段,然后调用tcsetattr(3)-> ioctl(TCSETS*),这将简单地更改后续->c_line调用返回的字段。tcgetattr(3)ioctl(TCGETS)

在这个答案的最后是一个小的 C 示例程序,它应该真正改变其 stdin fd 上的行规则。

这并不是唯一stty(1)不足的方法;stty也无法设置“非标准”波特率(这可以在 Linux 上使用TCSETS2// TCSETSW2ioctl轻松完成TCSETSF2,但不幸的是它没有在标准 C 库中公开,并且不被 所使用stty)。

$ cat > tiocsetd.c <<'EOT'
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <err.h>

int main(int ac, char **av){
        int o;
        if(ioctl(0, TIOCGETD, &o)) err(1, "io(TIOCGETD)");
        if(ac > 1){
                int n, d = atoi(av[1]);
                if(ioctl(0, TIOCSETD, &d)) err(1, "io(TIOCSETD)");
                if(ioctl(0, TIOCGETD, &n)) err(1, "io(TIOCGETD)");
                printf("%d -> %d => %d\n", o, d, n);
        }else
                printf("%d\n", o);
        return 0;
}
EOT
$ cc -Wall tiocsetd.c -o tiocsetd
$ ./tiocsetd
0

$ tty
/dev/pts/4 ## << make a note of this
$ cat /proc/tty/ldiscs
n_tty       0
n_null     27
$ ./tiocsetd 27
<your tty is hugged ;-)>

要恢复它,请./tiocsetd 0 </dev/pts/4从另一个终端运行(替换/dev/pts/4为实际的 tty),然后按^C

相关内容