aboutsummaryrefslogtreecommitdiff
path: root/tests/fdstream/driver.cxx
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 /tests/fdstream/driver.cxx
parent7dc71b1ff87913cba31a26f081b65d85b429186f (diff)
Support ifdstream non-blocking mode
Diffstat (limited to 'tests/fdstream/driver.cxx')
-rw-r--r--tests/fdstream/driver.cxx93
1 files changed, 89 insertions, 4 deletions
diff --git a/tests/fdstream/driver.cxx b/tests/fdstream/driver.cxx
index 2e3bac5..f77e2d5 100644
--- a/tests/fdstream/driver.cxx
+++ b/tests/fdstream/driver.cxx
@@ -2,6 +2,11 @@
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#ifndef _WIN32
+# include <chrono>
+# include <thread> // this_thread::sleep_for()
+#endif
+
#include <ios>
#include <string>
#include <vector>
@@ -13,6 +18,7 @@
#include <exception>
#include <butl/path>
+#include <butl/process>
#include <butl/fdstream>
#include <butl/timestamp>
#include <butl/filesystem>
@@ -90,13 +96,55 @@ read_time (const path& p, const T& s, size_t n)
int
main (int argc, const char* argv[])
{
- if (!(argc == 1 || (argc == 2 && argv[1] == string ("-v"))))
+ bool v (false);
+ bool child (false);
+
+ int i (1);
+ for (; i != argc; ++i)
{
- cerr << "usage: " << argv[0] << " [-v]" << endl;
- return 1;
+ string a (argv[i]);
+ if (a == "-c")
+ child = true;
+ else if (a == "-v")
+ v = true;
+ else
+ {
+ cerr << "usage: " << argv[0] << " [-v] [-c]" << endl;
+ return 1;
+ }
+ }
+
+ // To test non-blocking reading from ifdstream the test program launches
+ // itself as a child process with -c option and roundtrips a string through
+ // it. The child must write the string in chunks with some delays to make
+ // sure the parent reads in chunks as well.
+ //
+ if (child)
+ {
+ cin.exceptions (ios_base::badbit);
+ cout.exceptions (ios_base::failbit | ios_base::badbit | ios_base::eofbit);
+
+ string s;
+ getline (cin, s, '\0');
+
+ size_t n (10);
+ for (size_t i (0); i < s.size (); i += n)
+ {
+ cout.write (s.c_str () + i, min (n, s.size () - i));
+ cout.flush ();
+
+ // @@ MINGW GCC 4.9 doesn't implement this_thread. If ifdstream
+ // non-blocking read will ever be implemented use Win32 Sleep()
+ // instead.
+ //
+#ifndef _WIN32
+ this_thread::sleep_for (chrono::milliseconds (50));
+#endif
+ }
+
+ return 0;
}
- bool v (argc == 2);
dir_path td (dir_path::temp_directory () / dir_path ("butl-fdstream"));
// Recreate the temporary directory (that possibly exists from the previous
@@ -351,6 +399,43 @@ main (int argc, const char* argv[])
{
}
+ // Test non-blocking reading.
+ //
+ try
+ {
+ const char* args[] = {argv[0], "-c", nullptr};
+ process pr (args, -1, -1);
+
+ ofdstream os (pr.out_fd);
+ ifdstream is (pr.in_ofd, fdstream_mode::non_blocking);
+
+ const string s (
+ "0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz");
+
+ os << s;
+ os.close ();
+
+ string r;
+ char buf[3];
+ while (!is.eof ())
+ {
+ streamsize n (is.readsome (buf, sizeof (buf)));
+ r.append (buf, n);
+ }
+
+ is.close ();
+
+ assert (r == s);
+ }
+ catch (const ios::failure&)
+ {
+ assert (false);
+ }
+ catch (const process_error&)
+ {
+ assert (false);
+ }
+
#else
// Check translation modes.