From: CSBVAX::MRGATE!INFO-VAX-RELAY@KL.SRI.COM@SMTP 8-JUL-1988 19:46 To: ARISIA::EVERHART Subj: Re: a couple of random questions Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Tue 3 May 88 21:38:44-PDT Received: by ucbvax.Berkeley.EDU (5.59/1.28) id AA00387; Mon, 2 May 88 19:26:24 PDT Received: from USENET by ucbvax.Berkeley.EDU with netnews for info-vax@kl.sri.com (info-vax@kl.sri.com) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 30 Apr 88 04:29:15 GMT From: oodis01!uplherc!sp7040!obie!wsccs!terry@tis.llnl.gov (Every system needs one) Subject: Re: a couple of random questions Message-Id: <509@wsccs.UUCP> References: <10426@steinmetz.ge.com>, <541@vsi.UUCP>, <2736@bsu-cs.UUCP> Sender: info-vax-request@kl.sri.com To: info-vax@kl.sri.com In article <2736@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: > [my observation that ftell() on VMS gives different values for > the same file position reached in different ways] > > My thinking was affected by my VMS C manual, which says that "With > record files, ftell returns the starting position of the current > record, not the current byte offset." What I observed seems to > illustrate that VMS C's idea of "the current record" depends on how you > reached end-of-file. Another soul relegated to NL: by a buggy ftell()! The specific problem you get is this: when reading a record oriented file using fgetc() (and also fgets(), for all I know), you read a record [read...read...read]. This record stops at the end of the record, where VMS kindly supplies a '\n', pretending it's a stream file (as a record seperator). The problem is that say you are bouncing around in a file, so you want to fseek() to reposition the pointer to the record following the one you just read... logically, you ftell(), and store the result (which is the record number, not the byte offset into the file). The problem you run into is that you fseek() to the location later AND IT PUTS YOU AT THE START OF THE RECORD YOU JUST DID THE FTELL FROM! What's going on?!? You KNOW you read the full record! The problem is that the record pointer is not advanced to the next record until you read the first character of that record, even after VMS has gone and faked up the '\n' for you! The proper operation would be to go and advance the record pointer after faking the '\n' record terminator. After all, the next thing you read will be the first byte of that record, so one would assume that if you are pointing at the front of a record and did an fseek(ftell()), you would still be there, instead of the previous record! Here is a fix that will be portable when this bug is finally fixed in a future revision of the VMS libraries, God willing. It makes the assumption that you are using the standard C calls to do I/O and haven't done any of the weird stuff required to talk to strange files. Making the argument's match is your own problem... the following code took 5 days: [Should I declare this shareware and demand $5.00 or a first born male child?] #define ftell() dftell() /* Hi. I live in a global include and*/ /* come to visit all your .c files!*/ ..... /* some unreasonably large amount of normal code*/ ..... ..... /* this must be the last thing in some poor .c file*/ #undef ftell() /* so we can use the real one. UGH.*/ dftell() { ungetc( getc()); /* force record pointer update*/ return( ftell()); /* return updated position*/ } This is damned ugly, but will save you doing it everywhere or changing all ftell()'s everywhere. It also has the advantage of allowing you to say #ifdef VMS /* code that is otherwise reasonable*/ #endif instead of carrying it all over. Never tried it under ANSI-C becuase there isn't one yet until the standard lands on my head. Probably bomb if they see it, and become an example of "unallowable code" (volatile dftell()?). | Terry Lambert UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry | | @ Century Software OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry | | SLC, Utah | | These opinions are not my companies, but if you find them | | useful, send a $20.00 donation to Brisbane Australia... | | 'Admit it! You're just harrasing me because of the quote in my signature!' | -------