ERANGE 和 EOVERFLOW 之间的语义区别是什么?

What's the semantic difference between ERANGE and EOVERFLOW?

errnoERANGE 被 POSIX 记录为

Result too large.

EOVERFLOW 记录为

Value too large to be stored in data type.

这两者在语义上有什么区别?特别是考虑到 ERANGE 被 ISO 9899 使用(例如在 strtol 中),其语义描述为 EOVERFLOW。这两个 errno 值是否仅因历史原因而不同?

如果可能,请使用适当的来源支持您的论点。

SingleUnix 对 EOVERFLOW:

相当冗长

Value too large to be stored in data type The user ID or group ID of an IPC or file system object was too large to be stored into appropriate member of the caller-provided structure. This error will only occur on implementations that support a larger range of user ID or group ID values than the declared structure member can support. This usually occurs because the IPC or file system object resides on a remote machine with a larger value of the type uid_t, off_t or gid_t than the local system.

EOVERFLOW 似乎是为了表示子系统不兼容,即某些系统 returned 的值大于另一个子系统可以处理的值。

EOVERFLOWexplained in more detail的道理:

Most of the uses of this error code are related to large file support. Typically, these cases occur on systems which support multiple programming environments with different sizes for off_t, but they may also occur in connection with remote file systems.

In addition, when different programming environments have different widths for types such as int and uid_t, several functions may encounter a condition where a value in a particular environment is too wide to be represented. In that case, this error should be raised. For example, suppose the currently running process has 64-bit int, and file descriptor 9223372036854775807 is open and does not have the close-on- exec flag set. If the process then uses execl() to exec a file compiled in a programming environment with 32-bit int, the call to execl() can fail with errno set to [EOVERFLOW]. A similar failure can occur with execl() if any of the user IDs or any of the group IDs to be assigned to the new process image are out of range for the executed file's programming environment.

Note, however, that this condition cannot occur for functions that are explicitly described as always being successful, such as getpid().

感谢@rici 指点

ERANGE 更像是 这永远不适合strtol() 就是一个例子。另一个不太清楚的问题:尝试将 SYSV 信号量增加到超过其配置限制 returns ERANGE.

虽然 EOVERFLOW 数据在那里,但它不适合本地数据结构。

例如lseek()可以returnEOVERFLOW。这种情况发生,例如当 off_t 仅为 32 位但文件系统可以支持更大的文件时,您尝试搜索超过 OS 可以处理的范围。为什么不是 ERANGE?因为系统原则上可以处理操作,只是不能return以可用的数据类型给你。

尝试在 Linux return 和 EOVERFLOW 上的 32 位系统上使用 mmap() 映射超过 2G(其他系统 return EINVAL).

不幸的是,这并不完全一致。例如,蓝牙堆栈 returns EOVERFLOW 当它发现系统中的主机控制器太多时。

存在语义差异:

EOVERFLOW 用于缓冲区大小 os 太小且请求的数据传输会溢出目标缓冲区或类似错误情况的情况:

http://man7.org/linux/man-pages/man2/open_by_handle_at.2.html

EOVERFLOW

         The handle->handle_bytes value passed into the call was too
          small.  When this error occurs, handle->handle_bytes is
          updated to indicate the required size for the handle.

http://man7.org/linux/man-pages/man2/open.2.html

EOVERFLOW

         pathname refers to a regular file that is too large to be
          opened.  The usual scenario here is that an application
          compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64
          tried to open a file whose size exceeds (1<<31)-1 bytes; see
          also O_LARGEFILE above.  This is the error specified by
          POSIX.1; in kernels before 2.6.24, Linux gave the error EFBIG
          for this case.

ERANGE 用于不适合目标类型 (C99) 的值和超出特定命令定义范围的参数 (POSIX)

但它也用于 EOVERFLOW 更合适的错误:

http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html

  The pthread_setname_np() function can fail with the following error:

 ERANGE The length of the string specified pointed to by name exceeds
          the allowed limit.

  The pthread_getname_np() function can fail with the following error:

  ERANGE The buffer specified by name and len is too small to hold the
          thread name.

我猜 EOVERFLOW 用于系统调用,ERANGE 用于 C 库函数,标准的和非标准的。