The correct way to check readability / writeability of a folder

I wrote a function to check readability / writeability to a folder.

For unit testing, I need to create different cases:

  • a folder with readable and writable files
  • folder with readable files (not writable)
  • A folder that cannot be written and cannot be read.

Here is the code for the function I came to, up to this point:

void FileUtils::checkPath(std::string path, bool &readable, bool &writable) { namespace bf = boost::filesystem; std::string filePath = path + "/test.txt"; // remove a possibly existing test file remove(filePath.c_str()); // check that the path exists if(!bf::is_directory(path)) { readable = writable = false; return; } // try to write in the location std::ofstream outfile (filePath.c_str()); outfile << "I can write!" << std::endl; outfile.close(); if(!outfile.fail() && !outfile.bad()) { writable = true; } // look for a file to read std::ifstream::pos_type size; char * memblock; for (bf::recursive_directory_iterator it(path); it != bf::recursive_directory_iterator(); ++it) { if (!is_directory(*it)) { std::string sFilePath = it->path().string(); std::ifstream file(sFilePath.c_str(), std::ios::in|std::ios::binary|std::ios::ate); if (file.is_open()) { size = file.tellg(); if(size > 0) { memblock = new char [1]; file.seekg (0, std::ios::beg); file.read (memblock, 1); file.close(); delete[] memblock; if(!file.fail() && !file.bad()) { readable = true; } break; } } else { // there is a non readable file in the folder // readable = false; break; } } } // delete the test file remove(filePath.c_str()); } 

Now with tests (with Google tests):

 TEST_F(FileUtilsTest, shouldCheckPath) { // given an existing folder namespace fs = boost::filesystem; fs::create_directory("/tmp/to_be_deleted"); bool readable = false, writable = false; FileUtils::checkPath("/tmp/to_be_deleted",readable, writable); fs::boost::filesystem::remove_all("/tmp/to_be_deleted"); EXPECT_TRUE(readable && writable); } 

I will add more for other occasions when I go further.

Now the game is open to offer the best solution :-)

+4
source share
2 answers

A safe way to check permissions is to literally check file mode. For directory permissions, the read and write values โ€‹โ€‹may be unexpected:

  • Read - allows you to display the contents of a directory
  • Write - allows you to create, rename, delete files from the directory, significantly changing the list of contents (also required to be executed)
  • Execute - allows you to access (both read and write) and change the properties of files in a directory

So, if you have a directory with the execution bit set, you can still read and write files inside. By turning the execution bit, you can disable access to files. As for the contained files, most of which you can find out from the directory permissions:

  • --x or rx : existing files can be read and written to
  • -wx or rwx : existing files can be read and written, files can be created, renamed and deleted.
  • otherwise: you do not have access to files at all

To determine if a file is read but not written (or vice versa), you need to check the permissions of the file itself. The directory can only specify access to files in general.

You can use stat () or access () (see Bovi's comment) to find out permissions for a file or directory. Since you are already using boost, you can also use boost :: filesystem :: status () , which simply wraps stat ().

+4
source

To be portable and correct, the only way to check the readability / writeability of a file / directory is to read / write from / to it. Permission models can be quite complex and not portable (for example, ACLs), so you cannot just check permissions on the parent directory. In addition, verification and then attempting to record is a race condition, since permissions may change between verification and recording.

If instead you need a high probability that the recording will be successful, for example, if you allow the user to select a folder from scratch for your application, just try to write a file and then delete its afterword. This allows you to know that the directory was writable during user selection.

To be reliable, always assume that file system operations will fail and are designed so that when they do, something logical will happen, not a crash. In particular, design the system so that the user can determine where the permission error is - since there are many resolution methods that can be set incorrectly, useful error messages go a long way.

0
source

Source: https://habr.com/ru/post/1435919/


All Articles