问题:C 中 write(2) 的返回值为 0 是错误吗?

在系统调用write(2)的手册页中 -

ssize_t write(int fd, const void *buf, size_t count);

它说:

返回值

成功时,返回写入的字节数(零表示未写入任何内容)。出错时,返回 -1,并适当设置errno。如果计数为零并且文件描述符引用常规文件,则可能返回 0,或者可能检测到错误。对于特殊文件,结果不可移植。

我将此解释为意味着返回 0 仅表示没有写入任何内容,无论出于何种任意原因。

但是,在处理作为 TCP 套接字的文件描述符时,UNP](http://www.unpbook.com/)中的[Stevens 将返回值 0 视为致命错误(这由另一个在短计数上调用exit(1)的函数包装):

ssize_t /* Write "n" bytes to a descriptor. */
writen(int fd, const void *vptr, size_t n)
{
    size_t      nleft;
    ssize_t     nwritten;
    const char  *ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;       /* and call write() again */
            else
                return(-1);         /* error */
        }

        nleft -= nwritten;
        ptr   += nwritten;
    }
    return(n);
}

如果errno指示 write 调用被接收信号的进程中断,他只将 0 视为合法返回值。

为什么?

解答

Stevens 可能这样做是为了捕捉行为不同的 write() 的旧实现。例如,单一 Unix 规范说(http://www.opengroup.org/onlinepubs/000095399/functions/write.html)

在此卷 IEEE Std 1003.1-2001 要求返回 -1 并将 errno 设置为 [EAGAIN] 时,大多数历史实现返回零

Logo

更多推荐