Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!tut.cis.ohio-state.edu!bloom-beacon!hstbme.mit.edu!scs From: scs@hstbme.mit.edu (Steve Summit) Newsgroups: comp.lang.c Subject: Re: When to use fflush()? Summary: VMS trivia Keywords: fflush Message-ID: <14352@bloom-beacon.MIT.EDU> Date: 16 Sep 89 20:35:28 GMT References: <14507@haddock.ima.isc.com> <10913@smoke.BRL.MIL> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: scs@adam.pika.mit.edu (Steve Summit) Lines: 66 In article <14507@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >I've forgotten whether this issue was ever resolved: what should happen if the >output stream is a VMS record-oriented file? If the currently buffered output >contains no newlines, is it appropriate for fflush() to do nothing, and return >success? In article <10913@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >The specification says that unwritten data IS delivered to the host >environment. It does not (and cannot) be specific about how that is >actually accomplished. >I would think that so long as the implementation ensures that the >data will reach the record-structured file SOMEtime, that would >suffice. Before the distinction between pANS C and Posix was as clear as it is today, and before the exhortation to use stdio rather than system calls in portable code was as strong, it was common to provide open/read/write/etc. in a "foreign" (non-Unix) C RTL. In that case, the right place to handle newline-to-record-structure conversion is of course in the write(2) emulation, not in stdio. Indeed, using a VMS C RTL I once wrote, the stdio sources could be taken from a Unix machine and compiled, without essential change, to run successfully "on top of" the Unix system call emulation. In this situation, the mind-set when considering the stdio code is that the underlying open/read/write emulation is "the operating system" even though it is actually library code running in user mode. fflush's job is done when it has called write(). (The data has been "delivered to the host environment.") The fact that the characters which have been written are waiting in a buffer at the write() level (waiting for the line to be terminated or the file closed) and have not, in fact, been written to the disk, is fairly equivalent to the fact that Unix uses delayed writes and the same thing is essentially true after a write(2) there. (The buffering is merely happening one level further up, or two levels if you consider that an emulation on VMS is properly written on top of RMS which may impose its own level of buffering before the VMS equivalent of low-level I/O system calls are reached.) A more interesting question (under this scheme) would be what should happen if fflush() (or any code, for that matter) were to call fsync() for a record-oriented text file. I don't remember if I implemented fsync() and, if I did, if I asked or answered the premature record termination question. A quality emulation of fsync semantics would certainly force data to be written as close to the disk as possible (calling RMS and lower-level flush operations as appropriate). It is probably possible to extend records in-place, as long as they're at the end of the file, so the premature record terminator might be "erased" if later I/O, after the fflush(), were to complete the "line" and add an explicit \n. It would require some fairly ugly state variables in the emulation's "file descriptor," of questionable payoff. (DEC's VMS C RTL uses by default a previously-unimportant VMS file type called "stream LF", rather than the standard record-oriented carriage-control text files, to circumvent these kinds of difficulties. Unfortunately, other VMS utilities historically had only sporadic understanding of stream-LF files, to the point that the first versions of DEC's VMS C compiler failed Ritchie's generality/usefulness test: C program text output from a C program was not acceptable as input to the C compiler. C's growing popularity has forced DEC to expand the handling of stream-LF files elsewhere in VMS, including, you'll be relieved to know, the input section of the C compiler.)