aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2016-02-21 21:38:54 -0500
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2016-02-21 21:38:54 -0500
commit878573f07cadf10fc1c32efd180409ddf854f855 (patch)
treeb5b420e4e4ec823bc9fe63206e1bb8a777d51709
parentfa0cb2cf4e0b52e57f50b2b8cc25228d481abc31 (diff)
operations: Abstract away common exception-handling
-rw-r--r--src/operations.cc316
1 files changed, 119 insertions, 197 deletions
diff --git a/src/operations.cc b/src/operations.cc
index 4433809..e4e76b3 100644
--- a/src/operations.cc
+++ b/src/operations.cc
@@ -46,7 +46,7 @@ namespace {
// Pointer to the directory underlying the mount point.
File* root_;
-mode_t DirectoryTypeToFileType(const unsigned char type) noexcept {
+mode_t DirectoryTypeToFileType(const unsigned char type) {
return static_cast<mode_t>(DTTOIF(type));
}
@@ -61,39 +61,25 @@ void* Initialize(fuse_conn_info*) noexcept { return nullptr; }
void Destroy(void*) noexcept {}
-int Getattr(const char* const c_path, struct stat* output) noexcept {
- try {
- const std::string path(c_path);
- if (path == "/") {
- *output = root_->Stat();
- } else {
- *output = root_->LinkStatAt(EncodePath(path).c_str());
- }
- return 0;
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "getattr: caught unexpected value";
- return -ENOTRECOVERABLE;
+int Getattr(const char* const c_path, struct stat* output) {
+ const std::string path(c_path);
+ if (path == "/") {
+ *output = root_->Stat();
+ } else {
+ *output = root_->LinkStatAt(EncodePath(path).c_str());
}
+ return 0;
}
int Fgetattr(const char*, struct stat* const output,
- struct fuse_file_info* const file_info) noexcept {
- try {
- *output = reinterpret_cast<File*>(file_info->fh)->Stat();
- return 0;
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "getattr: caught unexpected value";
- return -ENOTRECOVERABLE;
- }
+ struct fuse_file_info* const file_info) {
+ *output = reinterpret_cast<File*>(file_info->fh)->Stat();
+ return 0;
}
template <typename T>
int OpenResource(const char* const c_path, const int flags,
- uint64_t* const handle) noexcept {
+ uint64_t* const handle) {
try {
const std::string path(c_path);
std::unique_ptr<T> t(new T(
@@ -104,11 +90,6 @@ int OpenResource(const char* const c_path, const int flags,
return 0;
} catch (const std::bad_alloc&) {
return -ENOMEM;
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "caught unexpected value";
- return -ENOTRECOVERABLE;
}
}
@@ -118,206 +99,145 @@ int ReleaseResource(const uint64_t handle) noexcept {
return 0;
}
-int Mknod(const char* const c_path, const mode_t mode,
- const dev_t dev) noexcept {
- try {
- const std::string path(c_path);
- if (path == "/") {
- return -EISDIR;
- } else {
- root_->MkNod(EncodePath(path).c_str(), mode, dev);
- return 0;
- }
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "mknod: caught unexpected value";
- return -ENOTRECOVERABLE;
+int Mknod(const char* const c_path, const mode_t mode, const dev_t dev) {
+ const std::string path(c_path);
+ if (path == "/") {
+ return -EISDIR;
+ } else {
+ root_->MkNod(EncodePath(path).c_str(), mode, dev);
+ return 0;
}
}
-int Chmod(const char* const c_path, const mode_t mode) noexcept {
- try {
- const std::string path(c_path);
- root_->ChModAt(path == "/" ? "." : EncodePath(path).c_str(), mode);
- return 0;
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "getattr: caught unexpected value";
- return -ENOTRECOVERABLE;
- }
+int Chmod(const char* const c_path, const mode_t mode) {
+ const std::string path(c_path);
+ root_->ChModAt(path == "/" ? "." : EncodePath(path).c_str(), mode);
+ return 0;
}
-int Rename(const char* const c_old_path,
- const char* const c_new_path) noexcept {
- try {
- const std::string old_path(c_old_path);
- const std::string new_path(c_new_path);
- if (old_path == "/" || new_path == "/") {
- return -EINVAL;
- } else {
- root_->RenameAt(EncodePath(old_path).c_str(),
- EncodePath(new_path).c_str());
- return 0;
- }
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "mknod: caught unexpected value";
- return -ENOTRECOVERABLE;
+int Rename(const char* const c_old_path, const char* const c_new_path) {
+ const std::string old_path(c_old_path);
+ const std::string new_path(c_new_path);
+ if (old_path == "/" || new_path == "/") {
+ return -EINVAL;
+ } else {
+ root_->RenameAt(EncodePath(old_path).c_str(), EncodePath(new_path).c_str());
+ return 0;
}
}
-int Open(const char* const path, fuse_file_info* const file_info) noexcept {
+int Open(const char* const path, fuse_file_info* const file_info) {
return OpenResource<File>(path, file_info->flags, &file_info->fh);
}
int Read(const char*, char* const buffer, const size_t bytes,
- const off_t offset, fuse_file_info* const file_info) noexcept {
- LOG(INFO) << "read with offset " << offset;
- try {
- auto* const file = reinterpret_cast<File*>(file_info->fh);
- const std::vector<std::uint8_t> read = file->Read(offset, bytes);
- std::memcpy(buffer, read.data(), read.size());
- return static_cast<int>(read.size());
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "read: caught unexpected value";
- return -ENOTRECOVERABLE;
- }
+ const off_t offset, fuse_file_info* const file_info) {
+ auto* const file = reinterpret_cast<File*>(file_info->fh);
+ const std::vector<std::uint8_t> read = file->Read(offset, bytes);
+ std::memcpy(buffer, read.data(), read.size());
+ return static_cast<int>(read.size());
}
int Write(const char*, const char* const buffer, const size_t bytes,
- const off_t offset, fuse_file_info* const file_info) noexcept {
- try {
- auto* const file = reinterpret_cast<File*>(file_info->fh);
- const std::vector<std::uint8_t> to_write(buffer, buffer + bytes);
- file->Write(offset, to_write);
- return static_cast<int>(bytes);
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "read: caught unexpected value";
- return -ENOTRECOVERABLE;
- }
+ const off_t offset, fuse_file_info* const file_info) {
+ auto* const file = reinterpret_cast<File*>(file_info->fh);
+ const std::vector<std::uint8_t> to_write(buffer, buffer + bytes);
+ file->Write(offset, to_write);
+ return static_cast<int>(bytes);
}
-int Utimens(const char* const c_path, const timespec times[2]) noexcept {
- try {
- const std::string path(c_path);
- root_->UTimeNs(path == "/" ? "." : EncodePath(path).c_str(), times[0],
- times[1]);
- return 0;
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "utimens: caught unexpected value";
- return -ENOTRECOVERABLE;
- }
+int Utimens(const char* const c_path, const timespec times[2]) {
+ const std::string path(c_path);
+ root_->UTimeNs(path == "/" ? "." : EncodePath(path).c_str(), times[0],
+ times[1]);
+ return 0;
}
-int Release(const char*, fuse_file_info* const file_info) noexcept {
+int Release(const char*, fuse_file_info* const file_info) {
return ReleaseResource<File>(file_info->fh);
}
-int Unlink(const char* c_path) noexcept {
- try {
- const std::string path(c_path);
- if (path == "/") {
- // Removing the root is probably a bad idea.
- return -EPERM;
- } else {
- root_->UnlinkAt(EncodePath(path).c_str());
- return 0;
- }
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "unlink: caught unexpected value";
- return -ENOTRECOVERABLE;
+int Unlink(const char* c_path) {
+ const std::string path(c_path);
+ if (path == "/") {
+ // Removing the root is probably a bad idea.
+ return -EPERM;
+ } else {
+ root_->UnlinkAt(EncodePath(path).c_str());
+ return 0;
}
}
-int Mkdir(const char* const c_path, const mode_t mode) noexcept {
- try {
- const std::string path(c_path);
- if (path == "/") {
- // They're asking to create the mount point. Huh?
- return -EEXIST;
- } else {
- root_->MkDir(EncodePath(path).c_str(), mode);
- return 0;
- }
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "mknod: caught unexpected value";
- return -ENOTRECOVERABLE;
+int Mkdir(const char* const c_path, const mode_t mode) {
+ const std::string path(c_path);
+ if (path == "/") {
+ // They're asking to create the mount point. Huh?
+ return -EEXIST;
+ } else {
+ root_->MkDir(EncodePath(path).c_str(), mode);
+ return 0;
}
}
-int Opendir(const char* const path, fuse_file_info* const file_info) noexcept {
+int Opendir(const char* const path, fuse_file_info* const file_info) {
return OpenResource<Directory>(path, O_DIRECTORY, &file_info->fh);
}
int Readdir(const char*, void* const buffer, fuse_fill_dir_t filler,
- const off_t offset, fuse_file_info* const file_info) noexcept {
- try {
- auto* const directory = reinterpret_cast<Directory*>(file_info->fh);
+ const off_t offset, fuse_file_info* const file_info) {
+ auto* const directory = reinterpret_cast<Directory*>(file_info->fh);
- static_assert(std::is_same<off_t, long>(),
- "off_t is not convertible with long");
- if (offset != directory->offset()) {
- directory->Seek(offset);
- }
+ static_assert(std::is_same<off_t, long>(),
+ "off_t is not convertible with long");
+ if (offset != directory->offset()) {
+ directory->Seek(offset);
+ }
- for (std::experimental::optional<dirent> entry = directory->ReadOne();
- entry; entry = directory->ReadOne()) {
- struct stat stats;
- std::memset(&stats, 0, sizeof(stats));
- stats.st_ino = entry->d_ino;
- stats.st_mode = DirectoryTypeToFileType(entry->d_type);
- const off_t next_offset = directory->offset();
- if (filler(buffer, entry->d_name, &stats, next_offset)) {
- break;
- }
+ for (std::experimental::optional<dirent> entry = directory->ReadOne(); entry;
+ entry = directory->ReadOne()) {
+ struct stat stats;
+ std::memset(&stats, 0, sizeof(stats));
+ stats.st_ino = entry->d_ino;
+ stats.st_mode = DirectoryTypeToFileType(entry->d_type);
+ const off_t next_offset = directory->offset();
+ if (filler(buffer, entry->d_name, &stats, next_offset)) {
+ break;
}
- } catch (const std::system_error& e) {
- return -e.code().value();
- } catch (...) {
- LOG(ERROR) << "readdir: caught unexpected value";
- return -ENOTRECOVERABLE;
}
-
return 0;
}
-int Releasedir(const char*, fuse_file_info* const file_info) noexcept {
+int Releasedir(const char*, fuse_file_info* const file_info) {
return ReleaseResource<Directory>(file_info->fh);
}
-int Rmdir(const char* c_path) noexcept {
+int Rmdir(const char* c_path) {
+ const std::string path(c_path);
+ if (path == "/") {
+ // Removing the root is probably a bad idea.
+ return -EPERM;
+ } else {
+ root_->RmDirAt(EncodePath(path).c_str());
+ return 0;
+ }
+}
+
+template <typename Function, Function f, typename... Args>
+int CatchAndReturnExceptions(Args... args) noexcept {
try {
- const std::string path(c_path);
- if (path == "/") {
- // Removing the root is probably a bad idea.
- return -EPERM;
- } else {
- root_->RmDirAt(EncodePath(path).c_str());
- return 0;
- }
+ return f(args...);
} catch (const std::system_error& e) {
return -e.code().value();
} catch (...) {
- LOG(ERROR) << "unlink: caught unexpected value";
+ LOG(ERROR) << "caught unexpected value";
return -ENOTRECOVERABLE;
}
}
} // namespace
+#define CATCH_AND_RETURN_EXCEPTIONS(f) CatchAndReturnExceptions<decltype(f), f>
+
fuse_operations FuseOperations(File* const root) {
root_ = root;
@@ -328,29 +248,31 @@ fuse_operations FuseOperations(File* const root) {
result.flag_nopath = true;
result.flag_utime_omit_ok = true;
- result.init = &Initialize;
- result.destroy = &Destroy;
+ result.init = Initialize;
+ result.destroy = Destroy;
- result.getattr = &Getattr;
- result.fgetattr = &Fgetattr;
+ result.getattr = CATCH_AND_RETURN_EXCEPTIONS(Getattr);
+ result.fgetattr = CATCH_AND_RETURN_EXCEPTIONS(Fgetattr);
- result.mknod = &Mknod;
- result.chmod = &Chmod;
- result.rename = &Rename;
- result.open = &Open;
- result.read = &Read;
- result.write = &Write;
- result.utimens = &Utimens;
- result.release = &Release;
- result.unlink = &Unlink;
+ result.mknod = CATCH_AND_RETURN_EXCEPTIONS(Mknod);
+ result.chmod = CATCH_AND_RETURN_EXCEPTIONS(Chmod);
+ result.rename = CATCH_AND_RETURN_EXCEPTIONS(Rename);
+ result.open = CATCH_AND_RETURN_EXCEPTIONS(Open);
+ result.read = CATCH_AND_RETURN_EXCEPTIONS(Read);
+ result.write = CATCH_AND_RETURN_EXCEPTIONS(Write);
+ result.utimens = CATCH_AND_RETURN_EXCEPTIONS(Utimens);
+ result.release = CATCH_AND_RETURN_EXCEPTIONS(Release);
+ result.unlink = CATCH_AND_RETURN_EXCEPTIONS(Unlink);
- result.mkdir = &Mkdir;
- result.opendir = &Opendir;
- result.readdir = &Readdir;
- result.releasedir = &Releasedir;
- result.rmdir = &Rmdir;
+ result.mkdir = CATCH_AND_RETURN_EXCEPTIONS(Mkdir);
+ result.opendir = CATCH_AND_RETURN_EXCEPTIONS(Opendir);
+ result.readdir = CATCH_AND_RETURN_EXCEPTIONS(Readdir);
+ result.releasedir = CATCH_AND_RETURN_EXCEPTIONS(Releasedir);
+ result.rmdir = CATCH_AND_RETURN_EXCEPTIONS(Rmdir);
return result;
}
+#undef CATCH_AND_RETURN_EXCEPTIONS
+
} // namespace scoville