6600pete@hub.UUCP (12/07/89)
When one opens a file under *most* flavors of UN*X (I realize this is the kind of thing that will be system-dependent, though it oughtn't) with fopen ( ..., "a" ), the file mark is supposed to be moved to EOF before every write. Now, how is this done? Are there two system calls, one to move the file mark and one to do the write, or is there one system call, "append"? If the latter, then this is an easier solution for a problem I have than figuring out how to do record locking. ------------------------------------------------------------------------------- Pete Gontier : InterNet: 6600pete@ucsbuxa.ucsb.edu, BitNet: 6600pete@ucsbuxa Editor, Macker : Online Macintosh Programming Journal; mail for subscription Hire this kid : Mac, DOS, C, Pascal, asm, excellent communication skills
stevens@hsi.UUCP (Richard Stevens) (12/07/89)
In article <3250@hub.UUCP>, 6600pete@hub.UUCP writes: > When one opens a file under *most* flavors of UN*X (I realize this is > the kind of thing that will be system-dependent, though it oughtn't) > with fopen ( ..., "a" ), the file mark is supposed to be moved to EOF > before every write. Now, how is this done? Are there two system calls, > one to move the file mark and one to do the write, or is there one > system call, "append"? With System V Release 2, fopen specifies the O_APPEND flag to the open system call if you specify the "a" mode. This has the kernel move the inode's read/write offset to the end of the file every time you write to the file. Hence only one system call is required. I suspect the later release of System V also do this. Interesting, however, is that the 4.3BSD source differs. It does an lseek to the EOF when fopen is called, and that's it. 4.3 does have an O_APPEND option to open, but it doesn't appear to be used. The 4.3 man page for fopen also doesn't go to the lengths that the system V man page does specifying that "a" really means that every write gets appended, regardless of the file's current position. Richard Stevens Health Systems International, New Haven, CT stevens@hsi.com ... { uunet | yale } ! hsi ! stevens
meissner@dg-rtp.dg.com (Michael Meissner) (12/07/89)
In article <3250@hub.UUCP> 6600pete@hub.UUCP writes: | When one opens a file under *most* flavors of UN*X (I realize this is | the kind of thing that will be system-dependent, though it oughtn't) | with fopen ( ..., "a" ), the file mark is supposed to be moved to EOF | before every write. Now, how is this done? Are there two system calls, | one to move the file mark and one to do the write, or is there one | system call, "append"? If the latter, then this is an easier solution | for a problem I have than figuring out how to do record locking. In "modern" Unixes (ie, System V.[01234], Berkeley BSD 4.[23], possibly eariler in System III, and Berkeley 4.1, but I don't have manuals for them), the open system call takes a flag (O_APPEND) that says to reset the file position to the end of the file whenever a write system call occurs. On a filesystem local to the machine, this is done atomically with the write call. I'm not sure whether this is guaranteed to be atomic under NFS, but I suspect not, particularly if the NFS server is not a UNIX system (such as a VAX running VMS or IBM mainframe). My version 7 manual does not list any flags for open, and the fopen man page does not make any promises about ruber-banding the file position to the end of the file. -- -- Michael Meissner, Data General. Until 12/15: meissner@dg-rtp.DG.COM After 12/15: meissner@osf.org
6600pete@hub.UUCP (12/07/89)
From article <895@hsi86.hsi.UUCP-, by stevens@hsi.UUCP (Richard Stevens):
- In article <3250@hub.UUCP-, 6600pete@hub.UUCP writes:
-- When one opens a file under *most* flavors of UN*X
-- with fopen ( ..., "a" ), the file mark is supposed to be moved to EOF
-- before every write. Now, how is this done? Are there two system calls,
-- one to move the file mark and one to do the write, or is there one
-- system call, "append"?
-
- With System V Release 2, [ there is one system call ].
- I suspect the later release of System V also do this.
-
- Interesting, however, is that the 4.3BSD source differs. It does
- an lseek to the EOF when fopen is called, and that's it. 4.3 does
- have an O_APPEND option to open, but it doesn't appear to be used.
From article <MEISSNER.89Dec6215032@tiktok.rtp.dg.com-, by meissner@dg-rtp.dg.com
(Michael Meissner):
- On a filesystem local to the machine, [ the append ]
- is done atomically with the write call. I'm not sure whether this is
- guaranteed to be atomic under NFS, but I suspect not, particularly if
- the NFS server is not a UNIX system (such as a VAX running VMS or IBM
- mainframe).
- My version 7 manual does not list any flags for open, and the fopen
- man page does not make any promises about ruber-banding the file
- position to the end of the file.
Perhaps the best way to do it, then, is to call open() with O_APPEND,
then pass the handle to fdopen()? What does anyone think?
-------------------------------------------------------------------------------
Pete Gontier : InterNet: 6600pete@ucsbuxa.ucsb.edu, BitNet: 6600pete@ucsbuxa
Editor, Macker : Online Macintosh Programming Journal; mail for subscription
Hire this kid : Mac, DOS, C, Pascal, asm, excellent communication skills
cpcahil@virtech.uucp (Conor P. Cahill) (12/07/89)
In article <3250@hub.UUCP>, 6600pete@hub.UUCP writes: > When one opens a file under *most* flavors of UN*X (I realize this is > the kind of thing that will be system-dependent, though it oughtn't) > with fopen ( ..., "a" ), the file mark is supposed to be moved to EOF > before every write. Now, how is this done? Are there two system calls, > one to move the file mark and one to do the write, or is there one > system call, "append"? If the latter, then this is an easier solution > for a problem I have than figuring out how to do record locking. There exists an append mode for open files where the kernel automatically places all writes at the end of file. This is what fopen(3) will use under unix. Under other os's this will depend upon the capabilities of the os. If the system has an append mode, then it will probably be used. Else If the system has a mechanism to move around a file (like unix lseek()) it will probably be used to move to the end of the file before each write. Else the library could just read data until it came to EOF and then write the data. (Yes, this would be very inefficient) -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
chris@mimsy.umd.edu (Chris Torek) (12/07/89)
In article <895@hsi86.hsi.UUCP> stevens@hsi.UUCP (Richard Stevens) writes: >... Interesting, however, is that the 4.3BSD source differs. It does >an lseek to the EOF when fopen is called, and that's it. 4.3 does >have an O_APPEND option to open, but it doesn't appear to be used. This is scheduled to change (to match the wording in the ANSI standard). I also wrote code to assert FAPPEND mode on fdopen(fd, "a"). This is a bit nastier, but would seem to be required for reasons of sanity. I do not, however, clear FAPPEND on other fdopen calls. What does SysV do? What does the SVID say? -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
rec@dg.dg.com (Robert Cousins) (12/07/89)
In article <3250@hub.UUCP> 6600pete@hub.UUCP writes: >When one opens a file under *most* flavors of UN*X (I realize this is >the kind of thing that will be system-dependent, though it oughtn't) >with fopen ( ..., "a" ), the file mark is supposed to be moved to EOF >before every write. Now, how is this done? Are there two system calls, >one to move the file mark and one to do the write, or is there one >system call, "append"? If the latter, then this is an easier solution >for a problem I have than figuring out how to do record locking. >------------------------------------------------------------------------------- >Pete Gontier : InterNet: 6600pete@ucsbuxa.ucsb.edu, BitNet: 6600pete@ucsbuxa >Editor, Macker : Online Macintosh Programming Journal; mail for subscription >Hire this kid : Mac, DOS, C, Pascal, asm, excellent communication skills It is important to point out that use of "a" mode is some circumstances will not work as anticipated. This is in any environment in which NFS is used and two programs are writing to the same file without locking the records in an effective fashion. The reason for this is that the NFS protocol does not have any concept of "guaranteed append" so the client operating system translates append writes into something more like lseek-write combinations which are more-or-less atomic. The problem with this is that the client operating system has its own idea of where the end of the file is and therefore where to append. If another client has appended something to the file in the mean time it could be lost. This all comes from the fact that NFS is a stateless protocol. Each NFS operation carries with it all (or atleast is supposed to) information the server needs to complete the operation. Furthermore, all operations are idempotent and therefore can be repeatedly performed. (This is how they get away with using UDP/IP.) In effect, an NFS write translates into a "write x bytes in file y starting at location z." If the same write is performed several times (since UDP/IP can deliver a request multiple times), the data file's contents are the same. Had this been a stateful protocol ("append x bytes to file y") and multiple requests were delivered, one could easily see a datafile with a bad case of the "stutters." Robert Cousins Dept. Mgr, Workstation Dev't. Data General Corp. Speaking for myself alone. executions took place
davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (12/08/89)
In retrospect I think that one more key letter would have been useful in pANS. The use of "a" to mean 'always append, never rewrite' is a useful one, but often "a" is used when what is meant is to 'open the existing file if there is one, otherwise create one.' If "a" really means append only, then the second use requires: open for "r" if that fails open for "w+" This is not a big deal, but either another open type in addition to {rwa} could have been provided, or another modifier in addition to {+b} would suffice. Something for the next committee to consider, I suspect. -- bill davidsen (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) "The world is filled with fools. They blindly follow their so-called 'reason' in the face of the church and common sense. Any fool can see that the world is flat!" - anon
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/08/89)
In article <3263@hub.UUCP> 6600pete@hub.UUCP writes: >Perhaps the best way to do it, then, is to call open() with O_APPEND, >then pass the handle to fdopen()? What does anyone think? I think you haven't shown us a clear conception about what you need to do. Is there some reason for not using fopen(...,"a") and letting the C implementation worry about the details?
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/08/89)
In article <21152@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: >This is scheduled to change (to match the wording in the ANSI standard). >I also wrote code to assert FAPPEND mode on fdopen(fd, "a"). This is a >bit nastier, but would seem to be required for reasons of sanity. I do >not, however, clear FAPPEND on other fdopen calls. >What does SysV do? What does the SVID say? All the System V documentation and sources I could find, including SVID Issue 2, indicate that the proper open() modes were the responsibility of the invoker of fdopen(), not of the fdopen() implementation. IEEE Std 1003.1 is a bit more explicit in its description of fdopen(): "The type of the stream must be allowed by the mode of the open file". To me this indicates clearly that the System V implementation is proper. In fact, I think it is a disservice for some other (4.nBSD?) implementation to add functionality such as you describe. That could mislead programmers on such systems into thinking that that implementation's behavior was universal, whereas it is not.
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/08/89)
In article <1989Dec7.130813.4992@virtech.uucp> cpcahil@virtech.uucp (Conor P. Cahill) writes:
-Under other os's this will depend upon the capabilities of the os.
-Else If the system has a mechanism to move around a file (like unix lseek())
- it will probably be used to move to the end of the file before each
- write.
On a single-user non-multitasking system, a better implementation would
be to seek to the end only on the initial open, not for each write.
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/08/89)
In article <1890@crdos1.crd.ge.COM> davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) writes:
- In retrospect I think that one more key letter would have been useful
-in pANS. The use of "a" to mean 'always append, never rewrite' is a
-useful one, but often "a" is used when what is meant is to 'open the
-existing file if there is one, otherwise create one.'
If so, that's simply a user error. That is not and never has been
the meaning of the "a" fopen() mode.
trt@rti.UUCP (Thomas Truscott) (12/09/89)
> It is important to point out that use of "a" mode is some circumstances > will not work as anticipated. ... [problems with NFS noted] > Had this been a stateful protocol ("append x bytes to file y") and multiple > requests were delivered, one could easily see a datafile with a bad > case of the "stutters." Except of course that stateful protocols invariably have "at most once" semantics. Since it is stateful the protocol can easily detect and discard the duplicate requests. Tom Truscott
les@chinet.chi.il.us (Leslie Mikesell) (12/09/89)
In article <11775@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >On a single-user non-multitasking system, a better implementation would >be to seek to the end only on the initial open, not for each write. But what if the single-user non-multitasking system is networked to a shared filesystem and you would like your log files to work? Les Mikesell les@chinet.chi.il.us
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/11/89)
In article <1989Dec9.000805.1617@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: -In article <11775@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: ->On a single-user non-multitasking system, a better implementation would ->be to seek to the end only on the initial open, not for each write. -But what if the single-user non-multitasking system is networked to -a shared filesystem and you would like your log files to work? Suggest you look up "system" in a decent engineering textbook. You described a system that doesn't fit my qualifiers.
rec@dg.dg.com (Robert Cousins) (12/11/89)
In article <3319@rti.UUCP> trt@rti.UUCP (Thomas Truscott) writes: >> It is important to point out that use of "a" mode is some circumstances >> will not work as anticipated. ... [problems with NFS noted] > >> Had this been a stateful protocol ("append x bytes to file y") and multiple >> requests were delivered, one could easily see a datafile with a bad >> case of the "stutters." > >Except of course that stateful protocols invariably have "at most once" >semantics. Since it is stateful the protocol can easily >detect and discard the duplicate requests. > Tom Truscott It is true that there are a number ways in which NFS could have been designed differently. However, the point is, fopen(..., "a") does have some implications in an NFS environment which do derive from the early design decision to use a stateless protocol. Question in general: How could NFS have been designed (from scratch) to be more closely representative of UNIX semantics while keeping its "nice" features? I think it is time to have this discussion again. Maybe some new ideas will come up. Robert Cousins Dept. Mgr, Workstation Dev't. Data General Corp. Speaking for myself alone.
bobmon@iuvax.cs.indiana.edu (RAMontante) (12/12/89)
gwyn@brl.arpa (Doug Gwyn) <11775@smoke.BRL.MIL> : -On a single-user non-multitasking system, a better implementation -[of append] would -be to seek to the end only on the initial open, not for each write. Is the process forbidden from doing an lseek, or are you allowing the programmer to reposition somewhere else in the file? What is the semantics of the append behavior?
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/12/89)
In article <31276@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes: >gwyn@brl.arpa (Doug Gwyn) <11775@smoke.BRL.MIL> : >-On a single-user non-multitasking system, a better implementation >-[of append] would >-be to seek to the end only on the initial open, not for each write. >Is the process forbidden from doing an lseek, or are you allowing the >programmer to reposition somewhere else in the file? What is the >semantics of the append behavior? You must mean fseek(), as use of lseek() in conjunction with a stdio stream can break stdio operation. fseek() on an "a" mode stream could report failure (or, to be fancy, it could succeed if the f.p.i. wouldn't be changed by the seek). However, the story for an "a+" mode stream is different, because so far as I can determine reads from the stream can be initiated anywhere by preceding them with fseek() calls, and only writes are required to jump to the end of the file. Whether or not seek before write would be necessary depends on how much state information is maintained for the stream by the stdio implementation.
les@chinet.chi.il.us (Leslie Mikesell) (12/12/89)
In article <11785@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >-In article <11775@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >->On a single-user non-multitasking system, a better implementation would >->be to seek to the end only on the initial open, not for each write. >-But what if the single-user non-multitasking system is networked to >-a shared filesystem and you would like your log files to work? >Suggest you look up "system" in a decent engineering textbook. >You described a system that doesn't fit my qualifiers. I fail to see how providing each user-level process with its own CPU and i/o facilities would break anyone's concept of a "system". Do you mean that all filesystem clients and servers must maintain state information to be worthy of being called a "system"? Les Mikesell les@chinet.chi.il.us
Kemp@DOCKMASTER.NCSC.MIL (12/13/89)
Michael Meissner writes: > On a filesystem local to the machine, this [seeking to EOF] is > done atomically with the write call. I'm not sure whether this > is guaranteed to be atomic under NFS, but I suspect not, particularly > if the NFS server is not a UNIX system (such as a VAX running VMS > or IBM mainframe). This has *nothing* to do with the NFS server. The client is responsible for maintaining whatever state is associated with the open file, including the seek position. From the NFS Protocol Spec, Version 2: NFSPROC_WRITE(writeargs) struct writeargs { fhandle file; unsigned beginoffset; unsigned offset; unsigned totalcount; opaque data<NFS_MAXDATA>; }; 'Writes "data" beginning at "offset" bytes from the beginning of "file". The first byte of the file is at offset zero. ... The write operation is atomic. Data from this call to WRITE will not be mixed with data from another client's calls. Note: The arguments "beginoffset" and "totalcount" are ignored and are removed in the next protocol revision.' Dave Kemp <Kemp@dockmaster.ncsc.mil> "My sister is a yahoo"
peter@ficc.uu.net (Peter da Silva) (12/13/89)
Names removed to protect the guilty. a>On a single-user non-multitasking system, a better implementation would a>be to seek to the end only on the initial open, not for each write. b>But what if the single-user non-multitasking system is networked to b>a shared filesystem and you would like your log files to work? a>Suggest you look up "system" in a decent engineering textbook. a>You described a system that doesn't fit my qualifiers. b>I fail to see how providing each user-level process with its own CPU b>and i/o facilities would break anyone's concept of a "system". Now it's not a single-user non-multitasking system. That is, you didn't fit his qualifiers. Like he said. Now for something completely different: b>Do you mean that all filesystem clients and servers must maintain state b>information to be worthy of being called a "system"? Well, it's a quality of information issue. But I agree with P1003.1 on this one... stateless NFA isn't acceptable. -- `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>. 'U` Also <peter@ficc.lonestar.org> or <peter@sugar.lonestar.org>. "It was just dumb luck that Unix managed to break through the Stupidity Barrier and become popular in spite of its inherent elegance." -- gavin@krypton.sgi.com
les@chinet.chi.il.us (Leslie Mikesell) (12/14/89)
In article <21726@adm.BRL.MIL> Kemp@DOCKMASTER.NCSC.MIL writes: >Michael Meissner writes: > > On a filesystem local to the machine, this [seeking to EOF] is > > done atomically with the write call. I'm not sure whether this > > is guaranteed to be atomic under NFS, but I suspect not, particularly > > if the NFS server is not a UNIX system (such as a VAX running VMS > > or IBM mainframe). >This has *nothing* to do with the NFS server. The client is responsible >for maintaining whatever state is associated with the open file, >including the seek position. Which means that it can't be guaranteed to know the current EOF position if there are multiple writers. The server knows the EOF position, of course, but doesn't accept "append" requests. With a stateless protocol the possibility would then exist for a request to succeed, but the ack back to the client to be lost resulting it a retry on the request. If another "append" request intervened before the retry, the write would be duplicated in different places. Les Mikesell les@chinet.chi.il.us
guy@auspex.UUCP (Guy Harris) (12/19/89)
>Which means that it can't be guaranteed to know the current EOF position >if there are multiple writers. Correct. >The server knows the EOF position, of course, but doesn't accept "append" >requests. With a stateless protocol the possibility would then exist for >a request to succeed, but the ack back to the client to be lost resulting >it a retry on the request. If another "append" request intervened before >the retry, the write would be duplicated in different places. No, since the "write" request contains the position in the file at which the "write" is to occur; instead, you run the risk of having your data overwritten by another writer. If the server *did* accept an "append" request" that implicitly wrote to the end of the file, a retry would run the risk of causing the write to be duplicated in different places.