ERANGE和EOVERFLOW之间的语义差异是什么?

时间:2016-01-24 20:30:32

标签: c posix semantics errno

POSIX将errnoERANGE记录为

  

结果太大了。

EOVERFLOW记录为

  

值太大而无法存储在数据类型中。

这两者之间的语义差异是什么?特别是考虑到{98}使用ERANGE(例如在strtol中)EOVERFLOW描述了语义errno。这两个payload值仅因历史原因而不同吗?

如果可能,请使用适当的来源备份您的论据。

2 个答案:

答案 0 :(得分:5)

SingleUnix对EOVERFLOW非常详细:

  

值太大而无法存储在数据类型中IPC或文件系统对象的用户ID或组ID太大,无法存储到调用者提供的结构的相应成员中。此错误仅发生在支持比声明的结构成员可支持的更大范围的用户ID或组ID值的实现上。这通常是因为IPC或文件系统对象驻留在具有比本地系统更大的uid_t,off_t或gid_t值的远程计算机上。

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

理论中

EOVERFLOWexplained in more detail

  

此错误代码的大多数用法都与大文件支持有关。通常,这些情况发生在支持off_t不同大小的多个编程环境的系统上,但它们也可能与远程文件系统连接。

     

此外,当不同的编程环境对诸如int和uid_t之类的类型具有不同的宽度时,若干函数可能遇到特定环境中的值太宽而无法表示的情况。在这种情况下,应该提出此错误。例如,假设当前正在运行的进程具有64位int,并且文件描述符9223372036854775807已打开且未设置close-on-exec标志。如果进程然后使用execl()来执行在具有32位int的编程环境中编译的文件,则对execl()的调用可能会失败并且errno设置为[EOVERFLOW]。如果要分配给新过程映像的任何用户标识或任何组标识超出了已执行文件的编程环境的范围,则execl()可能会发生类似的故障。

     

但请注意,对于明确描述为始终成功的函数,例如getpid(),不会出现这种情况。

感谢@rici指针

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

如果数据存在EOVERFLOW,则它不适合本地数据结构。

例如,lseek()可以返回EOVERFLOW。这发生了,例如,当off_t仅为32位但文件系统可以支持更大的文件时,您尝试超出操作系统可以处理的范围。为什么不是ERANGE?由于系统原则上可以处理操作,因此无法以可用的数据类型将其返回给您。

尝试在Linux上的32位系统上使用mmap()映射2G以上的数据会返回EOVERFLOW(其他系统返回EINVAL)。

不幸的是,这并不完全一致。例如,当蓝牙堆栈在系统中找到太多主机控制器时,它会返回EOVERFLOW

答案 1 :(得分:4)

存在语义差异:

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

  

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库函数,标准版本,而不是。