C11 Working Draft Standard N1570 said that on page 306 at "7.21.5.3 The fopen function" section
Opening a file with append mode ('a' as the first character in the mode argument) causes all subsequent writes to the file to be forced to the then current end-of-file, regardless of intervening calls to the fseek function. ...
Can anybody confirms that not only fseek function but also other file positioning function such as fsetpos and rewind can't intervene the append mode?
Well, the standard on page 338 said that rewind does a similar thing with (void)fseek(stream, 0L, SEEK_SET) except that the error indicator for the stream is also cleared. But as far as I have read on page 337 the standard does not state that fsetpos similar to fseek.
Source Code to illustrate this problem
#include <stdio.h>
// Declare the File Pointer
FILE *fp;
// Declare the test integer variable
int TEST;
// declare the test position variable for fsetpos test
fpos_t POSITION;
void WriteData(int choice){
// Clear the file content
fp = fopen("test.bin", "wb"); fclose(fp);
// Reopen the file with ab
fp = fopen("test.bin", "ab");
// Initialize the test integer variable
TEST = 100;
// Write five sample data
int i;
for(i = 1; i <= 5; i++) {
fwrite(&TEST, sizeof(TEST), 1, fp);
// If two data were written then save the position
if( i == 2 )
fgetpos(fp, &POSITION);
}
// Change the data
TEST = 54321;
// Declare the test case
switch(choice){
case 1 : fseek(fp, (long) 2*sizeof(TEST), SEEK_SET); break;
case 2 : rewind(fp); break;
case 3 : fsetpos(fp, &POSITION); break;
}
// Write the data again
fwrite(&TEST, sizeof(TEST), 1, fp);
// Close the file
fclose(fp);
}
void ReadData(){
// Open the file for read
fp = fopen("test.bin", "rb");
printf("\n [OUTPUT]");
// while the data can be read then print it to the console
while( fread(&TEST, sizeof(TEST), 1, fp) == 1)
printf("\n %d", TEST);
// Close the file
fclose(fp);
}
int main(){
/* Test Case Process */
printf("\n\n Intervene using fseek(fp, (long) 2*sizeof(TEST), SEEK_SET);");
WriteData(1);
ReadData();
printf("\n\n Intervene using rewind(fp);");
WriteData(2);
ReadData();
printf("\n\n Intervene using fsetpos(fp, &POSITION);");
WriteData(3);
ReadData();
return 0;
}
The desired output:
Intervene using fseek(fp, (long) 2*sizeof(TEST), SEEK_SET);
[OUTPUT]
100
100
100
100
100
54321
Intervene using rewind(fp);
[OUTPUT]
100
100
100
100
100
54321
Intervene using fsetpos(fp, &POSITION);
[OUTPUT]
100
100
100
100
100
54321
If the output were like that, then the standard does confirms that not only fseek function that can't intervene the subsequent writes, but also rewind and fsetpos. Else if the output were not like that, then the standard does not confirms it.
Finally, If I might re-ask my question again. Does the standard also confirms that not only fseek function that can't intervene the seubsequent writes, but also rewind and fsetpos?
If the standard confirms then please explain where does the statement which indicate the confirmation.
Else if the standard does not confirms then please explain where does the statement which indicate the denial.
About my question, what I need to know is the certainty that standard does confirms the compiler writer must exactly do this or do that etc. in order to confirms the standard, nothing more
ISO C17 (ISO/IEC 9899:2017 - N2176 working draft)
7.21.5.3 The fopen function
...
6 Opening a file with append mode (’a’ as the first character in the mode argument) causes all subsequent writes to the file to be forced to the then current end-of-file, regardless of intervening calls to the fseek function. ...
...
ISO C23 (ISO/IEC 9899:2024 - N3220 working draft)
7.23.5.3 The fopen function
...
6 Opening a file with append mode (’a’ as the first character in the mode argument) causes all subse-quent writes to the file to be forced to the then current end-of-file at the point of buffer flush or actual write, regardless of intervening calls to the fseek, fsetpos, or rewind functions. ...
...
[wg14/wg21 liaison] fopen 'x', 'a' and 'p'
From: Niall Douglas <s_sourceforge_at_[hidden]>
Date: Fri, 27 May 2022 13:23:43 +0000
...
fopen("a"):Opening a file with append mode (\code{'a'} as the first character in the mode argument) causes all subsequent writes to the file to be forced to the current end-of-file at the point of buffer flush or actual write}, regardless of intervening calls to the \code{fseek}, \code{fsetpos}, or \code{rewind} functions. Incrementing the current end-of-file by the amount of data written is atomic with respect to other threads writing to the same file provided the file was also opened in append mode. If the implementation is not capable of incrementing the current end-of-file atomically, it shall fail setting \code{errno} to \code{ENOTSUP} instead of performing non-atomic end-of-file writes.} In some implementations, opening a binary file with append mode (\code{'b'} as the second or third character in the above list of \code{mode} argument values) may initially position the file position indicator for the stream beyond the last data written, because of null character padding.
[Main change: increment of end of file to become atomic]
...
Although the C17 draft (N2176) strictly mentions only fseek. The C23 draft (N3220) and the liaison material explicitly broaden the wording to include fsetpos and rewind, making the specification unambiguous across all File-Positioning Functions.
And despite the fact that the liaison material states that the “Main change” annotation highlights the atomicity addition, the wording change is undeniably present in the final proposal that WG14 moved forward with.
So finally, the mystery has been solved many years later.