• R/O
  • SSH

posixpp: Commit

The main posixpp library and associated tests.


Commit MetaInfo

Revision2737e23040266d8ffd8a569d1859da2b91cc1a48 (tree)
Time2021-04-30 01:31:13
AuthorEric Hopper <hopper@omni...>
CommiterEric Hopper

Log Message

Tests for dup and dup2.

Change Summary

Incremental Difference

diff -r 61484b250fd1 -r 2737e2304026 tests/simplefd.cpp
--- a/tests/simplefd.cpp Wed Apr 28 05:51:39 2021 -0700
+++ b/tests/simplefd.cpp Thu Apr 29 09:31:13 2021 -0700
@@ -67,3 +67,106 @@
6767 }
6868 }
6969 }
70+
71+SCENARIO(
72+ "File descriptor objects have dup and dup2 methods that work as expected."
73+) {
74+ GIVEN(
75+ "A new opened file foo in a new temporary directory containing "
76+ "some known text."
77+ ) {
78+ tempdir testdir;
79+ static const char known_text[] = "This is just some known text.";
80+ auto fooname = testdir.get_name() / "foo";
81+ using ::posixpp::fd;
82+ using of = ::posixpp::openflags;
83+ using fdf = ::posixpp::fdflags;
84+ using ::posixpp::modeflags;
85+ auto foo{
86+ fd::open(
87+ fooname.native().c_str(),
88+ of::creat | fdf::wronly,
89+ modeflags::irwall
90+ ).result()
91+ };
92+ // Don't write out the trailing '\0';
93+ REQUIRE(foo.write(known_text, sizeof(known_text) - 1).result() == sizeof(known_text) - 1);
94+ foo.close().throw_if_error();
95+ foo = fd::open(fooname.native().c_str(), fdf::rdonly).result();
96+ WHEN("The foo.dup() is called.") {
97+ fd bar{ foo.dup().result() };
98+
99+ THEN("It results in a new valid file descriptor.") {
100+ REQUIRE(bar.is_valid());
101+ REQUIRE(foo.as_fd() != bar.as_fd());
102+ }
103+ AND_WHEN("You read one character from it.") {
104+ char buf[1];
105+ REQUIRE(bar.read(buf, 1).result() == 1);
106+ THEN("you read the first character of the known text.") {
107+ REQUIRE(buf[0] == known_text[0]);
108+ }
109+ AND_WHEN("you then read one character from the original fd.") {
110+ char buf2[1];
111+ REQUIRE(foo.read(buf2, 1).result() == 1);
112+ THEN("that character is the second character of the known text.") {
113+ REQUIRE(buf2[0] == known_text[1]);
114+ }
115+ }
116+ }
117+ }
118+ WHEN("foo.dup2(foo) is called.") {
119+ REQUIRE_NOTHROW(foo.dup2(foo).throw_if_error());
120+ THEN("foo is still valid") {
121+ REQUIRE(foo.is_valid());
122+ }
123+ THEN( "a byte read from foo is the first byte of known_text") {
124+ char buf_foo[1];
125+ REQUIRE(foo.read(buf_foo, 1).result() == 1);
126+ REQUIRE(buf_foo[0] == known_text[0]);
127+ }
128+ }
129+ AND_GIVEN("Another file descriptor opened on the same file.") {
130+ auto foo2{fd::open(fooname.native().c_str(), fdf::rdonly).result()};
131+ THEN("It is valid.") {
132+ REQUIRE(foo2.is_valid());
133+ }
134+ WHEN(
135+ "One byte is read from each"
136+ ) {
137+ // Initialize to 0 to make sure they change when read into.
138+ char buf_foo[1] = {};
139+ char buf_foo2[1] = {};
140+ REQUIRE(foo.read(buf_foo, 1).result() == 1);
141+ REQUIRE(foo2.read(buf_foo2, 1).result() == 1);
142+ THEN(
143+ "it's the same byte, and the first byte of the known "
144+ "text, demonstrating that they each refer to a different "
145+ "underlying file descriptor."
146+ ) {
147+ REQUIRE(buf_foo2[0] == known_text[0]);
148+ REQUIRE(buf_foo[0] == buf_foo2[0]);
149+ } AND_WHEN("we dup2 the first fd to the second fd") {
150+ foo.dup2(foo2).throw_if_error();
151+ THEN("foo2 is still valid, and can be closed") {
152+ REQUIRE(foo2.is_valid());
153+ REQUIRE_NOTHROW(foo2.close().throw_if_error());
154+ } AND_WHEN ("we then read read a byte from each file.") {
155+ char buff2_foo[1];
156+ char buf2_foo2[1];
157+ REQUIRE(foo.read(buff2_foo, 1).result() == 1);
158+ REQUIRE(foo2.read(buf2_foo2, 1).result() == 1);
159+ THEN(
160+ "then we get the 2nd and 3rd bytes of known "
161+ "text, demonstrating they now refer to the same "
162+ "underlying file descriptor."
163+ ) {
164+ REQUIRE(buff2_foo[0] == known_text[1]);
165+ REQUIRE(buf2_foo2[0] == known_text[2]);
166+ }
167+ }
168+ }
169+ }
170+ }
171+ }
172+}
Show on old repository browser