Xref: utzoo comp.lang.c:33064 comp.unix.programmer:309 Path: utzoo!attcan!uunet!ogicse!mintaka!bloom-beacon!daemon From: scs@adam.mit.edu (Steve Summit) Newsgroups: comp.lang.c,comp.unix.programmer Subject: Re: Request code for log-file mechanism Keywords: c log-file source Message-ID: <1990Oct22.221536.22257@athena.mit.edu> Date: 22 Oct 90 22:15:36 GMT References: <1990Oct17.094623.2381@westc.uucp> <1990Oct17.213140.19516@decuac.dec.com> <4006@goanna.cs.rmit.oz.au> Sender: daemon@athena.mit.edu (Mr Background) Reply-To: scs@adam.mit.edu (Steve Summit) Organization: Thermal Technologies, Inc. Lines: 44 In article <1990Oct17.094623.2381@westc.uucp> marco@westc.uucp (Marco Nijdam) writes: >We are writing an application that must keep a log-file of the >actions that where taken. It is possible that more than one >process writes to a log file at the same time. In article <4006@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: >Not only that, they wanted it *portable*. >You're in luck. ANSI C comes pretty close to what you want. [Suggests using fopen "a" mode and setvbuf() to select line buffering, with a large buffer.] >What's going on here? The "a" argument of fopen() says "the file position >indicator is positioned at the end of the file before EACH write". Making >the buffer big enough for the longest line and selecting line buffering >ensures that each time you write a line using fprintf(), the whole line >will be buffered and then sent out. > >You really need to check the fine print, but this *should* work reasonably >well. That is, after all, why "a" is defined the way it is. For anything >more reliable, you will have to rely on file locking. I was going to suggest a similar approach, as an approximate solution, but I'm afraid that the "fine print" does not ensure that this will work. First of all, there is no guarantee that buffered output is written with a single call to the underlying operating system (write(2) or the equivalent for Unix). (Actually, section 4.9.3 comes closer than I would have thought, saying that line-buffered "characters are intended to be transmitted to... the host environment as a block," although that's "when a new-line character is encountered.") Secondly, there is no guarantee that the underlying operating system's low-level write mechanism is atomic. (Unix's tends to be, at least for "reasonably" sized requests.) As Richard mentions, file locking is the more reliable approach, though obviously less portable. (In practice, his suggested mechanism will probably work fine, at least on a Unix system. Beware of older Unix systems, for which fopen "a" mode indicated a seek to the end at open time, with no special attention thereafter, whereas this application requires the equivalent of open(2)'s O_APPEND mode, indicating a seek to the end upon each write.) Steve Summit scs@adam.mit.edu