aboutsummaryrefslogtreecommitdiff
path: root/butl/fdstream
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-10-07 16:08:22 +0300
committerBoris Kolpackov <boris@codesynthesis.com>2016-10-17 16:21:46 +0200
commit31726418d0f8f77040aaa0f9f5d0c5bb36105b6f (patch)
treebbceda8931febbbf8b7dd5b8fd944672f584d48b /butl/fdstream
parent7dc71b1ff87913cba31a26f081b65d85b429186f (diff)
Support ifdstream non-blocking mode
Diffstat (limited to 'butl/fdstream')
-rw-r--r--butl/fdstream34
1 files changed, 28 insertions, 6 deletions
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<char>
{
@@ -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<char>::int_type;
using traits_type = std::basic_streambuf<char>::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