写(2)是否总是写入小于或等于SSIZE_MAX?

write(2)的函数签名是ssize_t write(int fd, const void *buf, size_t count) 。 通常, size_t的最大值大于ssize_t 。 这是否意味着write实际可写的数据量实际上是SSIZE_MAX而不是SIZE_MAX ? 如果不是这种情况,当写入的字节数大于SSIZE_MAX时会发生什么情况?

我基本上想知道write的数据量是否受SSIZE_MAXSIZE_MAX

类型ssize_t由POSIX定义为有符号类型,能够存储至少32767( _POSIX_SSIZE_MAX )而没有其他保证。 因此它的最大值可以小于size_t的最大值。

ssize_t的POSIX定义:

 ssize_t 

用于计数字节或错误指示。

因此,您请求写入的字节数可能大于ssize_t可以容纳的字节数。 在这种情况下,POSIX将其留给实现。

来自write()的POSIX规范:

 ssize_t write(int fildes, const void *buf, size_t nbyte); 

如果nbyte的值大于{SSIZE_MAX},则结果是实现定义的。

write()的POSIX规范说:

如果nbyte的值大于{SSIZE_MAX},则结果是实现定义的。

因此,任何写入超过SSIZE_MAX字节的尝试SSIZE_MAX导致POSIX没有强制要求的行为,但必须由系统记录(它是实现定义的,而不是未定义的行为)。 但是,不同的系统可能会以不同的方式处理它,并且没有什么可以阻止一个系统报告错误(可能是errno设置为EINVAL )和另一个系统写入SSIZE_MAX字节并报告该错误,将其留给应用程序再次尝试其余部分,以及其他系统系统可以是创造性的,也可以做不同的事情。

如果你有一个64位系统, SSIZE_MAX可能大于世界上最大的单一数据中心的磁盘空间量(可能是一个数量级或更多,甚至允许NSA和谷歌),所以你不太可能遇到这个真正的问题,但在32位系统上,你可以轻松拥有超过2 GiB的空间,如果ssize_t是32位,你必须处理所有这些。 (在Mac OS X 10.10.3上,32位版本具有4字节size_tssize_t ,至少在默认情况下是这样。)

是的,可以在一次写入调用中写入的数据量仅限于ssize_t中可以保存的数据量。 有关说明,请参阅相关的glibc文档页面 。 引用该页面,“你的程序应该总是在循环中调用write,迭代直到写入所有数据。” (重点补充)该页面还阐明了ssize_t用于表示可以在单个操作中读取或写入的块的大小。