// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/location.h"
#include "base/pickle.h"
#include "base/posix/unix_domain_socket.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "starboard/memory.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

namespace {

// Callers should use ASSERT_NO_FATAL_FAILURE with this function, to
// ensure that execution is aborted if the function has assertion failure.
void CreateSocketPair(int fds[2]) {
#if defined(OS_MACOSX)
  // Mac OS does not support SOCK_SEQPACKET.
  int flags = SOCK_STREAM;
#else
  int flags = SOCK_SEQPACKET;
#endif
  ASSERT_EQ(0, socketpair(AF_UNIX, flags, 0, fds));
#if defined(OS_MACOSX)
  // On OSX an attempt to read or write to a closed socket may generate a
  // SIGPIPE rather than returning -1, corrected with SO_NOSIGPIPE option.
  int nosigpipe = 1;
  ASSERT_EQ(0, setsockopt(fds[0], SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe,
                          sizeof(nosigpipe)));
  ASSERT_EQ(0, setsockopt(fds[1], SOL_SOCKET, SO_NOSIGPIPE, &nosigpipe,
                          sizeof(nosigpipe)));
#endif
}

TEST(UnixDomainSocketTest, SendRecvMsgAbortOnReplyFDClose) {
  Thread message_thread("UnixDomainSocketTest");
  ASSERT_TRUE(message_thread.Start());
  int fds[2];
  ASSERT_NO_FATAL_FAILURE(CreateSocketPair(fds));
  ScopedFD scoped_fd0(fds[0]);
  ScopedFD scoped_fd1(fds[1]);

  // Have the thread send a synchronous message via the socket.
  Pickle request;
  message_thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(IgnoreResult(&UnixDomainSocket::SendRecvMsg), fds[1],
                          nullptr, 0U, nullptr, request));

  // Receive the message.
  std::vector<ScopedFD> message_fds;
  uint8_t buffer[16];
  ASSERT_EQ(
      static_cast<int>(request.size()),
      UnixDomainSocket::RecvMsg(fds[0], buffer, sizeof(buffer), &message_fds));
  ASSERT_EQ(1U, message_fds.size());

  // Close the reply FD.
  message_fds.clear();

  // Check that the thread didn't get blocked.
  WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
                      WaitableEvent::InitialState::NOT_SIGNALED);
  message_thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&event)));
  ASSERT_TRUE(event.TimedWait(TimeDelta::FromMilliseconds(5000)));
}

TEST(UnixDomainSocketTest, SendRecvMsgAvoidsSIGPIPE) {
  // Make sure SIGPIPE isn't being ignored.
  struct sigaction act = {}, oldact;
  act.sa_handler = SIG_DFL;
  ASSERT_EQ(0, sigaction(SIGPIPE, &act, &oldact));
  int fds[2];
  ASSERT_NO_FATAL_FAILURE(CreateSocketPair(fds));
  ScopedFD scoped_fd1(fds[1]);
  ASSERT_EQ(0, IGNORE_EINTR(close(fds[0])));

  // Have the thread send a synchronous message via the socket. Unless the
  // message is sent with MSG_NOSIGNAL, this shall result in SIGPIPE.
  Pickle request;
  ASSERT_EQ(
      -1, UnixDomainSocket::SendRecvMsg(fds[1], nullptr, 0U, nullptr, request));
  ASSERT_EQ(EPIPE, errno);
  // Restore the SIGPIPE handler.
  ASSERT_EQ(0, sigaction(SIGPIPE, &oldact, nullptr));
}

// Simple sanity check within a single process that receiving PIDs works.
TEST(UnixDomainSocketTest, RecvPid) {
  int fds[2];
  ASSERT_NO_FATAL_FAILURE(CreateSocketPair(fds));
  ScopedFD recv_sock(fds[0]);
  ScopedFD send_sock(fds[1]);

  ASSERT_TRUE(UnixDomainSocket::EnableReceiveProcessId(recv_sock.get()));

  static const char kHello[] = "hello";
  ASSERT_TRUE(UnixDomainSocket::SendMsg(send_sock.get(), kHello, sizeof(kHello),
                                        std::vector<int>()));

  // Extra receiving buffer space to make sure we really received only
  // sizeof(kHello) bytes and it wasn't just truncated to fit the buffer.
  char buf[sizeof(kHello) + 1];
  ProcessId sender_pid;
  std::vector<ScopedFD> fd_vec;
  const ssize_t nread = UnixDomainSocket::RecvMsgWithPid(
      recv_sock.get(), buf, sizeof(buf), &fd_vec, &sender_pid);
  ASSERT_EQ(sizeof(kHello), static_cast<size_t>(nread));
  ASSERT_EQ(0, memcmp(buf, kHello, sizeof(kHello)));
  ASSERT_EQ(0U, fd_vec.size());

  ASSERT_EQ(getpid(), sender_pid);
}

// Same as above, but send the max number of file descriptors too.
TEST(UnixDomainSocketTest, RecvPidWithMaxDescriptors) {
  int fds[2];
  ASSERT_NO_FATAL_FAILURE(CreateSocketPair(fds));
  ScopedFD recv_sock(fds[0]);
  ScopedFD send_sock(fds[1]);

  ASSERT_TRUE(UnixDomainSocket::EnableReceiveProcessId(recv_sock.get()));

  static const char kHello[] = "hello";
  std::vector<int> send_fds(UnixDomainSocket::kMaxFileDescriptors,
                            send_sock.get());
  ASSERT_TRUE(UnixDomainSocket::SendMsg(send_sock.get(), kHello, sizeof(kHello),
                                        send_fds));

  // Extra receiving buffer space to make sure we really received only
  // sizeof(kHello) bytes and it wasn't just truncated to fit the buffer.
  char buf[sizeof(kHello) + 1];
  ProcessId sender_pid;
  std::vector<ScopedFD> recv_fds;
  const ssize_t nread = UnixDomainSocket::RecvMsgWithPid(
      recv_sock.get(), buf, sizeof(buf), &recv_fds, &sender_pid);
  ASSERT_EQ(sizeof(kHello), static_cast<size_t>(nread));
  ASSERT_EQ(0, memcmp(buf, kHello, sizeof(kHello)));
  ASSERT_EQ(UnixDomainSocket::kMaxFileDescriptors, recv_fds.size());

  ASSERT_EQ(getpid(), sender_pid);
}

// Check that RecvMsgWithPid doesn't DCHECK fail when reading EOF from a
// disconnected socket.
TEST(UnixDomianSocketTest, RecvPidDisconnectedSocket) {
  int fds[2];
  ASSERT_NO_FATAL_FAILURE(CreateSocketPair(fds));
  ScopedFD recv_sock(fds[0]);
  ScopedFD send_sock(fds[1]);

  ASSERT_TRUE(UnixDomainSocket::EnableReceiveProcessId(recv_sock.get()));

  send_sock.reset();

  char ch;
  ProcessId sender_pid;
  std::vector<ScopedFD> recv_fds;
  const ssize_t nread = UnixDomainSocket::RecvMsgWithPid(
      recv_sock.get(), &ch, sizeof(ch), &recv_fds, &sender_pid);
  ASSERT_EQ(0, nread);
  ASSERT_EQ(-1, sender_pid);
  ASSERT_EQ(0U, recv_fds.size());
}

}  // namespace

}  // namespace base
