Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the semantic difference between ERANGE and EOVERFLOW?

The errno value ERANGE is documented by POSIX as

Result too large.

and EOVERFLOW is documented as

Value too large to be stored in data type.

What's the semantic difference between these two? Especially considering that ERANGE is used by ISO 9899 (e.g. in strtol) with the semantic described for EOVERFLOW. Are these two errno values only distinct for historical reasons?

Please back up your arguments with appropriate sources if possible.

like image 570
fuz Avatar asked Jan 24 '16 20:01

fuz


1 Answers

SingleUnix is quite verbose about 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 seems to be intended to signal a subsystem incompatibility, i.e. some system returned a larger value than another subsystem can handle.

EOVERFLOW is explained in more detail in the rationale:

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().

Thanks to @rici for the pointer

ERANGE is more like this won't ever fit. strtol() is one example. Another, less clear one: Trying to increment a SYSV semaphore past its configured limit returns ERANGE.

With EOVERFLOW that data is there, it just does not fit into the local data structure(s).

For example, lseek() can return EOVERFLOW. This happens, e.g. when off_t is only 32bit but the file system can support larger files and you try to seek past the range the OS can handle. Why isn't this ERANGE? Because the system can handle the operation in principle, it just cannot return it to you in the data type available.

Trying to map more than 2G using mmap() on a 32bit system on Linux returns an EOVERFLOW (other systems return EINVAL).

Unfortunately, this is not totally consistent. For example, the bluetooth stack returns EOVERFLOW when it finds too many host controllers in the system.

like image 159
dhke Avatar answered Sep 18 '22 12:09

dhke