The fwrite function is not returning error, if the file was removed.

The fwrite function call is not returning error, when the file it writes to is removed, please advise on how to find if the file already opened and being written by a program is removed manually or by some other process.

please see the code below,

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
  int cnt = 10;
  int index;
  int count;
  FILE *fp;
  char message[50] = "writing to example file";

  fp = fopen("example","a");

  if (fp == NULL)
  {
    printf("opening file example failed\n");
    exit(01);
  }
  for (index = 0;index <= cnt;index++)
  {

    count = fwrite(message,sizeof(message),1,fp);
    fflush(fp);
    if (count != 1)
    {
      printf("Error writing to file example\n");
    }
    else
    {
      printf("data written to file example successfully\n");
    }
    sleep(20);
  }
  fclose(fp);
  return(00);
}

the above code was executed, I just left the file alone during the first two loops and then removed the file during the sleep and after that as well, the program is printing the success message, even though the file is not available.

Please advise.:b:

The file no longer has any links in the filesystem, but the file still exists until your application closes the file. (Note that exiting the process closes the file even if you don't explicitly call fclose().) You can see when this happens by checking the link count on the file (as shown in the following example). Obviously, you should add error checking to the fstat() call, but this should work for demonstration purposes:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

int main(void) {
        int             cnt = 10;
        int             count;
        int             index;
        FILE            *fp;
        char            message[50] = "writing to example file";
        struct stat     sbuf;

        fp = fopen("example","a");

        if (fp == NULL) {
                printf("opening file example failed\n");
                exit(01);
        }
        for (index = 0;index <= cnt;index++) {
                count = fwrite(message,sizeof(message),1,fp);
                fflush(fp);
                if (count != 1) {
                        printf("Error writing to file example\n");
                } else {
                        printf("data written to file example successfully\n");
                }
                fstat(fileno(fp), &sbuf);
                printf("Links to example: %d\n", sbuf.st_nlink);

                sleep(20);
        }
        fclose(fp);
        return(00);
}
1 Like

rm uses the unlink system call to "delete" a file. The unlink(2) manual page usually documents the behavior which Don described.

If you also wanted to watch for replacement, you could record the original inode with fstat then monitor the pathname with stat: failure && errno == ENOENT -> file unlinked, success && original_inode != current_inode -> file replaced.

For more efficient but more complicated and unportable monitoring, refer to Linux's inotify or BSD's kqueue.

Regards,
Alister

1 Like

Thanks Don and Alister, for your help !!!
Thanks again:)