gupta@asgb.UUCP (10/25/84)
Description: If a file is opened [using fopen(3S)] in the "r+" mode, read till
the end of file is reached, and then written to using "fprintf(3S)",
the call returns the correct number of characters written to the file
but does NOT append to the file! To recreate the effects, try the
program given below.
Environment: Vax-11/780*, running Unix* 5.2
Solution: ??? (Use sprintf and fputs instead :-)
/* ------- Program to create the problem: -------- */
/*
Bug in stdio routines.
This program finds out the number of lines (assumes line length < LEN)
in a file and then appends line to the file containing the count.
step 1. Compile with code segment 1 and test.
It works.
step 2. Compile with code segment 2 and test.
It doesn't work!
PROGRAM USES fopen.test AS TEST FILE. fopen.test SHOULD EXIST.
*/
#include <stdio.h>
#define INF "fopen.test"
#define LEN 80
main()
{
FILE *fp;
int j = 0;
char line[LEN], *p;
fp = fopen(INF, "r+"); /* Open file for read and update */
while ((p=fgets(line,LEN,fp)) != NULL) /* find num. of lines in file */
j++;
/* Begin segment 1 -- Write the number of lines to string and then
write string to file */
sprintf(line,"%d\n",j);
j = fputs(line,fp);
/* End segment 1 */
/* Begin segment 2 -- Write number of lines to file
j = fprintf(fp,"%d\n",j);
-- End segment 2 */
fprintf(stdout, "Number of chars written: %d\n",j); /* print number of
chars written */
fclose(fp); /* Close file */
exit(0);
}
/* ------------------------- End of program ------------------ */
* Vax-11/780 is a trademark of Digital Equip. Corp.
Unix is a trademark of Bell Labs.
Yogesh Gupta
sdcrdcf -- bmcg!asgb!gupta
sdcsvax -/
mp@allegra.UUCP (Mark Plotnick) (10/29/84)
This bug (sans fix) is documented in the SVR2 release notes booklet. A helpful person at the Lisle hotline said the errors were in *printf.c, in which the code incorrectly uses the | operator to test bit flags. He also pointed out that the printfs work fine on the 3B20 even though the sources are identical! Mark
jm@wlbr.UUCP (James Macropol) (10/31/84)
. <stdio> usually requires an fseek() when switching between read <--> write modes on a file opened in any of the "+" modes. This is to insure that the buffer pointers are set up properly. Jim Macropol {ihnp4,trwrb,scgvaxd,vortex}!wlbr!jm
gupta@asgb.UUCP (11/01/84)
> <stdio> usually requires an fseek() when switching between read <--> write > modes on a file opened in any of the "+" modes. This is to insure that the > buffer pointers are set up properly. > > Jim Macropol > {ihnp4,trwrb,scgvaxd,vortex}!wlbr!jm This is what the Programmer Reference Manual states: - FOPEN(3S) - . - . - . - - When a file is opened for update, both input and output may - be done on the resulting stream. However, output may not be - directly followed by input without an intervening fseek or - rewind, and input may not be directly followed by output - without an intervening fseek, rewind,[1m or an input operation - which encounters end-of-file.[0m Thus, after an input operation that encounters end-of-file, the printf should work. Also, the printf doesn't work even if an fseek is added! Once you start reading the file, you just cannot write it using the printf!! Yogesh Gupta {sdcrdcf, sdcsvax}!bmcg!asgb!gupta
jim@ISM780B.UUCP (11/03/84)
><stdio> usually requires an fseek() when switching between read <--> write >modes on a file opened in any of the "+" modes. This is to insure that the >buffer pointers are set up properly. The manual says fseek isn't necessary of EOF is reached on input.
phil@qfdts.OZ (Phil Chadwick) (11/07/84)
In our release of Sys V r2.0 there were four versions of "printf" containing a bug which directs the output into the bit bucket under some circumstances. The subroutines live in the directory "/usr/src/lib/libc/port/print". They are: fprintf.c version 1.5 ) Our release may well printf.c version 1.5 \ differ from yours. vfprintf.c version 1.1 / Check that the versions vprintf.c version 1.1 ) are the same! These routines all fail under circumstances where: (a) a stream is opened for update, (b) data are read from or written to the stream, (c) an fseek() is issued, (d) one of the above *printf() routines is used to write a small amount of data to the stream (i.e. less than a buffer full), (e) the stream is fflush()'d. The cause of the problem appears to be due to a failure of the printf routines to reset the _cnt field of the appropriate FILE structure from zero to the size of the buffer being used prior to writing to the stream. I applied the following fixes to fprintf.c, printf.c, vfprintf.c and vprintf.c some time ago and have had no further problems: (a) Insert "#include ../stdio/stdiom.h" in each file. (b) For fprintf.c and vfprintf.c replace the first compound if statement with: if(_WRTCHK(iop) != 0) return EOF; (c) For printf.c and vprintf.c replace the first compound if statement with: if(_WRTCHK(stdout) != 0) return EOF; ---- Phil Chadwick Australia: (07) 2296500 Department of Forestry International: +61 7 2296500 PO Box 5 Brisbane, Roma Street SUN: phil:qfdts AUSTRALIA 4001 UUCP: {decvax,vax135}!mulga!phil:qfdts