为什么sys_read系统在检测到新行时调用结束?

时间:2016-08-28 17:41:07

标签: linux assembly nasm system-calls tty

我是汇编的初学者(使用nasm)。我正在通过大学课程学习装配。

我正在尝试了解sys_read linux系统调用时的行为。具体来说, sys_read在读取新行或换行符时会停止。根据我所教的,这是事实。这online tutorial article也肯定了事实/主张。

  

当sys_read检测到换行符时,控件返回程序,用户输入位于您在ECX中传递的内存地址。

我检查了linux程序员的sys_read调用手册(通过“man 2 read”)。它没有提到它应该的行为,对吗?

  

read()尝试从文件描述符fd读取计数字节数   从buf开始进入缓冲区。

     

在支持搜索的文件上,读操作开始于   文件偏移量,文件偏移量增加字节数   读。如果文件偏移量处于或超过文件末尾,则不会有字节   read,read()返回零。

     

如果count为零,read()可能会检测到下面描述的错误。在   没有任何错误,或者如果read()没有检查错误,a   read()的计数为0,返回零,没有其他影响。

     

如果count大于SSIZE_MAX,则结果未指定。

所以我的问题是,为什么会发生这种行为? Linux内核中的规范是否应该发生这种情况还是其他内容的结果?

2 个答案:

答案 0 :(得分:9)

这是因为你正在阅读POSIX tty in canonical mode(在你按返回“提交”行之前退格工作;这些都是由内核的tty驱动程序处理的)。查找POSIX tty语义/ stty / ioctl。如果您运行./a.out < input.txt,则不会看到此行为。

请注意,如果你点击control-d(EOF tty控制序列),TTY上的read()将返回没有换行符。

假设read()读取整行对于玩具程序是可以的,但是开始假设任何需要健壮的东西,即使你已经检查过你从TTY读到。我忘记了如果用户将多行文本粘贴到终端模拟器中会发生什么。很可能它们最终都在一个read()缓冲区中。

另请参阅my answer on a question about small read()s leaving unread data on the terminal:如果在一行上输入的字符多于read()缓冲区大小,则至少需要再读取一次系统调用来清除输入。

正如您所指出的,read(2) libc函数只是sys_read的一个薄包装器。这个问题的答案实际上与汇编语言无关,对C语言(或任何其他语言)的系统编程也是如此。

进一步阅读:

答案 1 :(得分:4)

这不是read()系统调用的属性,而是终端驱动程序termios的属性。在默认配置中,termios会缓冲输入的字符(即您键入的内容),直到您按 Enter ,然后整行将被发送到从终端读取的程序。这是为了方便起见,因此您可以在发送之前编辑该行。

正如Peter Cordes所说,当从其他类型的文件(如常规文件)中读取时,这种行为不存在,并且可以通过配置termios来关闭。

教程说的是垃圾,请忽略它。