Versions Compared

Key

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

Files can often be identified by other attributes in addition to the file name, for example, by comparing file ownership or creation time. For example, you can store information on Information about a file that you have has been created and closed , can be stored and then use this information used to validate the identity of the file when you reopen it is reopened.

Comparing multiple attributes of the file improves increases the probability that you have correctly identified the appropriate filelikelihood that the reopened file is the same file that had been previously operated on.

Non-Compliant Code Example

This non-compliant code example relies exclusively on the file name to identify the file object.

Code Block
bgColor#FFCCCC
FILE *fd = fopen(filename, "rw");
if (fd) {
  /*...*/ write to file */
  fclose(fd);
}
else {
  /* handle fileerror openedcondition */
}

/* reopen filename */
fd = fopen(filename, "r");
if (fd) {
  /* read from file */
  fclose(fd);
}
else {
  /* handle error condition */
}

There is no guarantee that the file opened for reading is the same file that was opened for writing.

Compliant Solution (POSIX)

...

Code Block
bgColor#ccccff
struct stat st;
dev_t dev; /* device */
ino_t ino; /* file serial number */

int fd = open(filename, O_RDWRWRONLY);
if ((fd != -1) && (fstat(fd, &st) != -1)) {
  ino = st.st_ino;
  dev = st.st_dev; 
  /* write to file */
  close(fd);
}
else {
  /* handle error condition */
}

/* reopen previously written file */
fd = open(filename, O_RDONLY);
if ((fd != -1) &&
    (fstat(fd, &st) != -1) &&
    (st.st_ino == ino) &&
    (st.st_dev == dev)
   ) {
   /* ... read from file */
}
  close(fd);
}
else {
  /* handle error condition */
}

The structure members st_mode, st_ino, st_dev, st_uid, st_gid, st_atime, st_ctime, and st_mtime should all have meaningful values for all file types on POSIX compliant systems. The st_ino field contains the file serial number. The st_dev field identifies the device containing the file. The st_ino and st_dev, taken together, uniquely identifies the file. The st_dev value is not necessarily consistent across reboots or system crashes, however.

Wiki Markup
It is also necessary to call the {{fstat()}} function on an already opened file, rather than calling {{stat()}} on a file name followed by {{open()}} to ensure the file for which the information is being collected is the same file which is opened.  See \[[FIO01-A. Be careful using functions that use file names for identification]\] for more information on avoiding race conditions resulting from the use of file names for identification.

Compliant Solution (POSIX)

...

Code Block
bgColor#ccccff
struct stat st;
dev_t dev = 773; /* device */
ino_t ino = 11321585;  /* file serial number */
FILE *fd = fopen(filename, "r");
if ((fd) &&
    (fstat(fileno(fd), &st) != -1) &&
    (st.st_ino == ino) &&
    (st.st_dev == dev)
    ) {
   /* ... */
}
fclose(fd);

...