From 31726418d0f8f77040aaa0f9f5d0c5bb36105b6f Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 7 Oct 2016 16:08:22 +0300 Subject: Support ifdstream non-blocking mode --- butl/fdstream | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'butl/fdstream') diff --git a/butl/fdstream b/butl/fdstream index 49b3d4d..2d7fae5 100644 --- a/butl/fdstream +++ b/butl/fdstream @@ -34,11 +34,15 @@ namespace butl // - char only // - input or output but not both // - no support for put back + // - non-blocking file descriptor is supported only by showmanyc() function + // and only on POSIX // - throws ios::failure in case of open()/read()/write()/close() errors // - exception mask has at least badbit // - after catching an exception caused by badbit the stream is no longer // used // - not movable, though can be easily supported + // - passing to constructor -1 file descriptor is valid and results in the + // creation of an unopened object // class LIBBUTL_EXPORT fdbuf: public std::basic_streambuf { @@ -46,7 +50,7 @@ namespace butl virtual ~fdbuf (); fdbuf () = default; - fdbuf (int fd) {open (fd);} + fdbuf (int fd) {if (fd != -1) open (fd);} fdbuf (const fdbuf&) = delete; fdbuf& operator= (const fdbuf&) = delete; @@ -60,6 +64,9 @@ namespace butl bool is_open () const {return fd_ != -1;} + int + fd () const {return fd_;} + public: using int_type = std::basic_streambuf::int_type; using traits_type = std::basic_streambuf::traits_type; @@ -96,6 +103,7 @@ namespace butl private: int fd_ = -1; char buf_[8192]; + bool non_blocking_ = false; }; // File stream mode. @@ -109,11 +117,21 @@ namespace butl // you may want not to "offend" the other end by closing your end before // reading all the data. // + // The blocking/non_blocking flags determine whether the IO operation should + // block or return control if currently there is no data to read or no room + // to write. Only the istream::readsome() function supports the semantics of + // non-blocking operations. We also only support this on POSIX (Windows does + // not provide means for the non-blocking reading from a file descriptor so + // these flags are noop there). IO stream operations other than readsome() + // are illegal for non_blocking mode and result in the badbit being set. + // enum class fdstream_mode: std::uint16_t { - text = 0x01, - binary = 0x02, - skip = 0x04 + text = 0x01, + binary = 0x02, + skip = 0x04, + blocking = 0x08, + non_blocking = 0x10 }; inline fdstream_mode operator& (fdstream_mode, fdstream_mode); @@ -149,6 +167,10 @@ namespace butl fdstream_base (int fd): buf_ (fd) {} fdstream_base (int, fdstream_mode); + public: + int + fd () const {return buf_.fd ();} + protected: fdbuf buf_; }; @@ -243,7 +265,7 @@ namespace butl // // throw failed (); // - class LIBBUTL_EXPORT ifdstream: fdstream_base, public std::istream + class LIBBUTL_EXPORT ifdstream: public fdstream_base, public std::istream { public: // Create an unopened object with iostate = badbit | failbit (we cannot @@ -323,7 +345,7 @@ namespace butl // (std::uncaught_exception() == true). This is enforced with assert() in // the ofdstream destructor. // - class LIBBUTL_EXPORT ofdstream: fdstream_base, public std::ostream + class LIBBUTL_EXPORT ofdstream: public fdstream_base, public std::ostream { public: // Create an unopened object with iostate = badbit | failbit (we cannot -- cgit v1.1