How to check if I can delete a file in unix

I know that any I/O operation can fail, but I'm trying to reduce the possibilities of any errors.

Some context, I'm writing another Dotfiles Manager (it's in a early stage), and I need to check if I can delete files before I do delete them, because if one of them fail, my program would leave the folder in a messed up state.

Here's my current hack for this, I'll check if I have permissions to write to a file, using append to leave contents as they are:

use std::{fs::OpenOptions, path::Path};

pub fn can_i_delete_it(path: impl AsRef<Path>) -> bool {
    let file = OpenOptions::new()
        .create(false)
        .append(true)
        .open(path.as_ref());
    let ok = file.is_ok();
    ok
}

If I can write to a file, I can delete it too, is this really guaranteed to work with files? What about directories?

The problem I found by using fs::Metadata is that it gives me the mode permission bits but that's all, I wanted a more straight forward way than reading groups and users around.

1 Like

I forgot to mention that I'm new to Rust, so maybe I'm missing something obvious, don't be harsh on me :v .

Deleting a file in POSIX actually only requires write access on its directory to unlink the filename. If that's the last reference to the underlying file, then the filesystem will really delete it. Same for directories, rmdir needs permission on the parent directory.

So the test you want is an access(parent_dir, W_OK) -- but beware of TOCTOU races. That is, just because you have permission now, doesn't mean you still will when you actually attempt it.

You might be better off exploring more robust error recovery, but it's up to you to decide what's possible.

4 Likes

@cuviper, thanks so much for your response! I really appreciate your explanation.

This was for my Dotfiles Manager project, but instead of inserting the functionality inside of my project, I decided to create a public crate for everyone to use your knowledge :wink:.

https://github.com/marcospb19/unix_file_permissions/blob/main/src/functions.rs

This is my first time trying to use FFI, so there's probably room for improvement there.

Thanks for making this possible, there's work in progress, but I plan in releasing it before the end of the month.