arons@sesame.ucdavis.edu (Tom &) (12/21/89)
In porting a program from a BSD system to hp-ux version 3.10 on a 9k/800 I discovered a difference in stdio behavior. fd = fopen(path, "a") is used on the BSD system to open, creating if necessary a file. One, and only one, number is kept in the file by using: fseek(fd, 0L, 0); fprintf(fd, "%d\n", n); to update the file. On the hp-ux system the fseek's are effectively no-ops, that is the file consists of as many numbers as there are writes. Changing the "a" to a "r+" in the fopen works fine if the file exists, but won't create a new file. "a+" seems to behave the same as "a". In all cases the fseek returns a 0, indicating success. A workaround is easy enough to implement, but it is annoying to have to #ifdef the code. I am not sure whether the difference is a bug in either the BSD or hp-ux system, or some BSD/System V semantic difference. Does anyone know? The man page explanations for fopen on both systems are virtually identical. Tom Arons Internet: arons@iris.ucdavis.edu EE/CS Department Bitnet: arons@ucdavis University of California UUCP: {lll-crg, ucbvax}!ucdavis!iris!arons Davis, CA 95616 Phone: (916) 752-1750
decot@hpisod2.HP.COM (Dave Decot) (12/21/89)
> In porting a program from a BSD system to hp-ux version 3.10 on a 9k/800 > I discovered a difference in stdio behavior. > > fd = fopen(path, "a") > > is used on the BSD system to open, creating if necessary a file. > One, and only one, number is kept in the file by using: > > fseek(fd, 0L, 0); > fprintf(fd, "%d\n", n); > > to update the file. Since this code is opening the file for append (which means all writes should be done at the end) and seeking to the beginning, and not using the more intuitive "w+" flag to accomplish what appears at first glance to be the same effect, I would assume that the code is written this way as some kind of attempt to update the file atomically without conflicting with some other application. It is unclear that it would succeed at that goal even on the BSD system. > On the hp-ux system the fseek's are effectively no-ops, that is > the file consists of as many numbers as there are writes. Indeed it should. The "a" asks for "append mode". According to open(2) on both systems, that means every write appends to the end of the file, regardless of the current file offset. > Changing > the "a" to a "r+" in the fopen works fine if the file exists, but > won't create a new file. "a+" seems to behave the same as "a". > In all cases the fseek returns a 0, indicating success. A workaround > is easy enough to implement, but it is annoying to have to #ifdef the > code. Perhaps just use "w+" mode, or if this is an attempt to keep a sequence number from being updated simultaneously by different processes, rewrite the code to do proper file locking. > I am not sure whether the difference is a bug in either the BSD or > hp-ux system, or some BSD/System V semantic difference. Does anyone > know? The man page explanations for fopen on both systems are > virtually identical. The difference is the two interpretations of the word "append" for fopen(). See O_APPEND on open(2) for the (consistent) definitions of how appending to files is done. HP-UX sets the O_APPEND flag to do fopen()'s "a" append mode, BSD does not set O_APPEND, so writes do not always occur at the end of the file. Dave Decot HP DISCLAIMER: This article is not necessarily the opinion of Hewlett-Packard Company. It is provided without warranty of any kind, and the effects of its use is solely the responsibility of the user.
kah@hpfcso.HP.COM (Kathy Harris) (12/22/89)
/ hpfcso:comp.sys.hp / arons@sesame.ucdavis.edu (Tom &) / 10:48 am Dec 20, 1989 / >In porting a program from a BSD system to hp-ux version 3.10 on a 9k/800 >I discovered a difference in stdio behavior. > fd = fopen(path, "a") >is used on the BSD system to open, creating if necessary a file. >One, and only one, number is kept in the file by using: > fseek(fd, 0L, 0); > fprintf(fd, "%d\n", n); >to update the file. >On the hp-ux system the fseek's are effectively no-ops, that is >the file consists of as many numbers as there are writes. Changing >the "a" to a "r+" in the fopen works fine if the file exists, but >won't create a new file. "a+" seems to behave the same as "a". >In all cases the fseek returns a 0, indicating success. A workaround >is easy enough to implement, but it is annoying to have to #ifdef the >code. The HP-UX behavior is correct AT&T Sys V.2 stdio behavior. I don't know if BSD defines different behavior or if this is a bug in BSD. The relevant section in the HP-UX manual is from fopen(3S): When a file is opened for append (i.e., when *type* is "a" or "a+"), it is impossible to overwirte information already in the file. Fseek may be used to reposition the pointer to any position in the file, but when output is written to the file, the current file pointer is disregarded. All output is written at the end of the file and causes the file pointer to be respositioned at the end of the output. The ANSI C definition for "append" modes is similar. You have several options to set up code that should be portable: (a) If you always want to start with a "clean" file, use "w+" to do the fopen. (b) If you want to retain an existing file, but create a new one if necessary, then use open(2) to open the file and then fdopen(3S) to set up the stream. Open(2) gives you finer control over how a file is opened. You would want to use the flags O_RDWR and O_CREAT Kathy Harris H.P. Colorado Language Lab
rer@hpfcdc.HP.COM (Rob Robason) (12/28/89)
> In porting a program from a BSD system to hp-ux version 3.10 on a 9k/800 > I discovered a difference in stdio behavior. > fd = fopen(path, "a") > is used on the BSD system to open, creating if necessary a file. Here are the open(2) flags for each mode: MODE BSD HP-UX ----------------------------------------------------------------------------- "a" O_CREAT | O_WRONLY* O_CREAT | O_APPEND | O_WRONLY* "r" O_RDONLY* O_RDONLY* "w" O_TRUNC | O_CREAT | O_WRONLY* O_TRUNC | O_CREAT | O_WRONLY* -------- * if the "+" is present in mode, uses O_RDWR The HP-UX code derives from SysV.2. I suspect the difference results from the earlier heritage of BSD from version 7, although I can't easily verify that. > On the hp-ux system the fseek's are effectively no-ops, that is the file > consists of as many numbers as there are writes. This is consistent with the O_APPEND flag to open(2). > Changing the "a" to a "r+" in the fopen works fine if the file exists, > but won't create a new file. At least this is consistent between the two systems. > "a+" seems to behave the same as "a". In all cases the fseek returns a > 0, indicating success. The fseek _does_ succeed, but the file pointer is repositioned at the time of the write by the OS. > A workaround is easy enough to implement, but it is annoying to have to > #ifdef the code. As Kathy mentions, the "w" mode will work and it is also the same on both systems. Just remember that it truncates the file, so if you're planning on reading the old number before writing a new one, you'll have a problem. If this is the case, you might consider splitting the create operation from the fopen so you can share code without ifdef. Whichever you use, this will be necessary in porting to other SysV (and as Kathy also mentions, POSIX) conformant systems as well. > I am not sure whether the difference is a bug in either the BSD or hp-ux > system, or some BSD/System V semantic difference. Does anyone know? From the description: "a" append: open for writing at end of file, or create for writing it sure seems like it was intended that O_APPEND was to be used. > Tom Arons Internet: arons@iris.ucdavis.edu Rob Robason