The standard library has a function readonly()
in the std::fs::Permissions
crate.
But this function doesn't indicate if we have the right to write inside a file.
See the following code:
use std::fs::File;
fn main() -> std::io::Result<()> {
let f = File::open("/bin/ls")?;
let readonly = f.metadata()?.permissions().readonly();
println!("Is `/bin/ls` readonly ?");
match readonly {
true => println!("Yes"),
false => println!("No"),
}
Ok(())
}
❯ cargo run -q
Is `/bin/ls` readonly ?
No
❯ ls -l /bin/ls
-rwxr-xr-x 1 root root 138216 févr. 8 2024 /bin/ls
root
has the right to write (rwx
), so the file is not considered as readonly.
Proposition
I suggest adding a function writeable()
inside the std::fs::Permissions
crate.
This function would return a bool
:
true
if we have the right to write.false
if we don't have the right to write.
Reasoning and drawback
Drawback
The drawback of adding this function is that users might try to check if they have the permission of the file before writing to it.
Like in this forum discussion : How to test std::fs::File has write permission - #4 by bigdogs - help - The Rust Programming Language Forum.
A better pattern is to write to the file, and handle any error to avoid TOCTOU race conditions.
Advantage
Rust already forces the user to handle the error. Which mostly mitigates the TOCTOU race conditions.
On the flip side, there are legitimate reasons to check if we have the right to write inside a file.
In my case, I am writing an hexadecimal editor. It would be nice to inform the user that he doesn't have the possibility to write inside the file.
Vim does it when we try to edit a file without the correct permissions. This is a common problem, and it would be nice to have a cross-platform way to check if we have the rights for this operation.
Workaround
It's always possible of writing inside a file, and restore it. But such an operation would change the date of the last modification despite no changes being performed.