VMS C & records in files

Every system needs one terry at wsccs.UUCP
Wed Aug 31 15:00:56 AEST 1988


In article <1609 at edison.GE.COM>, rja at edison.GE.COM (rja) writes:
> I'm not aware of any solution to the problem of VMS file types.  The
> problem is precisely that VMS is so record-oriented.  Even nominal 
> text files don't work like UNIX.  We find that we have to use a loop of
> successive calls to read() to fill (for example) a 512 byte buffer
> because it gives only 1 record at a time even though you asked for 512
> bytes. :-(
>   UNIX and even MS-DOS will let you read 512 bytes in a chunk so it's VMS
> that is brain-damaged in this case.

Generally, I am on th UNIX side of the VMS/UNIX See-Digital-Sue-The-
Government-When-It-Mentions-UNIX-But-Still-Lose-The-Contract debate.

*BUT* it is the programmer, not VMS in this case.  Try one of:

	char *file = "myfile";

			/---- avoid the extra versions now!
			|
			v
	fopen( file, "r+");
	fopen( file, "r+", "rat=var,cr");
	fopen( file, "r+", "rat=fix", "mrs=512");

	If you must use open(), then at least have the decent-C to
read with more than on character in your buffer and write the same
way.  Files written with either the 2nd or 3rd above can't use putc()
at the low level, or the will (of course!) write out single records.
A record is sort of defined (gentleman's agreement?!?) as the result
of a single write operation.  The function fprintf() (for example)
uses putc() at the low level and so is broken.  If you can stand the
link warnings, write your own buffered putc().  The fprintf() can
be fixed by using your own with sprintf() and puts() or write()...
again, you will have to ignore the link errors, as well as the new
compile-time warnings about varadic functions.

The one real gripe I have is with record oriented files and implied
carriage control.  When reading from one of these things, VMS "fakes-up"
the record delimiter at the end.  I am of the opinion that after doing
that, the ftell() (which gives the record # even though you aren't
supposed to assume that) gives the fseek() target of the _beginning_
of_the_current_record_, even though the next character read will be
from the next record and should instead give the seek offset for the
beginning of the next record.  A fix that will survive them fixing it
(a real bummer if you're linked shared) follows:


#define ftell myftell	/* depends on not being a macro*/


....
....
....

/* DANGER! don't use ftell() after this in your code!*/
#undef ftell

myftell( fp)	/* not called myftell() to avoid becoming mymyftell()*/
FILE *fp;
{
	ungetc(getc());	/* inserting the fp is left as an exercise...*/
	return( ftell( fp));	/* uses the real ftell()*/
}

If ftell() is a macro on your system, happy search/replace!


| 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...   |
|                   'I have an eight user poetic liscence' - me               |



More information about the Comp.lang.c mailing list