Sender: rich AT phekda DOT freeserve DOT co DOT uk Message-ID: <3E305173.9E89FA57@phekda.freeserve.co.uk> Date: Thu, 23 Jan 2003 20:32:52 +0000 From: Richard Dawe X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.23 i586) X-Accept-Language: de,fr MIME-Version: 1.0 To: djgpp-workers AT delorie DOT com Subject: Re: readv, writev [PATCH] References: <3E2FC531 DOT F37C6D24 AT phekda DOT freeserve DOT co DOT uk> <2427-Thu23Jan2003204136+0200-eliz AT is DOT elta DOT co DOT il> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Hello. Eli Zaretskii wrote: > > > Date: Thu, 23 Jan 2003 10:34:25 +0000 > > From: Richard Dawe > > > > Say you write the first part of the data, but then the write for the next > > part fails. What do you return? The call has failed, but you have written > > some data. It seems to me that it would be hard for a program to recover > > gracefully from this, since it doesn't know what has been written > > to the file. > > What is teh common practice in other implementations? Like glibc, > for example? There are three alternatives in glibc, depending on OS: (a) Use the system call. (There is one on Linux. This falls back on the POSIX implementation in certain conditions - too many iovecs in the vector.) (b) Allocate a chunk of memory, copy all the chunks into it and write them out. (This is the POSIX implementation.) (c) Fail and return ENOSYS (function unimplemented). For (b) there is a comment: /* XXX I don't know whether it is acceptable to try writing the data in chunks. Probably not so we just fail here. */ Please note that I haven't looked at the glibc source before. I was pretty surprised to find that it uses technique (b)! I looked at glibc 2.2.93 sources. For option (b) glibc uses alloca for small (< 512K) allocations. readv has similar code, with a similar "XXX" comment as above for the POSIX implementation. > > If writev were to write iov-by-iov and one call failed, it would need to > > seek to the position that it was at, before writing. This is to ensure: > > > > 1. that a retry will overwrite the data; > > 2. that we read from the position where the writes started. > > I'm not sure I understand this: what retry are we talking about here? I mean the application retrying the write. (Sorry, I wasn't clear there.) > Also, read after write requires an lseek, right? Yes, if you want to read back the data you just wrote. But if write() fails, then the file pointer is not advanced. Consider writev() for a vector of 2 entries, if we write() iovec-by-iovec: Entry 1: write() succeeds Entry 2: write() fails If we want to fail writev(), because the second write fails, then we should seek to the position before writev() was called. > > * It should cope with non-blocking write calls. > > Is this relevant for DOS? We don't support non-blocking I/O. I guess not. I suspect we'd need to update libc in other places to support non-blocking I/O properly. I was just thinking back to my libsocket days. libsocket did support non-blocking I/O. But then libsocket comes with its own readv()/writev() implementation. I wonder if any other FSEXTs support non-blocking I/O? > > > Can't you use _read instead? Is readv supposed to handle text files and > > > do CRLF->NL conversions? > > > > > > The same holds for _write in writev. > > > > I assumed that readv, writev were just vector-input versions of read, > > write and so should have the same CFLF->NL conversion characteristics. > > >From the function's descriptions, it sounds like they are for binary > data, but I might be mistaken. [snip] Typically readv() and writev() are used with sockets, because they're pretty convenient for that. > Does anyone know what does Cygwin do in this case? Cygwin's writev() uses the normal write() call, which CRLF->NL conversion, if in text mode. See: http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/syscalls.cc?rev=1.240&content-type=text/x-cvsweb-markup&cvsroot=src http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/fhandler.cc?rev=1.143&content-type=text/x-cvsweb-markup&cvsroot=src The first file is just the "system call", which ends up going to a Cygwin file handler. Search for fhandler_base::write and fhandler_base::writev in the second file. OK, now I'm slightly embarrassed. This is also the first time I've looked at the Cygwin source and they seem to use the memory allocation method too. Bye, Rich =] -- Richard Dawe [ http://www.phekda.freeserve.co.uk/richdawe/ ]