aboutsummaryrefslogtreecommitdiff
path: root/butl
diff options
context:
space:
mode:
Diffstat (limited to 'butl')
-rw-r--r--butl/fdstream11
-rw-r--r--butl/fdstream.cxx23
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::