diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2016-11-08 15:23:13 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2016-11-08 15:23:13 +0300 |
commit | ce9d743824be796471bae9b57c0185ef8ec1b804 (patch) | |
tree | fb2b9c476b6fe48639f794f5ec857e8eb890c145 | |
parent | b3473af950434305614bdf031fb408eaef06c1d5 (diff) |
Add auto_fd::close()
-rw-r--r-- | butl/fdstream | 11 | ||||
-rw-r--r-- | butl/fdstream.cxx | 23 |
2 files changed, 29 insertions, 5 deletions
diff --git a/butl/fdstream b/butl/fdstream index 9c7274d..289d925 100644 --- a/butl/fdstream +++ b/butl/fdstream @@ -19,8 +19,7 @@ namespace butl { // RAII type for file descriptors. Note that failure to close the descriptor - // is silently ignored by both the destructor and reset() (thought we could - // probably provide the close() function that throws). + // is silently ignored by both the destructor and reset(). // // The descriptor can be negative. Such a descriptor is treated as unopened // and is not closed. @@ -28,7 +27,7 @@ namespace butl struct nullfd_t {constexpr explicit nullfd_t (int) {}}; constexpr const nullfd_t nullfd (-1); - class auto_fd + class LIBBUTL_EXPORT auto_fd { public: auto_fd (nullfd_t = nullfd): fd_ (-1) {} @@ -53,6 +52,12 @@ namespace butl void reset (int fd = -1) noexcept; + // Close an open file descriptor. Throw ios::failure on failure. The object + // become unopened whenever the exception is thrown or not. + // + void + close (); + private: int fd_; }; diff --git a/butl/fdstream.cxx b/butl/fdstream.cxx index dbd7767..102ad66 100644 --- a/butl/fdstream.cxx +++ b/butl/fdstream.cxx @@ -68,6 +68,26 @@ namespace butl ec, m); } + // auto_fd + // + void auto_fd:: + close () + { + if (fd_ >= 0) + { + bool r (fdclose (fd_)); + + // If fdclose() failed then no reason to expect it to succeed the next + // time. + // + fd_ = -1; + + if (!r) + throw_ios_failure (errno); + } + } + + // fdbuf // fdbuf:: @@ -105,8 +125,7 @@ namespace butl // This semantics change seems to be the right one as there is no reason to // expect fdclose() to succeed after it has already failed once. // - if (is_open () && !fdclose (fd_.release ())) - throw_ios_failure (errno); + fd_.close (); } streamsize fdbuf:: |