diff --git a/src/filesystem.cc b/src/filesystem.cc index 4a05944..3a39fac 100644 --- a/src/filesystem.cc +++ b/src/filesystem.cc @@ -59,12 +59,15 @@ namespace { class RealFile : public File { public: - explicit RealFile(int fd) : fd_(fd) {} + RealFile(re2::StringPiece name, int fd) + : name_(name.data(), name.size()), fd_(fd) {} RealFile(const RealFile &) = delete; void operator=(const RealFile &) = delete; ~RealFile() final { Close(); } + const std::string &name() const { return name_; } + int Access(const char *path, int mode, int flags) final { return faccessat(fd_, path, mode, flags) < 0 ? errno : 0; } @@ -106,7 +109,7 @@ class RealFile : public File { if (ret < 0) { return errno; } - f->reset(new RealFile(ret)); + f->reset(new RealFile(StrCat(name_, "/", path), ret)); return 0; } @@ -145,6 +148,7 @@ class RealFile : public File { } private: + std::string name_; int fd_ = -1; }; @@ -186,7 +190,7 @@ class RealFilesystem : public Filesystem { if (ret < 0) { return errno; } - f->reset(new RealFile(ret)); + f->reset(new RealFile(path, ret)); return 0; } diff --git a/src/filesystem.h b/src/filesystem.h index bc55ffa..ab30b55 100644 --- a/src/filesystem.h +++ b/src/filesystem.h @@ -58,6 +58,9 @@ class File { // Close the file, ignoring the result. virtual ~File() {} + // A name for the file (typically assigned at open time). + virtual const std::string &name() const = 0; + // faccessat(), returning 0 on success or errno>0 on failure. virtual int Access(const char *path, int mode, int flags) = 0; @@ -95,6 +98,7 @@ class File { class MockFile : public File { public: + MOCK_CONST_METHOD0(name, const std::string &()); MOCK_METHOD3(Access, int(const char *, int, int)); MOCK_METHOD0(Close, int()); diff --git a/src/recording.cc b/src/recording.cc index 04bd751..afd26e8 100644 --- a/src/recording.cc +++ b/src/recording.cc @@ -143,7 +143,8 @@ bool SampleFileWriter::Open(const char *filename, std::string *error_message) { int ret = parent_dir_->Open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600, &file_); if (ret != 0) { - *error_message = StrCat("open ", filename, ": ", strerror(ret)); + *error_message = StrCat("open ", filename, " (within dir ", + parent_dir_->name(), "): ", strerror(ret)); return false; } return true;