为什么 sys_read 系统调用在检测到换行时结束?
Why does the sys_read system call end when it detects a new line?
我是汇编初学者(使用 nasm)。我正在通过大学课程学习汇编。
我试图了解 sys_read linux 系统调用在被调用时的行为。具体来说,sys_read 在读取新行或换行时停止 。根据我所受的教导,这是真的。这 online tutorial article 也肯定了 fact/claim.
When sys_read detects a linefeed, control returns to the program and the users input is located at the memory address you passed in ECX.
我查看了 linux 程序员手册中的 sys_read 调用(通过“man 2 read”)。它没有提到应该提到的行为,对吗?
read() attempts to read up to count bytes from file descriptor fd
into the buffer starting at buf.
On files that support seeking, the read operation commences at the
file offset, and the file offset is incremented by the number of bytes
read. If the file offset is at or past the end of file, no bytes are
read, and read() returns zero.
If count is zero, read() may detect the errors described below. In
the absence of any errors, or if read() does not check for errors, a
read() with a count of 0 returns zero and has no other effects.
If count is greater than SSIZE_MAX, the result is unspecified.
所以我的问题是,为什么会发生这种行为?这是 linux 内核中的规范,这应该发生还是其他原因的结果?
这不是 read()
系统调用的属性,而是 termios
的 属性,终端驱动程序。在默认配置中,termios 缓冲传入的字符(即您键入的内容),直到您按 Enter,之后整行被发送到从终端读取的程序。这是为了方便起见,因此您可以在发送之前编辑该行。
正如 Peter Cordes 所说,从其他类型的文件(如常规文件)读取时不会出现此行为,可以通过配置 termios 将其关闭。
教程里说的都是垃圾,请无视
这是因为您正在从 POSIX tty in canonical mode 读取(在您按 return 到 "submit" 行之前,退格键起作用;这全部由内核的 tty 驱动程序处理)。查找 POSIX tty 语义/stty/ioctl。如果您 运行 ./a.out < input.txt
,您将不会看到此行为。
请注意,如果您按 control-d(EOF tty 控制序列),TTY 上的 read()
将 return 没有换行符。
假设 read()
读取整行对于玩具程序来说是可以的,但是 不要 开始假设在任何需要健壮的地方,即使你已检查您是否正在从 TTY 读取。我忘记了 如果用户将多行文本粘贴到终端仿真器 会发生什么。很可能它们最终都在一个 read()
缓冲区中。
另请参阅 :如果您在一行中输入的字符数超过了 read()
缓冲区大小,您至少需要再调用一次读取系统调用来清除输入。
如您所述,read(2)
libc 函数只是 sys_read
的薄包装。这个问题的答案确实与汇编语言无关,用C(或任何其他语言)进行系统编程也是如此。
进一步阅读:
stty(1)
手册页:您可以在其中更改控制字符执行的操作。
- The TTY demystified:一些历史,一些图表显示 xterm、内核和从 tty 读取的进程如何交互。还有关于会话管理和信号的东西。
- https://en.wikipedia.org/wiki/POSIX_terminal_interface#Canonical_mode_processing 以及该文章的相关部分。
我是汇编初学者(使用 nasm)。我正在通过大学课程学习汇编。
我试图了解 sys_read linux 系统调用在被调用时的行为。具体来说,sys_read 在读取新行或换行时停止 。根据我所受的教导,这是真的。这 online tutorial article 也肯定了 fact/claim.
When sys_read detects a linefeed, control returns to the program and the users input is located at the memory address you passed in ECX.
我查看了 linux 程序员手册中的 sys_read 调用(通过“man 2 read”)。它没有提到应该提到的行为,对吗?
read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf.
On files that support seeking, the read operation commences at the file offset, and the file offset is incremented by the number of bytes read. If the file offset is at or past the end of file, no bytes are read, and read() returns zero.
If count is zero, read() may detect the errors described below. In the absence of any errors, or if read() does not check for errors, a read() with a count of 0 returns zero and has no other effects.
If count is greater than SSIZE_MAX, the result is unspecified.
所以我的问题是,为什么会发生这种行为?这是 linux 内核中的规范,这应该发生还是其他原因的结果?
这不是 read()
系统调用的属性,而是 termios
的 属性,终端驱动程序。在默认配置中,termios 缓冲传入的字符(即您键入的内容),直到您按 Enter,之后整行被发送到从终端读取的程序。这是为了方便起见,因此您可以在发送之前编辑该行。
正如 Peter Cordes 所说,从其他类型的文件(如常规文件)读取时不会出现此行为,可以通过配置 termios 将其关闭。
教程里说的都是垃圾,请无视
这是因为您正在从 POSIX tty in canonical mode 读取(在您按 return 到 "submit" 行之前,退格键起作用;这全部由内核的 tty 驱动程序处理)。查找 POSIX tty 语义/stty/ioctl。如果您 运行 ./a.out < input.txt
,您将不会看到此行为。
请注意,如果您按 control-d(EOF tty 控制序列),TTY 上的 read()
将 return 没有换行符。
假设 read()
读取整行对于玩具程序来说是可以的,但是 不要 开始假设在任何需要健壮的地方,即使你已检查您是否正在从 TTY 读取。我忘记了 如果用户将多行文本粘贴到终端仿真器 会发生什么。很可能它们最终都在一个 read()
缓冲区中。
另请参阅 read()
缓冲区大小,您至少需要再调用一次读取系统调用来清除输入。
如您所述,read(2)
libc 函数只是 sys_read
的薄包装。这个问题的答案确实与汇编语言无关,用C(或任何其他语言)进行系统编程也是如此。
进一步阅读:
stty(1)
手册页:您可以在其中更改控制字符执行的操作。- The TTY demystified:一些历史,一些图表显示 xterm、内核和从 tty 读取的进程如何交互。还有关于会话管理和信号的东西。
- https://en.wikipedia.org/wiki/POSIX_terminal_interface#Canonical_mode_processing 以及该文章的相关部分。