From 374975a73c1b930fad168e9b4ad873912080661d Mon Sep 17 00:00:00 2001 From: Scott Lamb Date: Sat, 30 Apr 2016 08:38:29 -0700 Subject: [PATCH] On startup, ensure --sample_file_dir is writable. --- src/filesystem.cc | 4 ++++ src/filesystem.h | 4 ++++ src/moonfire-nvr-main.cc | 16 ++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/filesystem.cc b/src/filesystem.cc index b1d18b5..4a05944 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -65,6 +65,10 @@ class RealFile : public File { ~RealFile() final { Close(); } + int Access(const char *path, int mode, int flags) final { + return faccessat(fd_, path, mode, flags) < 0 ? errno : 0; + } + int Close() final { if (fd_ < 0) { return 0; diff --git a/src/filesystem.h b/src/filesystem.h index a5adaad..bc55ffa 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -58,6 +58,9 @@ class File { // Close the file, ignoring the result. virtual ~File() {} + // faccessat(), returning 0 on success or errno>0 on failure. + virtual int Access(const char *path, int mode, int flags) = 0; + // Close the file, returning 0 on success or errno>0 on failure. // Already closed is considered a success. virtual int Close() = 0; @@ -92,6 +95,7 @@ class File { class MockFile : public File { public: + MOCK_METHOD3(Access, int(const char *, int, int)); MOCK_METHOD0(Close, int()); // The std::unique_ptr variants of Open are wrapped here because gmock's diff --git a/src/moonfire-nvr-main.cc b/src/moonfire-nvr-main.cc index 00c2451..4f0d9c2 100644 --- a/src/moonfire-nvr-main.cc +++ b/src/moonfire-nvr-main.cc @@ -131,13 +131,25 @@ int main(int argc, char** argv) { env.video_source = moonfire_nvr::GetRealVideoSource(); std::unique_ptr sample_file_dir; + std::string sample_file_dirname = FLAGS_sample_file_dir; int ret = moonfire_nvr::GetRealFilesystem()->Open( - FLAGS_sample_file_dir.c_str(), O_DIRECTORY | O_RDONLY, &sample_file_dir); + sample_file_dirname.c_str(), O_DIRECTORY | O_RDONLY, &sample_file_dir); if (ret != 0) { - LOG(ERROR) << "Unable to open --sample_file_dir=" << FLAGS_sample_file_dir + LOG(ERROR) << "Unable to open --sample_file_dir=" << sample_file_dirname << ": " << strerror(ret) << "; exiting."; exit(1); } + + // Separately, ensure the sample file directory is writable. + // (Opening the directory above with O_DIRECTORY|O_RDWR doesn't work even + // when the directory is writable; it fails with EISDIR.) + ret = sample_file_dir->Access(".", W_OK, 0); + if (ret != 0) { + LOG(ERROR) << "--sample_file_dir=" << sample_file_dirname + << " is not writable: " << strerror(ret) << "; exiting."; + exit(1); + } + env.sample_file_dir = sample_file_dir.release(); moonfire_nvr::Database db;