| Index: ipc/ipc_send_fds_test.cc
|
| diff --git a/ipc/ipc_send_fds_test.cc b/ipc/ipc_send_fds_test.cc
|
| index 005103c3dbb8cd3c38d35be6bf7b0507bb8e6200..5699e6d99f7649248b09c033cdc039c22562ee36 100644
|
| --- a/ipc/ipc_send_fds_test.cc
|
| +++ b/ipc/ipc_send_fds_test.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "build/build_config.h"
|
|
|
| +#if defined(OS_POSIX)
|
| #if defined(OS_MACOSX)
|
| extern "C" {
|
| #include <sandbox.h>
|
| @@ -11,18 +12,15 @@ extern "C" {
|
| #endif
|
| #include <fcntl.h>
|
| #include <sys/stat.h>
|
| +#include <unistd.h>
|
|
|
| +#include "base/file_descriptor_posix.h"
|
| #include "base/message_loop.h"
|
| +#include "base/pickle.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| -#include "ipc/ipc_channel.h"
|
| -#include "ipc/ipc_listener.h"
|
| #include "ipc/ipc_message_utils.h"
|
| -#include "ipc/ipc_multiprocess_test.h"
|
| #include "ipc/ipc_test_base.h"
|
|
|
| -#if defined(OS_POSIX)
|
| -#include "base/file_descriptor_posix.h"
|
| -
|
| namespace {
|
|
|
| const unsigned kNumFDsToSend = 20;
|
| @@ -33,21 +31,21 @@ static void VerifyAndCloseDescriptor(int fd, ino_t inode_num) {
|
| char buf;
|
| ssize_t amt_read = read(fd, &buf, 1);
|
| ASSERT_EQ(amt_read, 1);
|
| - ASSERT_EQ(buf, 0); // /dev/zero always reads NUL bytes.
|
| + ASSERT_EQ(buf, 0); // /dev/zero always reads 0 bytes.
|
|
|
| struct stat st;
|
| ASSERT_EQ(fstat(fd, &st), 0);
|
|
|
| ASSERT_EQ(close(fd), 0);
|
|
|
| - // We compare iNode numbers to check that the file sent over the wire
|
| - // was actually the same physical file as the one we were expecting.
|
| + // Compare inode numbers to check that the file sent over the wire is actually
|
| + // the one expected.
|
| ASSERT_EQ(inode_num, st.st_ino);
|
| }
|
|
|
| class MyChannelDescriptorListener : public IPC::Listener {
|
| public:
|
| - MyChannelDescriptorListener(ino_t expected_inode_num)
|
| + explicit MyChannelDescriptorListener(ino_t expected_inode_num)
|
| : expected_inode_num_(expected_inode_num),
|
| num_fds_received_(0) {}
|
|
|
| @@ -57,13 +55,12 @@ class MyChannelDescriptorListener : public IPC::Listener {
|
| ++num_fds_received_;
|
| base::FileDescriptor descriptor;
|
|
|
| - IPC::ParamTraits<base::FileDescriptor>::Read(
|
| - &message, &iter, &descriptor);
|
| + IPC::ParamTraits<base::FileDescriptor>::Read(&message, &iter, &descriptor);
|
|
|
| VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_);
|
| - if (num_fds_received_ == kNumFDsToSend) {
|
| + if (num_fds_received_ == kNumFDsToSend)
|
| MessageLoop::current()->Quit();
|
| - }
|
| +
|
| return true;
|
| }
|
|
|
| @@ -71,8 +68,8 @@ class MyChannelDescriptorListener : public IPC::Listener {
|
| MessageLoop::current()->Quit();
|
| }
|
|
|
| - bool GotExpectedNumberOfDescriptors() {
|
| - return kNumFDsToSend == num_fds_received_;
|
| + bool GotExpectedNumberOfDescriptors() const {
|
| + return num_fds_received_ == kNumFDsToSend;
|
| }
|
|
|
| private:
|
| @@ -80,126 +77,107 @@ class MyChannelDescriptorListener : public IPC::Listener {
|
| unsigned num_fds_received_;
|
| };
|
|
|
| -void TestDescriptorServer(IPC::Channel& chan,
|
| - base::ProcessHandle process_handle) {
|
| - ASSERT_TRUE(process_handle);
|
| +class IPCSendFdsTest : public IPCTestBase {
|
| + protected:
|
| + void RunServer() {
|
| + // Set up IPC channel and start client.
|
| + MyChannelDescriptorListener listener(-1);
|
| + CreateChannel(&listener);
|
| + ASSERT_TRUE(ConnectChannel());
|
| + ASSERT_TRUE(StartClient());
|
| +
|
| + for (unsigned i = 0; i < kNumFDsToSend; ++i) {
|
| + const int fd = open(kDevZeroPath, O_RDONLY);
|
| + ASSERT_GE(fd, 0);
|
| + base::FileDescriptor descriptor(fd, true);
|
| +
|
| + IPC::Message* message =
|
| + new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL);
|
| + IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
|
| + ASSERT_TRUE(sender()->Send(message));
|
| + }
|
|
|
| - for (unsigned i = 0; i < kNumFDsToSend; ++i) {
|
| - base::FileDescriptor descriptor;
|
| - const int fd = open(kDevZeroPath, O_RDONLY);
|
| - ASSERT_GE(fd, 0);
|
| - descriptor.auto_close = true;
|
| - descriptor.fd = fd;
|
| -
|
| - IPC::Message* message = new IPC::Message(0, // routing_id
|
| - 3, // message type
|
| - IPC::Message::PRIORITY_NORMAL);
|
| - IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
|
| - ASSERT_TRUE(chan.Send(message));
|
| - }
|
| + // Run message loop.
|
| + MessageLoop::current()->Run();
|
|
|
| - // Run message loop.
|
| - MessageLoop::current()->Run();
|
| + // Close the channel so the client's OnChannelError() gets fired.
|
| + channel()->Close();
|
|
|
| - // Close Channel so client gets its OnChannelError() callback fired.
|
| - chan.Close();
|
| + EXPECT_TRUE(WaitForClientShutdown());
|
| + DestroyChannel();
|
| + }
|
| +};
|
|
|
| - // Cleanup child process.
|
| - EXPECT_TRUE(base::WaitForSingleProcess(
|
| - process_handle, base::TimeDelta::FromSeconds(5)));
|
| +TEST_F(IPCSendFdsTest, DescriptorTest) {
|
| + Init("SendFdsClient");
|
| + RunServer();
|
| }
|
|
|
| -int TestDescriptorClient(ino_t expected_inode_num) {
|
| +int SendFdsClientCommon(const std::string& test_client_name,
|
| + ino_t expected_inode_num) {
|
| MessageLoopForIO main_message_loop;
|
| MyChannelDescriptorListener listener(expected_inode_num);
|
|
|
| - // Setup IPC channel.
|
| - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
|
| - &listener);
|
| - CHECK(chan.Connect());
|
| + // Set up IPC channel.
|
| + IPC::Channel channel(IPCTestBase::GetChannelName(test_client_name),
|
| + IPC::Channel::MODE_CLIENT,
|
| + &listener);
|
| + CHECK(channel.Connect());
|
|
|
| - // Run message loop so IPC Channel can handle message IO.
|
| + // Run message loop.
|
| MessageLoop::current()->Run();
|
|
|
| - // Verify that the message loop was exited due to getting the correct
|
| - // number of descriptors, and not because the channel closing unexpectedly.
|
| + // Verify that the message loop was exited due to getting the correct number
|
| + // of descriptors, and not because of the channel closing unexpectedly.
|
| CHECK(listener.GotExpectedNumberOfDescriptors());
|
|
|
| return 0;
|
| }
|
|
|
| -class IPCSendFdsTest : public IPCTestBase {
|
| -};
|
| +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsClient) {
|
| + struct stat st;
|
| + int fd = open(kDevZeroPath, O_RDONLY);
|
| + fstat(fd, &st);
|
| + EXPECT_GE(HANDLE_EINTR(close(fd)), 0);
|
| + return SendFdsClientCommon("SendFdsClient", st.st_ino);
|
| +}
|
|
|
| #if defined(OS_MACOSX)
|
| +// Test that FDs are correctly sent to a sandboxed process.
|
| // TODO(port): Make this test cross-platform.
|
| -MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClientSandboxed) {
|
| +TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) {
|
| + Init("SendFdsSandboxedClient");
|
| + RunServer();
|
| +}
|
| +
|
| +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsSandboxedClient) {
|
| struct stat st;
|
| const int fd = open(kDevZeroPath, O_RDONLY);
|
| fstat(fd, &st);
|
| - if (HANDLE_EINTR(close(fd)) < 0) {
|
| + if (HANDLE_EINTR(close(fd)) < 0)
|
| return -1;
|
| - }
|
|
|
| - // Enable the Sandbox.
|
| + // Enable the sandbox.
|
| char* error_buff = NULL;
|
| int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED,
|
| &error_buff);
|
| bool success = (error == 0 && error_buff == NULL);
|
| - if (!success) {
|
| + if (!success)
|
| return -1;
|
| - }
|
|
|
| sandbox_free_error(error_buff);
|
|
|
| - // Make sure Sandbox is really enabled.
|
| + // Make sure sandbox is really enabled.
|
| if (open(kDevZeroPath, O_RDONLY) != -1) {
|
| LOG(ERROR) << "Sandbox wasn't properly enabled";
|
| return -1;
|
| }
|
|
|
| // See if we can receive a file descriptor.
|
| - return TestDescriptorClient(st.st_ino);
|
| -}
|
| -
|
| -// Test that FDs are correctly sent to a sandboxed process.
|
| -TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) {
|
| - // Setup IPC channel.
|
| - MyChannelDescriptorListener listener(-1);
|
| -
|
| - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
|
| - &listener);
|
| - ASSERT_TRUE(chan.Connect());
|
| -
|
| - base::ProcessHandle process_handle = SpawnChild(
|
| - TEST_DESCRIPTOR_CLIENT_SANDBOXED,
|
| - &chan);
|
| - TestDescriptorServer(chan, process_handle);
|
| + return SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino);
|
| }
|
| #endif // defined(OS_MACOSX)
|
|
|
| -MULTIPROCESS_IPC_TEST_MAIN(RunTestDescriptorClient) {
|
| - struct stat st;
|
| - const int fd = open(kDevZeroPath, O_RDONLY);
|
| - fstat(fd, &st);
|
| - EXPECT_GE(HANDLE_EINTR(close(fd)), 0);
|
| -
|
| - return TestDescriptorClient(st.st_ino);
|
| -}
|
| -
|
| -TEST_F(IPCSendFdsTest, DescriptorTest) {
|
| - // Setup IPC channel.
|
| - MyChannelDescriptorListener listener(-1);
|
| -
|
| - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
|
| - &listener);
|
| - ASSERT_TRUE(chan.Connect());
|
| -
|
| - base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT,
|
| - &chan);
|
| - TestDescriptorServer(chan, process_handle);
|
| -}
|
| -
|
| } // namespace
|
|
|
| #endif // defined(OS_POSIX)
|
|
|