Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1a 7/7/83; site rlgvax.UUCP Path: utzoo!linus!philabs!seismo!rlgvax!guy From: guy@rlgvax.UUCP (Guy Harris) Newsgroups: net.unix-wizards Subject: Re: r+ on fopen. Message-ID: <1188@rlgvax.UUCP> Date: Fri, 23-Sep-83 00:50:38 EDT Article-I.D.: rlgvax.1188 Posted: Fri Sep 23 00:50:38 1983 Date-Received: Sun, 25-Sep-83 23:59:00 EDT References: <11771@sri-arpa.UUCP> Organization: CCI Office Systems Group, Reston, VA Lines: 55 If this was under V7, I'd be somewhat surprised as the differences between System III "stdio" (where the documentation claims it works) and V7 "stdio" are miniscule. Under 4.?BSD, however, the description (odd vs. even seek offsets) seems to fit a bug in the 4.?BSD "fseek". The fix follows: *** /tmp/,RCSt1011421 Fri Sep 23 00:45:21 1983 --- /tmp/,RCSt2011421 Fri Sep 23 00:45:22 1983 *************** *** 36,41 if (iop->_flag & _IORW) { iop->_ptr = iop->_base; iop->_flag &= ~_IOREAD; } p = lseek(fileno(iop), offset-resync, ptrname); iop->_cnt = 0; --- 36,42 ----- if (iop->_flag & _IORW) { iop->_ptr = iop->_base; iop->_flag &= ~_IOREAD; + resync = 0; } p = lseek(fileno(iop), offset-resync, ptrname); iop->_cnt = 0; The problem is that if you are switching from reading a stream to writing it, or vice versa, you must do an "fseek" between the last read and the first write (this is documented in the System III documentation). However, on a stream where the last operation was a read, if told to seek to an odd offset the 4.?BSD "fseek" will seek to that offset - 1 and then read the next character. I presume this was done because copies between kernel and user space on a PDP-11 are more efficient if both buffers are aligned on word boundaries (so check 2.?BSD for this as well!). Unfortunately, this means that the sequence: read seek to odd boundary write becomes: read seek to even boundary read one character write which violates the rule that an "fseek" must separate reads and writes. The fix merely turns off the seek to even boundary and read on streams open for reading and writing. Given this fix, I believe that "[rwa]+" on 4.?BSD will work as reliably as it does on V7 and System III, so everybody stick this fix in and then we can rewrite our code to use "[rwa]+". Guy Harris {seismo,mcnc,we13,brl-bmd,allegra}!rlgvax!guy