You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

read()函数返回值与O_NONBLOCK设置不符的技术咨询

Why Your read() Behavior Doesn't Match the Manual

Let's cut to the chase: the core issue here is that you're testing with a regular file, but the POSIX manual rules you're referencing only apply to stream-oriented file descriptors (like sockets, character devices, or pseudoterminals)—not regular files.

First, Let's Clarify Regular File Behavior

Regular files have a fixed, seekable size. When you call read() on a regular file:

  • If you're at the end of the file (EOF), read() will always return 0 immediately, regardless of whether O_NONBLOCK is set. There's no "waiting for more data" scenario here because regular files don't dynamically receive new data unless another process appends to them—and even then, you'd need to re-read from the new offset, not just keep calling read() at the EOF position.
  • If there is data available, read() will read as much as possible (up to your buffer size) and return the number of bytes read, again ignoring O_NONBLOCK.

The Manual Rules Apply to Special File Types

The manual's description of O_NONBLOCK behavior for "files that support non-blocking reads (excluding pipes/FIFOs)" refers to file descriptors where data arrives dynamically, such as:

  • Network sockets (TCP/UDP)
  • Character devices (e.g., /dev/tty, serial ports)
  • Pseudoterminals (PTYs)
  • Other stream-based I/O channels where data isn't pre-stored in a fixed file

For these types:

  • If O_NONBLOCK is set and no data is available, read() returns -1 with errno = EAGAIN
  • If O_NONBLOCK is not set, read() blocks until data arrives
  • If data is already available, O_NONBLOCK has no effect

A Quick Note on Your Code

In your second method, you're actually clearing the O_NONBLOCK flag with saved_flags & ~O_NONBLOCK—that sets the descriptor to blocking mode, not non-blocking. To enable non-blocking, you'd need to use saved_flags | O_NONBLOCK. But even if you fixed that, it wouldn't change the behavior for your regular file test case.

How to Verify the Manual's Rules

To see the expected non-blocking behavior, test with a stream-oriented descriptor. For example:

  1. Open /dev/tty (your terminal) with O_RDONLY
  2. Set O_NONBLOCK using fcntl()
  3. Call read() without typing anything—you'll get -1 with errno = EAGAIN
  4. Clear O_NONBLOCK and call read() again—the call will block until you type input

内容的提问来源于stack exchange,提问作者guang chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:40:07