Date: Tue, 31 Jul 2012 21:11:37 -0700 From: Alfred Perlstein <alfred@freebsd.org> To: David Xu <davidxu@freebsd.org> Cc: arch@freebsd.org Subject: Re: short read/write and error code Message-ID: <20120801041137.GA56944@elvis.mu.org> In-Reply-To: <5018992C.8000207@freebsd.org> References: <5018992C.8000207@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
This is cool, is there a test case that you can run on Linux/Solaris to compare expected vs actual behavior? * David Xu <davidxu@freebsd.org> [120731 19:49] wrote: > 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 > _______________________________________________ > freebsd-arch@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-arch > To unsubscribe, send any mail to "freebsd-arch-unsubscribe@freebsd.org" -- - Alfred Perlstein .- VMOA #5191, 03 vmax, 92 gs500, 85 ch250, 07 zx10 .- FreeBSD committer
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120801041137.GA56944>