Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

However, section 7.19.5.3 of C99 places the following restriction restrictions on update streams:

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file. Opening (or creating) a text file with update mode may instead open (or create) a binary stream in some implementations.

...

The following non-compliant code reads appends data from to a presumably random area of a file , and then appends data to the end of itreads from the same file.

Code Block
bgColor#ffcccc
char data[BUF_SIZESIZ];
char append_data[BUF_SIZESIZ];
size_t append_size;
FILE *FILE *file;

file = fopen(file_name, "a+");
if (file == NULL) {
  /* handle error */
}

if (fread(/* Initialize append_data */

if(fwrite(append_data, BUF_SIZ, 1, filedata) != 0BUF_SIZ) {
  /* Handle there not being data error */
}

/* Do something with data 
   Initialize append_data and append_size */

if(fwrite(append_if (fread(data, appendBUF_sizeSIZ, 1, datafile) != append_size0) {
  /* Handle error there not being data */
}

fclose(file);

However, since the stream is not flushed in between the call to fread() and fwrite(), undefined behavior results.

...

In this compliant solution, fflush() is called in between the output and input, removing the undefined behavior.

Code Block
bgColor#ffcccc#ccccff
char data[BUF_SIZESIZ];
char append_data[BUF_SIZESIZ];
size_t append_size;
FILE *FILE *file;

file = fopen(file_name, "a+");
if (file == NULL) {
  /* handle error */
}

/* Initialize append_data */

if (freadfwrite(append_data, BUF_SIZ, 1, filedata) != 0BUF_SIZ) {
  /* Handle there not being dataerror */
}

/* Do something with data 
   Initialize append_data and append_size */

fflush(file);

if (fwritefread(append_data, appendBUF_sizeSIZ, 1, datafile) != append_size0) {
  /* Handle error there not being data */
}

fclose(file);

Risk Assessment

...