Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!spool.mu.edu!agate!dog.ee.lbl.gov!elf.ee.lbl.gov!torek From: torek@elf.ee.lbl.gov (Chris Torek) Newsgroups: comp.unix.programmer Subject: Re: readv/writev Message-ID: <14609@dog.ee.lbl.gov> Date: 24 Jun 91 09:53:58 GMT Article-I.D.: dog.14609 References: <1991Jun21.215941.5693@ncsu.edu> Reply-To: torek@elf.ee.lbl.gov (Chris Torek) Organization: Lawrence Berkeley Laboratory, Berkeley Lines: 40 X-Local-Date: Mon, 24 Jun 91 02:53:58 PDT In article <1991Jun21.215941.5693@ncsu.edu> jwb@cepmax.ncsu.edu writes: >Stevens (in Unix Network Programming) notes that read/write on a >socket may input/output fewer bytes than requested. Can I expect the >same behavior for readv/writev? Yes. >If so, how might one implement "readvn"/"writevn"? (a la Steven's ...) (I am guessing what these are: loops around the read/write calls.) It is ugly. You must make use of the fact that the if the system call returns `early', it has partially processed at most one vector (and fully processed only any earlier vectors). Thus, something like: cc = readv(fd, iov, iovcnt); if (cc == 0) ... handle EOF ...; if (cc < 0) ... handle error ...; for (p = iov, n = iovcnt; n > 0; p++, n--) { if (iov->iov_len > cc) { iov->iov_base += cc; iov->iov_len -= cc; break; } cc -= iov->iov_len; } if (cc == 0) ... all done ...; iov = p; iovcnt = n; /* now there are iovcnt io vectors undone */ Note that this may modify one of the I/O vectors, hence is not suitable in some cases. To be fully general this would have to copy the vectors in those cases, and work from the copies; then it would have to free the copies when the whole transfer is done. This is one reason I elected to ignore readv and writev in my 4BSD stdio rewrite. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov