aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2016-02-20 14:14:44 -0500
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2016-02-20 14:14:44 -0500
commit54307cc19e2aae4426473c274a121a4efc02e7a2 (patch)
treeb4777aa4cb0b9b8ecdc549f2dfa4aea64691f839
parent4e5a3f6c53261d7b9b5f042a547fdab9e5243579 (diff)
Replace hand-rolled IoError class with std::system_error
-rw-r--r--src/operations.cc21
-rw-r--r--src/posix_extras.cc51
-rw-r--r--src/posix_extras.h19
-rw-r--r--src/scoville.cc3
4 files changed, 30 insertions, 64 deletions
diff --git a/src/operations.cc b/src/operations.cc
index c799322..44e8d6b 100644
--- a/src/operations.cc
+++ b/src/operations.cc
@@ -23,6 +23,7 @@
#include <experimental/optional>
#include <memory>
#include <new>
+#include <system_error>
#include <type_traits>
#include <dirent.h>
@@ -78,8 +79,8 @@ int Getattr(const char* const path, struct stat* output) noexcept {
LOG(INFO) << "getattr: trimming leading slash";
*output = root_->LinkStatAt(path + 1);
return 0;
- } catch (const IoError& e) {
- return -e.number();
+ } catch (const std::system_error& e) {
+ return -e.code().value();
}
}
@@ -99,8 +100,8 @@ int Open(const char* const path, fuse_file_info* const file_info) {
root_->OpenAt(path + 1, file_info->flags)));
} catch (const std::bad_alloc&) {
return -ENOMEM;
- } catch (const IoError& e) {
- return -e.number();
+ } catch (const std::system_error& e) {
+ return -e.code().value();
}
static_assert(sizeof(file_info->fh) == sizeof(uintptr_t),
@@ -125,8 +126,8 @@ int Create(const char* const path, const mode_t mode,
file.reset(new File(root_->OpenAt(path + 1, file_info->flags, mode)));
} catch (const std::bad_alloc&) {
return -ENOMEM;
- } catch (const IoError& e) {
- return -e.number();
+ } catch (const std::system_error& e) {
+ return -e.code().value();
}
static_assert(sizeof(file_info->fh) == sizeof(uintptr_t),
@@ -158,8 +159,8 @@ int Opendir(const char* const path, fuse_file_info* const file_info) {
root_->OpenAt(path + 1, O_DIRECTORY)));
} catch (const std::bad_alloc&) {
return -ENOMEM;
- } catch (const IoError& e) {
- return -e.number();
+ } catch (const std::system_error& e) {
+ return -e.code().value();
}
static_assert(sizeof(file_info->fh) == sizeof(uintptr_t),
@@ -192,8 +193,8 @@ int Readdir(const char*, void* const buffer, fuse_fill_dir_t filler,
break;
}
}
- } catch (const IoError& e) {
- return -e.number();
+ } catch (const std::system_error& e) {
+ return -e.code().value();
}
return 0;
diff --git a/src/posix_extras.cc b/src/posix_extras.cc
index 2aeda7b..4093cc0 100644
--- a/src/posix_extras.cc
+++ b/src/posix_extras.cc
@@ -12,49 +12,34 @@
// License for the specific language governing permissions and limitations under
// the License.
-#define _XOPEN_SOURCE 700
-#undef _GNU_SOURCE
-
#include "posix_extras.h"
#include <cerrno>
#include <experimental/optional>
#include <stdexcept>
-#include <string>
-#include <vector>
+#include <system_error>
#include <dirent.h>
#include <fcntl.h>
#include <glog/logging.h>
-#include <string.h> // a POSIX header, not a libc one
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace scoville {
-std::string IoError::Message(const int number) noexcept {
- try {
- std::vector<char> text(64);
- int strerror_result;
- while ((strerror_result = strerror_r(number, text.data(), text.size())) ==
- ERANGE) {
- VLOG(1) << "IoError::Message: doubling message size from " << text.size();
- text.resize(text.size() * 2);
- }
+namespace {
- if (strerror_result == 0) {
- return std::string(text.begin(), text.end());
- }
- } catch (...) {
- }
- return "(could not generate error message)";
+std::system_error SystemError() {
+ return std::system_error(errno, std::system_category());
}
+} // namespace
+
File::File(const char* const path, const int flags, const mode_t mode)
: path_(path) {
if ((fd_ = open(path, flags, mode)) == -1) {
- throw IoError();
+ throw SystemError();
}
VLOG(1) << "opening file descriptor " << fd_;
}
@@ -66,15 +51,14 @@ File::File(const File& other) : path_(other.path_), fd_(other.Duplicate()) {
File::~File() noexcept {
VLOG(1) << "closing file descriptor " << fd_;
if (close(fd_) == -1) {
- LOG(ERROR) << "failed to close file descriptor " << fd_ << ": "
- << IoError::Message(errno);
+ LOG(ERROR) << "failed to close file descriptor " << fd_;
}
}
struct stat File::Stat() const {
struct stat result;
if (fstat(fd_, &result) == -1) {
- throw IoError();
+ throw SystemError();
}
return result;
}
@@ -86,7 +70,7 @@ struct stat File::LinkStatAt(const char* const path) const {
struct stat result;
if (fstatat(fd_, path, &result, AT_SYMLINK_NOFOLLOW) == -1) {
- throw IoError();
+ throw SystemError();
}
return result;
}
@@ -98,7 +82,7 @@ File File::OpenAt(const char* const path, const int flags) const {
File result;
if ((result.fd_ = openat(fd_, path, flags)) == -1) {
- throw IoError();
+ throw SystemError();
}
result.path_ = path_ + "/" + path;
return result;
@@ -112,7 +96,7 @@ File File::OpenAt(const char* const path, const int flags,
File result;
if ((result.fd_ = openat(fd_, path, flags, mode)) == -1) {
- throw IoError();
+ throw SystemError();
}
result.path_ = path_ + "/" + path;
return result;
@@ -121,7 +105,7 @@ File File::OpenAt(const char* const path, const int flags,
int File::Duplicate() const {
int result;
if ((result = dup(fd_)) == -1) {
- throw IoError();
+ throw SystemError();
}
return result;
}
@@ -131,22 +115,21 @@ Directory::Directory(const File& file) {
// implementation, and should not otherwise be used by the application." We
// therefore need to grab an unmanaged copy of the file descriptor from file.
if (!(stream_ = fdopendir(file.Duplicate()))) {
- throw IoError();
+ throw SystemError();
}
rewinddir(stream_);
}
Directory::~Directory() noexcept {
if (closedir(stream_) == -1) {
- LOG(ERROR) << "failed to close directory stream: "
- << IoError::Message(errno);
+ LOG(ERROR) << "failed to close directory stream";
}
}
long Directory::offset() const {
long result;
if ((result = telldir(stream_)) == -1) {
- throw IoError();
+ throw SystemError();
}
return result;
}
@@ -160,7 +143,7 @@ std::experimental::optional<dirent> Directory::ReadOne() {
if (errno == 0) {
return std::experimental::nullopt;
} else {
- throw IoError();
+ throw SystemError();
}
}
return *result;
diff --git a/src/posix_extras.h b/src/posix_extras.h
index 6f2fb37..b6dbdfd 100644
--- a/src/posix_extras.h
+++ b/src/posix_extras.h
@@ -15,9 +15,7 @@
#ifndef POSIX_EXTRAS_H_
#define POSIX_EXTRAS_H_
-#include <cerrno>
#include <experimental/optional>
-#include <stdexcept>
#include <string>
#include <dirent.h>
@@ -26,23 +24,6 @@
namespace scoville {
-class IoError : public std::runtime_error {
- public:
- IoError() : IoError(errno) {}
-
- explicit IoError(const int number)
- : std::runtime_error(Message(number)), number_(number) {}
-
- int number() const noexcept { return number_; }
-
- // Converts an errno into a human-readable message, a la strerror(3).
- // Thread-safe.
- static std::string Message(int) noexcept;
-
- private:
- int number_;
-};
-
class File;
// RAII wrapper for Unix directory streams.
diff --git a/src/scoville.cc b/src/scoville.cc
index 4cc563d..2b79cf6 100644
--- a/src/scoville.cc
+++ b/src/scoville.cc
@@ -15,6 +15,7 @@
// this program. If not, see <http://www.gnu.org/licenses/>.
#include <memory>
+#include <system_error>
#include <fcntl.h>
#include <gflags/gflags.h>
@@ -42,7 +43,7 @@ int main(int argc, char* argv[]) {
const char* const root_path = argv[argc - 1];
try {
root.reset(new scoville::File(root_path, O_DIRECTORY));
- } catch (const scoville::IoError& e) {
+ } catch (const std::system_error& e) {
LOG(FATAL) << "scoville: bad mount point `" << root_path
<< "': " << e.what();
}