From owner-freebsd-arch@FreeBSD.ORG Wed Aug 1 02:49:16 2012 Return-Path: Delivered-To: arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 21FD0106566B for ; Wed, 1 Aug 2012 02:49:16 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id E97E98FC15 for ; Wed, 1 Aug 2012 02:49:15 +0000 (UTC) Received: from xyf.my.dom (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q712nE1L033454 for ; Wed, 1 Aug 2012 02:49:15 GMT (envelope-from davidxu@freebsd.org) Message-ID: <5018992C.8000207@freebsd.org> Date: Wed, 01 Aug 2012 10:49:16 +0800 From: David Xu User-Agent: Mozilla/5.0 (X11; FreeBSD i386; rv:9.0) Gecko/20111229 Thunderbird/9.0 MIME-Version: 1.0 To: arch@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Subject: short read/write and error code X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Aug 2012 02:49:16 -0000 POSIX requires write() to return actually bytes written, same rule is applied to read(). http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html > ETURN VALUE > > Upon successful completion, write() [XSI] and pwrite() shall > return the number of bytes actually written to the file associated > with fildes. This number shall never be greater than nbyte. > Otherwise, -1 shall be returned and errno set to indicate the error. http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html > RETURN VALUE > > Upon successful completion, read() [XSI] and pread() shall return > a non-negative integer indicating the number of bytes actually read. > Otherwise, the functions shall return -1 and set errno to indicate > the error. I have following patch to fix our code to be compatible with POSIX: Index: sys_generic.c =================================================================== --- sys_generic.c (revision 238927) +++ sys_generic.c (working copy) @@ -333,8 +333,7 @@ #endif cnt = auio->uio_resid; if ((error = fo_read(fp, auio, td->td_ucred, flags, td))) { - if (auio->uio_resid != cnt && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) + if (auio->uio_resid != cnt) error = 0; } cnt -= auio->uio_resid; @@ -539,15 +538,14 @@ if (fp->f_type == DTYPE_VNODE) bwillwrite(); if ((error = fo_write(fp, auio, td->td_ucred, flags, td))) { - if (auio->uio_resid != cnt && (error == ERESTART || - error == EINTR || error == EWOULDBLOCK)) - error = 0; /* Socket layer is responsible for issuing SIGPIPE. */ if (fp->f_type != DTYPE_SOCKET && error == EPIPE) { PROC_LOCK(td->td_proc); tdsignal(td, SIGPIPE); PROC_UNLOCK(td->td_proc); } + if (auio->uio_resid != cnt) + error = 0; } cnt -= auio->uio_resid; #ifdef KTRACE -current only resets error code to zero for short write when code is ERESTART, EINTR or EWOULDBLOCK. But this is incorrect, at least for pipe, when EPIPE is returned, some bytes may have already been written. For a named pipe, I may don't care a reader is disappeared or not, because for named pipe, a new reader can come in and talk with writer again, so I need to know how many bytes have been written, same is applied to reader, I don't care writer is gone, it can come in again and talk with reader. So I suggest to remove surplus code in -current's dofilewrite() and dofileread(). For EPIPE, We still deliver SIGPIPE to current thread, but returns actually bytes written. Regards, David Xu