aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-07-12 17:24:00 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-07-23 19:42:48 +0300
commit6c8e3f09c185d7fa4664ccd9e5c4f623a17b84cc (patch)
tree513f523dba31f275994d8152c02db82f3380c56e /tests
parent09bedede7116961fbfb298a6a6cfa933af7af682 (diff)
Extend fdstream
Diffstat (limited to 'tests')
-rw-r--r--tests/cpfile/driver.cxx21
-rw-r--r--tests/fdstream/driver.cxx192
-rw-r--r--tests/link/driver.cxx12
-rw-r--r--tests/pager/driver.cxx5
-rw-r--r--tests/process/driver.cxx26
5 files changed, 219 insertions, 37 deletions
diff --git a/tests/cpfile/driver.cxx b/tests/cpfile/driver.cxx
index 669ac26..23b6fc3 100644
--- a/tests/cpfile/driver.cxx
+++ b/tests/cpfile/driver.cxx
@@ -2,12 +2,13 @@
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <ios>
#include <string>
#include <cassert>
-#include <fstream>
#include <system_error>
#include <butl/path>
+#include <butl/fdstream>
#include <butl/filesystem>
using namespace std;
@@ -20,22 +21,20 @@ static const char text3[] = "XAB\r\n9";
static string
from_file (const path& f)
{
- ifstream ifs;
- ifs.exceptions (fstream::badbit | fstream::failbit);
- ifs.open (f.string (), ios::binary);
+ ifdstream ifs (f, ios::binary);
string s;
getline (ifs, s, '\0');
+ ifs.close (); // Not to miss failed close of the underlying file descriptor.
return s;
}
static void
to_file (const path& f, const char* s)
{
- ofstream ofs;
- ofs.exceptions (fstream::badbit | fstream::failbit);
- ofs.open (f.string (), ios::binary);
+ ofdstream ofs (f, ios::binary);
ofs << s;
+ ofs.close ();
}
int
@@ -89,7 +88,7 @@ main ()
cpfile (from, to, cpflags::none);
assert (false);
}
- catch (const system_error&)
+ catch (const ios::failure&)
{
}
@@ -162,11 +161,13 @@ main ()
cpfile (from, tslink, cpflags::none);
assert (false);
}
- catch (const system_error&)
+ catch (const ios::failure&)
{
}
- // Check that copy fail if 'from' symlink points to non-existent file.
+ // Check that copy fail if 'from' symlink points to non-existent file. The
+ // std::system_error is thrown as cpfile() fails to obtain permissions for
+ // the 'from' symlink target.
//
try
{
diff --git a/tests/fdstream/driver.cxx b/tests/fdstream/driver.cxx
index 3972473..0c6c480 100644
--- a/tests/fdstream/driver.cxx
+++ b/tests/fdstream/driver.cxx
@@ -2,9 +2,11 @@
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <ios>
#include <string>
#include <cassert>
-#include <system_error>
+#include <sstream>
+#include <exception>
#include <butl/path>
#include <butl/fdstream>
@@ -20,20 +22,20 @@ static const string text3 ("ABCDEF\r\nXYZ");
static string
from_file (const path& f, fdopen_mode m = fdopen_mode::none)
{
- ifdstream ifs (fdopen (f, m | fdopen_mode::in));
- ifs.exceptions (ifdstream::badbit);
+ ifdstream ifs (f, m, ifdstream::badbit);
string s;
getline (ifs, s, '\0');
+ ifs.close (); // Not to miss failed close of the underlying file descriptor.
return s;
}
static void
to_file (const path& f, const string& s, fdopen_mode m = fdopen_mode::none)
{
- ofdstream ofs (fdopen (f, m | fdopen_mode::out));
- ofs.exceptions (ofdstream::badbit | ofdstream::failbit);
+ ofdstream ofs (f, m);
ofs << s;
+ ofs.close ();
}
int
@@ -55,7 +57,7 @@ main ()
fdopen (f, fdopen_mode::out); // fdopen_mode::create is missed.
assert (false);
}
- catch (const system_error&)
+ catch (const ios::failure&)
{
}
@@ -64,13 +66,45 @@ main ()
assert (from_file (f, fdopen_mode::create) == "");
assert (try_rmfile (f) == rmfile_status::success);
+ // Read from the newly created non-empty file.
+ //
to_file (f, text1, fdopen_mode::create);
assert (from_file (f) == text1);
+ // Check that skip on close as requested.
+ //
+ {
+ ifdstream ifs (fdopen (f, fdopen_mode::in), fdstream_mode::skip);
+
+ string s;
+ getline (ifs, s);
+ assert (!ifs.eof ());
+
+ ifs.close ();
+ assert (ifs.eof ());
+ }
+
+ // Check that don't skip on close by default.
+ //
+ {
+ ifdstream ifs (fdopen (f, fdopen_mode::in));
+
+ string s;
+ getline (ifs, s);
+ assert (!ifs.eof ());
+
+ ifs.close ();
+ assert (!ifs.eof ());
+ }
+
// Read from the file opened in R/W mode.
//
assert (from_file (f, fdopen_mode::out) == text1);
+ // Read starting from the file's end.
+ //
+ assert (from_file (f, fdopen_mode::at_end) == "");
+
try
{
// Fail to create if the file already exists.
@@ -80,7 +114,7 @@ main ()
assert (false);
}
- catch (const system_error&)
+ catch (const ios::failure&)
{
}
@@ -101,6 +135,148 @@ main ()
to_file (f, text2, fdopen_mode::append);
assert (from_file (f) == text1 + text2);
+ // Append to the file with the yet another way.
+ //
+ to_file (f, text1, fdopen_mode::truncate);
+ to_file (f, text2, fdopen_mode::at_end);
+ assert (from_file (f) == text1 + text2);
+
+ // Check creating unopened ifdstream with a non-default exception mask.
+ //
+ to_file (f, "", fdopen_mode::truncate);
+
+ {
+ ifdstream ifs (-1, ifdstream::badbit);
+ ifs.open (f);
+
+ string s;
+ assert (!getline (ifs, s));
+ }
+
+ {
+ ifdstream ifs (-1, fdstream_mode::text, ifdstream::badbit);
+ ifs.open (f);
+
+ string s;
+ assert (!getline (ifs, s));
+ }
+
+ // Check creating unopened ofdstream with a non-default exception mask.
+ //
+ {
+ ofdstream ofs (-1, ifdstream::badbit);
+ ofs.open (f);
+
+ istringstream is;
+ ofs << is.rdbuf (); // Sets failbit if no characters is inserted.
+ ofs.close ();
+ }
+
+ {
+ ofdstream ofs (-1, fdstream_mode::binary, ifdstream::badbit);
+ ofs.open (f);
+
+ istringstream is;
+ ofs << is.rdbuf (); // Sets failbit if no characters is inserted.
+ ofs.close ();
+ }
+
+ // Fail to write to a read-only file.
+ //
+ // Don't work well for MinGW GCC (5.2.0) that throws ios::failure, which in
+ // combination with libstdc++'s ios::failure ABI fiasco (#66145) make it
+ // impossible to properly catch in this situation.
+ //
+ try
+ {
+ {
+ ofdstream ofs (fdopen (f, fdopen_mode::in));
+ ofs << text1;
+ ofs.flush ();
+ }
+
+ assert (false);
+ }
+#if !defined(_WIN32) || !defined(__GLIBCXX__)
+ catch (const ios::failure&)
+ {
+ }
+#else
+ catch (const std::exception&)
+ {
+ }
+#endif
+
+ try
+ {
+ ofdstream ofs;
+ ofs.open (fdopen (f, fdopen_mode::in));
+ ofs << text1;
+ ofs.close ();
+
+ assert (false);
+ }
+#if !defined(_WIN32) || !defined(__GLIBCXX__)
+ catch (const ios::failure&)
+ {
+ }
+#else
+ catch (const std::exception&)
+ {
+ }
+#endif
+
+ // Fail to read from a write-only file.
+ //
+ try
+ {
+ ifdstream ifs (fdopen (f, fdopen_mode::out));
+ ifs.peek ();
+
+ assert (false);
+ }
+ catch (const ios::failure&)
+ {
+ }
+
+ try
+ {
+ ifdstream ifs;
+ ifs.open (fdopen (f, fdopen_mode::out));
+ ifs.peek ();
+
+ assert (false);
+ }
+ catch (const ios::failure&)
+ {
+ }
+
+ // Dtor of a not opened ofdstream doesn't terminate a program.
+ //
+ {
+ ofdstream ofs;
+ }
+
+ // Dtor of an opened ofdstream doesn't terminate a program during the stack
+ // unwinding.
+ //
+ try
+ {
+ ofdstream ofs (f);
+ throw true;
+ }
+ catch (bool)
+ {
+ }
+
+ // Dtor of an opened but being in a bad state ofdstream doesn't terminate a
+ // program.
+ //
+ {
+ ofdstream ofs (f, fdopen_mode::out, ofdstream::badbit);
+ ofs.clear (ofdstream::failbit);
+ }
+
#ifndef _WIN32
// Fail for an existing symlink to unexistent file.
@@ -115,7 +291,7 @@ main ()
assert (false);
}
- catch (const system_error&)
+ catch (const ios::failure&)
{
}
diff --git a/tests/link/driver.cxx b/tests/link/driver.cxx
index 7ec4ac2..a32a8dc 100644
--- a/tests/link/driver.cxx
+++ b/tests/link/driver.cxx
@@ -4,11 +4,11 @@
#include <set>
#include <cassert>
-#include <fstream>
#include <utility> // pair
#include <system_error>
#include <butl/path>
+#include <butl/fdstream>
#include <butl/filesystem>
using namespace std;
@@ -35,10 +35,9 @@ link_file (const path& target, const path& link, bool hard, bool check_content)
return true;
string s;
- ifstream ifs;
- ifs.exceptions (fstream::badbit | fstream::failbit);
- ifs.open (link.string ());
+ ifdstream ifs (link);
ifs >> s;
+ ifs.close (); // Not to miss failed close of the underlying file descriptor.
return s == text;
}
@@ -93,10 +92,9 @@ main ()
path fp (td / fn);
{
- ofstream ofs;
- ofs.exceptions (fstream::badbit | fstream::failbit);
- ofs.open (fp.string ());
+ ofdstream ofs (fp);
ofs << text;
+ ofs.close ();
}
// Create the file hard link.
diff --git a/tests/pager/driver.cxx b/tests/pager/driver.cxx
index cab3078..e921533 100644
--- a/tests/pager/driver.cxx
+++ b/tests/pager/driver.cxx
@@ -2,6 +2,7 @@
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <ios> // ios_base::failure
#include <vector>
#include <string>
#include <utility> // move()
@@ -104,6 +105,10 @@ public:
assert (p.wait ());
}
+ catch (const ios_base::failure&)
+ {
+ assert (false);
+ }
catch (const system_error&)
{
assert (false);
diff --git a/tests/process/driver.cxx b/tests/process/driver.cxx
index 741340c..5c43fb5 100644
--- a/tests/process/driver.cxx
+++ b/tests/process/driver.cxx
@@ -68,13 +68,12 @@ exec (const path& p,
auto bin_mode = [bin](int fd) -> int
{
if (bin)
- fdmode (fd, fdtranslate::binary);
+ fdmode (fd, fdstream_mode::binary);
return fd;
};
ofdstream os (bin_mode (pr.out_fd));
- os.exceptions (ofdstream::badbit);
copy (in.begin (), in.end (), ostream_iterator<char> (os));
os.close ();
@@ -166,7 +165,6 @@ exec (const path& p,
int
main (int argc, const char* argv[])
-try
{
bool child (false);
bool bin (false);
@@ -201,8 +199,7 @@ try
if (i != argc)
{
if (!child)
- cerr << "usage: " << argv[0] << " [-c] [-i] [-o] [-e] [-b] [<dir>]"
- << endl;
+ cerr << "usage: " << argv[0] << " [-c] [-b] [<dir>]" << endl;
return 1;
}
@@ -235,9 +232,9 @@ try
{
if (bin)
{
- stdin_fdmode (fdtranslate::binary);
- stdout_fdmode (fdtranslate::binary);
- stderr_fdmode (fdtranslate::binary);
+ stdin_fdmode (fdstream_mode::binary);
+ stdout_fdmode (fdstream_mode::binary);
+ stderr_fdmode (fdstream_mode::binary);
}
vector<char> data
@@ -317,8 +314,13 @@ try
//
assert (exec (
fp.leaf (), vector<char> (), false, false, false, true, fp.directory ()));
-}
-catch (const system_error&)
-{
- assert (false);
+
+#ifndef _WIN32
+ // Check that wait() works properly if the underlying low-level wait
+ // operation fails.
+ //
+ process pr;
+ pr.handle = reinterpret_cast<process::handle_type>(-1);
+ assert (!pr.wait (true) && !pr.wait (false));
+#endif
}