Path: news1.icaen!news.uiowa.edu!chi-news.cic.net!arclight.uoregon.edu!news.bc.net!unixg.ubc.ca!rover.ucs.ualberta.ca!Myrias.AB.CA!eddore.myrias.com!eddore.myrias.com!not-for-mail From: gdr@eddore.myrias.com (Devin Reade) Newsgroups: comp.sys.apple2.programmer Subject: problem with fread (Orca/C v2.1) Date: 10 Nov 1996 14:43:48 -0700 Organization: Myrias Research Corporation Lines: 161 Message-ID: <565iak$2ph@eddore.myrias.com> NNTP-Posting-Host: eddore.myrias.com Provided for your information: This problem was first noticed by Norman Dodge. Very briefly, it seems that fread under Orca/C v2.1 reuses it's buffer contents on the second invocation. I've already emailed both Mike and Soenke on this. I just noticed that I should have followed the first two perror() calls with an exit(). Oh well ... =========== cut here =========== /* * This file demonstrates two problems with Orca/C v2.1 that were * not present in Orca/C v2.0.3. One is with ferror(3), the other * is with fread(3). (Actually, the symptoms occur in fread. Since * there are zero diffs between the the Orca fread sources between * v2.0.3 and v2.1, it's probably elsewhere -- unless my sources that * date from teh v2.0.3 period don't correspond to the v2.0.3 libraries.) * * In order to run this program, you need an input data file, with * arbitrary contents. The one I used was 2979 bytes long. * * See the description below. These problems were first noted by * Norman Dodge . This test was written * by Devin Reade . I have not yet examined the * library sources as to the cause of the error. */ #pragma keep "stdiotest" #pragma lint -1 #pragma debug 25 #include #define INFILE "data.in" #define OUTFILE "data.out" #define BUFFERSIZE 10 /* * Using a bare Orca/C v2.0.3 system, we get the following results for * a 2979 byte file (no resource fork), as expected: * * feof (data.in) = 0 * ferror(data.in) = 0 * done 298 loops (2979 bytes) * feof (data.in) = 128 * ferror(data.in) = 0 * * When METHOD is 0, we get (on a sample text file of 2979 bytes, no * resource fork), we get: * * feof (data.in) = 0 * ferror(data.in) = 0 * done 1 loops (10 bytes) * feof (data.in) = 0 * ferror(data.in) = 256 * * This shows that ferror is getting set prematurely. * * When METHOD is 1 (same input file), we get: * * feof (data.in) = 0 * ferror(data.in) = 0 * done 401 loops (4003 bytes) * feof (data.in) = 128 * ferror(data.in) = 256 * * Note that the latter is exactly 1024 bytes more than is expected, which * is the size of the default stream buffer. * * This latter test makes it appear that it appears that fread(3) is * initially reusing the contents of its internal buffer. In other words, * instead of: * * do until eof * fill buffer * while (stuff left in buffer) * provide user with bytes requested * end while * enddo * * it appears that we get: * * count = 1 * fill buffer * do until eof * while (stuff left in buffer) * provide user with bytes requested * end while * if (count > 1) { <-- this should be non-conditional * fill buffer * } * count = count + 1 * enddo */ #define METHOD 1 int main (int argc, char **argv) { FILE *fpin, *fpout; static char buffer[BUFFERSIZE]; size_t totalWritten, loopCount, count; totalWritten = 0; loopCount = 0; if ((fpin = fopen(INFILE, "r")) == NULL) { perror("couldn't open input file"); } if ((fpout = fopen(OUTFILE, "w")) == NULL) { perror("couldn't open output file"); } /* both of these should return zero */ printf("feof (%s)\t= %d\n", INFILE, feof(fpin)); printf("ferror(%s)\t= %d\n", INFILE, ferror(fpin)); #if METHOD == 0 while (!feof(fpin) && !ferror(fpin)) { count = fread (buffer, sizeof(char), BUFFERSIZE, fpin); if (count > 0) { fwrite (buffer, sizeof(char), count, fpout); } totalWritten += count; loopCount++; } #elif METHOD == 1 for(;;) { int done = 0; count = fread(buffer, sizeof(char), BUFFERSIZE, fpin); if (count < BUFFERSIZE) { if (ferror(fpin)) { perror("error on input file"); } done = 1; } fwrite (buffer, sizeof(char), count, fpout); totalWritten += count; loopCount++; if (done) { break; } } #else #error unknown method #endif printf("done %ld loops (%ld bytes)\n", loopCount, totalWritten); /* the first of these should return 1, the second zero */ printf("feof (%s)\t= %d\n", INFILE, feof(fpin)); printf("ferror(%s)\t= %d\n", INFILE, ferror(fpin)); fclose(fpin); fclose(fpout); return 0; } -- Devin Reade gdr@eddore.myrias.ab.ca