我看到这样的代码:
int my_write(int fd, char *buf, size_t len)
{
ssize_t written = 0;
while (len > 0) {
if ((written = write(fd, buf, len)) < 0) {
debug("write() failed: %s", strerror(errno));
return -1;
} else if (written == 0) {
debug("write() failed: %s", strerror(errno));
return -1;
}
len -= written;
buf += written;
}
return 0;
}
Solaris
上的手册页说明了这一点:
成功完成后,write()返回实际写入与fildes关联的文件的字节数。这个数字永远不会 大于nbyte。否则,返回-1,文件指针保持不变 未更改,并且errno设置为指示错误。
write(fd, buf, len /* > 0 */)
可以返回0
吗?如果是,何时?
fd
是常规文件(不是管道,套接字,...)描述符,它位于阻止模式。
答案 0 :(得分:2)
是的,它可能会返回零。当调用该函数不会写任何东西时,它将返回零值。
man
write
页
零表示没有写入
if ( len > 0 )
这个条件用于检查给定的字节是否完全写入。这个条件是在写函数没有问题时完全写入给定的字节。
len
是1000
,第一次写入是将字节写入512
,但我们需要将100个字节写入该文件描述符。所以我们必须减去写入字节的值。
len -= written;
现在len
的值为488(1000-512)
。现在在下一个循环中,write必须写入488个字节。
buf += written;
这是因为我们写了512个字节。我们必须编写剩余的字节,因此我们将指针位置递增以指出剩余的字节。
( written == 0 )
是否上述写入功能是否写入。如果它没有写任何东西,那就关闭它。
根据您的更新,当我们写入管道,FIFO和流或网络设备时,上述概念将更有用。在普通文件描述符中,它可能不会产生任何影响。
当文件系统空间不足或达到配额限制时,普通文件描述符会发生这种情况。这种情况很少见。这个概念主要用于写入非常规文件描述符。
答案 1 :(得分:2)
答案 2 :(得分:1)
是的,至少在Linux上,因为write(2)的手册页明确说明了
成功时,返回写入的字节数(零表示没有写入)。出错时,返回-1,并设置
errno
适当。
BTW,我相信在某些奇怪的情况下,write
返回的字节数可能会为0:例如:一个非阻塞管道或套接字 - 但通常是EAGAIN
错误 - 或者一些奇怪的套接字(不仅仅是TCP或UDP套接字!),或者某些NFS安装文件系统中的某个文件带有选项{{ 1}},或者当完全达到某个限制或某个配额阈值时;或某些奇怪的设备等intr
...
因此,当write
给出0时,我会处理极少数情况(特殊情况下write
&amp; EAGAIN
错误总是更好。我同意EINTR
给出0是非常罕见的,但我不明白为什么你会避免处理这种情况。
答案 3 :(得分:1)
在这种情况下,没有。
来自man 2 write
:
RETURN VALUE
On success, the number of bytes written is returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately.
If count is zero and fd refers to a regular file, then write() may
return a failure status if one of the errors below is detected. If no
errors are detected, 0 will be returned without causing any other
effect. If count is zero and fd refers to a file other than a regular
file, the results are not specified.
由于while(len > 0)
条件,write()
写入零字节当且仅当遇到错误时,在这种情况下它将返回-1。