[alohalytics] FileManager::IsDirectoryWritable()

This commit is contained in:
Alex Zolotarev 2015-06-23 00:02:13 +02:00
parent 7386ab1a3c
commit 36b6624774
2 changed files with 41 additions and 1 deletions

View file

@ -25,6 +25,7 @@ SOFTWARE.
#ifndef FILE_MANAGER_H
#define FILE_MANAGER_H
#include <algorithm>
#include <functional>
#include <fstream>
#include <string>
@ -85,9 +86,32 @@ struct FileManager {
fi.read(&buffer[0], static_cast<std::streamsize>(size));
return buffer;
}
// Returns true if we can write to the specified directory.
static bool IsDirectoryWritable(std::string directory) {
AppendDirectorySlash(directory);
std::string temporary_file = directory;
// For a pseudo-random file we turn directory path into a file name.
std::replace(temporary_file.begin(), temporary_file.end(), kDirectorySeparator, 'Z');
// Make sure it does not exist first.
while (true) {
try {
(void)GetFileSize(directory + temporary_file);
temporary_file += 'Z';
} catch (const std::exception &) {
break;
}
}
return std::string();
const ScopedRemoveFile remover(directory + temporary_file);
bool is_writable = false;
try {
(void)FileManager::AppendStringToFile(temporary_file, remover.file);
if (FileManager::ReadFileAsString(remover.file) == temporary_file) {
is_writable = true;
}
} catch (const std::exception &) {
}
return is_writable;
}
// Executes lambda for each regular file in the directory and stops immediately if lambda returns false.

View file

@ -212,6 +212,21 @@ void Test_GetFileSize() {
// It should also fail for directories.
TEST_EXCEPTION(std::ios_base::failure, FileManager::GetFileSize(FileManager::GetDirectoryFromFilePath(file)));
}
void Test_IsDirectoryWritable() {
const std::string file = GenerateTemporaryFileName();
const ScopedRemoveFile remover(file);
TEST_EQUAL(true, FileManager::IsDirectoryWritable(FileManager::GetDirectoryFromFilePath(file)));
TEST_EQUAL(false, FileManager::IsDirectoryWritable(file));
const std::string not_writable_system_directory =
#ifdef _MSC_VER
"C:\";
#else
"/Users";
#endif
// Suppose you do not run tests as root/Administrator.
TEST_EQUAL(false, FileManager::IsDirectoryWritable(not_writable_system_directory));
}
// ******************* Message Queue tests ******************
@ -490,6 +505,7 @@ int main(int, char * []) {
Test_AppendStringToFile();
Test_ForEachFileInDir();
Test_GetFileSize();
Test_IsDirectoryWritable();
Test_EndsWith();
Test_MessagesQueue_InMemory_Empty();