Skip to content

Commit 48349f8

Browse files
murraynfurszy
authored andcommitted
Provide relevant error message if datadir is not writable.
1 parent 3f94147 commit 48349f8

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

src/init.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,9 @@ static bool LockDataDirectory(bool probeOnly)
11901190
{
11911191
// Make sure only a single PIVX process is using the data directory.
11921192
fs::path datadir = GetDataDir();
1193+
if (!DirIsWritable(datadir)) {
1194+
return UIError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string()));
1195+
}
11931196
if (!LockDirectory(datadir, ".lock", probeOnly)) {
11941197
return UIError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), _(PACKAGE_NAME)));
11951198
}

src/test/util_tests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,22 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory)
10931093
fs::remove_all(dirname);
10941094
}
10951095

1096+
BOOST_AUTO_TEST_CASE(test_DirIsWritable)
1097+
{
1098+
// Should be able to write to the system tmp dir.
1099+
fs::path tmpdirname = fs::temp_directory_path();
1100+
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
1101+
1102+
// Should not be able to write to a non-existent dir.
1103+
tmpdirname = fs::temp_directory_path() / fs::unique_path();
1104+
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), false);
1105+
1106+
fs::create_directory(tmpdirname);
1107+
// Should be able to write to it now.
1108+
BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true);
1109+
fs::remove(tmpdirname);
1110+
}
1111+
10961112
namespace {
10971113

10981114
struct Tracker

src/util/system.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,19 @@ void ReleaseDirectoryLocks()
149149
dir_locks.clear();
150150
}
151151

152+
bool DirIsWritable(const fs::path& directory)
153+
{
154+
fs::path tmpFile = directory / fs::unique_path();
155+
156+
FILE* file = fsbridge::fopen(tmpFile, "a");
157+
if (!file) return false;
158+
159+
fclose(file);
160+
remove(tmpFile);
161+
162+
return true;
163+
}
164+
152165
/**
153166
* Interpret a string argument as a boolean.
154167
*

src/util/system.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
8989
bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
9090
bool RenameOver(fs::path src, fs::path dest);
9191
bool LockDirectory(const fs::path& directory, const std::string& lockfile_name, bool probe_only=false);
92+
bool DirIsWritable(const fs::path& directory);
9293

9394
/** Release all directory locks. This is used for unit testing only, at runtime
9495
* the global destructor will take care of the locks.

0 commit comments

Comments
 (0)