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_MAX还是SIZE_MAX限制的。
发布于 2015-04-19 05:55:05
ssize_t类型被POSIX定义为一种带符号的类型,能够在没有其他保证的情况下存储至少32767 (_POSIX_SSIZE_MAX)。因此它的最大值可以小于size_t的最大值。
ssize_t的POSIX定义:
ssize_t
用于字节计数或错误指示。
因此,您请求写入的字节数可能会大于ssize_t可以容纳的字节数。在这种情况下,POSIX将其留给实现。
来自write()的POSIX规范:
字节写入(int ssize_t,const void *buf,size_t nbyte);
如果nbyte的值大于{SSIZE_MAX},则结果由实现定义。
发布于 2015-04-19 05:55:57
write()的POSIX规范说:
如果
nbyte的值大于{SSIZE_MAX},则结果由实现定义。
因此,任何尝试写入超过SSIZE_MAX字节的行为都会导致不符合POSIX要求的行为,但必须由系统记录(这是实现定义的行为,而不是未定义的行为)。但是,不同的系统可能会有不同的处理方式,而且没有什么可以阻止一个系统报告错误(可能是将errno设置为EINVAL)和另一个系统写入SSIZE_MAX字节并报告错误,让应用程序在其余的字节上再次尝试,而其他系统可能会很有创造力,并以不同的方式做事情。
如果你有一个64位的系统,SSIZE_MAX可能比世界上最大的单个数据中心的磁盘空间大(可能是一个数量级甚至更多,甚至考虑到美国国家安全局和谷歌),所以你不太可能遇到真正的问题,但在32位系统上,你很容易有超过2 GiB的空间,如果ssize_t是32位的,你必须处理所有这些问题。(在MacOSX10.10.3上,32位版本至少在默认情况下具有4字节的size_t和ssize_t。)
发布于 2015-04-19 05:32:25
可以,一次调用write可以写入的数据量是有限制的,具体内容可以参考the relevant glibc documentation page。引用该页的话说,“您的程序应该始终在循环中写调用,迭代直到所有数据都被写入为止。”(重点补充)该页还澄清了ssize_t用于表示可在单个操作中读取或写入的块的大小。
https://stackoverflow.com/questions/29722999
复制相似问题