EDK: Add Core::DuplicateHandleWithReducedRights().
This will support both MojoDuplicateHandleWithReducedRights() and
MojoDuplicateHandle().
(No plumbing done yet -- to be done later.)
R=azani@chromium.org
Review URL: https://codereview.chromium.org/2001673003 .
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc
index c91ef7b..005dede 100644
--- a/mojo/edk/system/core_unittest.cc
+++ b/mojo/edk/system/core_unittest.cc
@@ -59,6 +59,31 @@
EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(h, MakeUserPointer(&rights)));
EXPECT_EQ(kDefaultMockHandleRights, rights);
+ MojoHandle h_dup = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_OK,
+ core()->DuplicateHandleWithReducedRights(
+ h, MOJO_HANDLE_RIGHT_DUPLICATE, MakeUserPointer(&h_dup)));
+ EXPECT_EQ(1u, info.GetDuplicateDispatcherCallCount());
+ EXPECT_NE(h_dup, MOJO_HANDLE_INVALID);
+ EXPECT_NE(h_dup, h);
+ rights = MOJO_HANDLE_RIGHT_NONE;
+ EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(h_dup, MakeUserPointer(&rights)));
+ EXPECT_EQ(kDefaultMockHandleRights & ~MOJO_HANDLE_RIGHT_DUPLICATE, rights);
+ MojoHandle h_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ core()->DuplicateHandleWithReducedRights(
+ h_dup, MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h_denied)));
+ EXPECT_EQ(1u, info.GetDuplicateDispatcherCallCount());
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h_denied);
+
+ EXPECT_EQ(0u, info.GetDtorCallCount());
+ EXPECT_EQ(0u, info.GetCloseCallCount());
+ EXPECT_EQ(0u, info.GetCancelAllAwakablesCallCount());
+ EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_dup));
+ EXPECT_EQ(1u, info.GetDtorCallCount());
+ EXPECT_EQ(1u, info.GetCloseCallCount());
+ EXPECT_EQ(1u, info.GetCancelAllAwakablesCallCount());
+
EXPECT_EQ(0u, info.GetWriteMessageCallCount());
EXPECT_EQ(MOJO_RESULT_OK,
core()->WriteMessage(h, NullUserPointer(), 0, NullUserPointer(), 0,
@@ -191,13 +216,14 @@
EXPECT_EQ(0u, hss.satisfied_signals);
EXPECT_EQ(0u, hss.satisfiable_signals);
- EXPECT_EQ(0u, info.GetDtorCallCount());
- EXPECT_EQ(0u, info.GetCloseCallCount());
- EXPECT_EQ(0u, info.GetCancelAllAwakablesCallCount());
- EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h));
- EXPECT_EQ(1u, info.GetCancelAllAwakablesCallCount());
- EXPECT_EQ(1u, info.GetCloseCallCount());
+ // |h| shares |info| with |h_dup|, which was closed above.
EXPECT_EQ(1u, info.GetDtorCallCount());
+ EXPECT_EQ(1u, info.GetCloseCallCount());
+ EXPECT_EQ(1u, info.GetCancelAllAwakablesCallCount());
+ EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h));
+ EXPECT_EQ(2u, info.GetDtorCallCount());
+ EXPECT_EQ(2u, info.GetCloseCallCount());
+ EXPECT_EQ(2u, info.GetCancelAllAwakablesCallCount());
// No awakables should ever have ever been added.
EXPECT_EQ(0u, info.GetRemoveAwakableCallCount());
@@ -230,6 +256,20 @@
EXPECT_EQ(0u, rights);
}
+ // |DuplicateHandleWithReducedRights()|:
+ {
+ MojoHandle h = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(
+ MOJO_RESULT_INVALID_ARGUMENT,
+ core()->DuplicateHandleWithReducedRights(
+ MOJO_HANDLE_INVALID, MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h)));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h);
+ EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+ core()->DuplicateHandleWithReducedRights(
+ 10, MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h)));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h);
+ }
+
// |Wait()|:
{
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
@@ -592,6 +632,17 @@
EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h));
}
+ // |DuplicateHandleWithReducedRights()|:
+ {
+ MockHandleInfo info;
+ MojoHandle h = CreateMockHandle(&info);
+ EXPECT_DEATH_IF_SUPPORTED(core()->DuplicateHandleWithReducedRights(
+ h, MOJO_HANDLE_RIGHT_NONE, NullUserPointer()),
+ kMemoryCheckFailedRegex);
+
+ EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h));
+ }
+
// |WaitMany()|:
{
MojoHandle handle = MOJO_HANDLE_INVALID;
@@ -688,6 +739,16 @@
EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(h[1], MakeUserPointer(&rights)));
EXPECT_EQ(kDefaultMessagePipeHandleRights, rights);
+ // Neither should be duplicatable.
+ MojoHandle h_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ core()->DuplicateHandleWithReducedRights(
+ h[0], MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h_denied)));
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ core()->DuplicateHandleWithReducedRights(
+ h[1], MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h_denied)));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h_denied);
+
// Neither should be readable.
MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE,
MOJO_HANDLE_SIGNAL_READABLE};
@@ -1047,6 +1108,16 @@
EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(ch, MakeUserPointer(&rights)));
EXPECT_EQ(kDefaultDataPipeConsumerHandleRights, rights);
+ // Neither should be duplicatable.
+ MojoHandle h_denied = MOJO_HANDLE_INVALID;
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ core()->DuplicateHandleWithReducedRights(
+ ph, MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h_denied)));
+ EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED,
+ core()->DuplicateHandleWithReducedRights(
+ ch, MOJO_HANDLE_RIGHT_NONE, MakeUserPointer(&h_denied)));
+ EXPECT_EQ(MOJO_HANDLE_INVALID, h_denied);
+
// Producer should be never-readable, but already writable.
hss = kEmptyMojoHandleSignalsState;
EXPECT_EQ(