Newsgroups: comp.os.msdos.djgpp From: fredex AT fcshome DOT stoneham DOT ma DOT us (fred smith) Subject: Re: Bug in ftruncate or not? X-Newsreader: TIN [version 1.2 PL2] Organization: None! Message-ID: References: <7noh88$a01$1 AT newssrv DOT otenet DOT gr> Date: Fri, 30 Jul 1999 02:07:10 GMT Lines: 95 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Pavlos (trash24379 AT usa DOT net) wrote: : Hello, : I know that most of 'bug' reports are actually a fault of the user... Do I : do something wrong here? I don't know about DJGPP, but on Linux it also fails to truncate. And I think I know why... Here's an excerpt from the ftruncate man page on RH 5.2: Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file posi- tioning function intervene between output and input, unless an input operation encounters end-of-file. (If this condition is not met, then a read is allowed to return the result of writes other than the most recent.) Therefore it is good practice (and indeed sometimes neces- sary under Linux) to put an fseek or fgetpos operation between write and read operations on such a stream. This operation may be an apparent no-op (as in fseek(..., 0L, SEEK_CUR) called for its synchronizing side effect. Apparently the ftruncate is considered to be an input function. Does anybody know why? If you add: fseek (f, 0L, SEEK_CUR); immediately before the ftruncate it works fine. If this is the same behavior you see on DJGPP then I'd guess it's correct since they are separate implementations. Anybody got a copy of "the standard" handy? BTW, the second parameter of fseek is type long, so your code is potentially broken, depending on sizeof(int) on your platform. Fred : This simple program will truncate the file only if you comment out #define : BUGGY. : At least in my PC... : If you don't comment #define BUGGY, it won't truncate the file. : Here is the code. : When you run it, press '1' the first time to create the file. Then run it : again and press '2' to truncate it. : Thank you. : Pavlos : <--- cut here ---> : #include : #include : #define BUGGY : int main(int argc, char **argv) : { : FILE *f; : char buf[1000]; : printf("1: Create file (1000 bytes), 2:Truncate file (to 500)\n"); : printf("Your choice: "); : switch(getch()) : { : case '1': : f = fopen("TEST1234.$$$", "wb+"); : fwrite(buf, 1000, 1, f); : return(0); : case '2': : f = fopen("TEST1234.$$$", "rb+"); : fread(buf, 1000, 1, f); : #ifdef BUGGY : fseek(f, 500, SEEK_SET); : fwrite(buf, 500, 1, f); : #endif : ftruncate(fileno(f), 500); : return(0); : default: : return(0); : } : } : <--- cut here ---> -- ---- Fred Smith -- fredex AT fcshome DOT stoneham DOT ma DOT us ----------------------------- I can do all things through Christ who strengthens me. ------------------------------ Philippians 4:13 -------------------------------