Search code examples
clinuxfilefile-descriptor

How to delete a file in C using a file-descriptor?


In my code, I create a file with a random name using mkstemp() function (Im on Linux). What this function returns is an int being a file descriptor.

int fd;
char temp[] = "tempXXXXXX";

fd = mkstemp(temp);

Later I can access the file using fdopen() through that int file descriptor.

FILE *file_ptr = NULL;

file_ptr = fdopen(fd);

But at the end of my program, I would like to see if the file still exists with the random name it was given when I created it (the program should change that file name if successful). I can set a flag if the rename() function run on that file is successful, but I still don't know how to delete it when I only have its file descriptor.

if rename files => remove the temp file

How can I do that? Or is there a way to get the files name if I have its file descriptor?


Solution

  • Neither C nor POSIX (since you are using POSIX library functions) defines a way to delete a file via an open file descriptor. And that makes sense, because the kind of deletion you're talking about is actually to remove a directory entry, not the file itself. The same file can be hard linked into the directory tree in multiple places, with multiple names. The OS takes care of removing its data from storage, or at least marking it as available for reuse, after the last hard link to it is removed from the directory tree and no process any longer has it open.

    A file descriptor is associated directly with a file, not with any particular path, notwithstanding the fact that under many circumstances, you obtain one via a path. This has several consequences, among them that once a process opens a file, that file cannot be pulled out from under it by manipulating the directory tree. And that is the basis for one of the standard approaches to your problem: unlink (delete) it immediately after opening it, before losing its name. Example:

    #include <stdlib.h>
    #include <unistd.h>
    
    int make_temp_file() {
        char filename[] = "my_temp_file_XXXXXX";
        int fd;
    
        fd = mkstemp(filename);
        if (fd == -1) {
            // handle failure to open ...
        } else {
            // file successfully opened, now unlink it
            int result = unlink(filename);
            // ... check for and handle error conditions ...
        }
    
        return fd;
    }
    

    Not only does that (nearly) ensure that the temp file does not outlive the need for it, but it also prevents the contents from being accessible to users and processes to which the owning process does not explicitly grant access.