// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test/multiprocess.h"

#include <signal.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

#include <memory>
#include <string>

#include "base/auto_reset.h"
#include "base/check_op.h"
#include "base/files/scoped_file.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "util/misc/scoped_forbid_return.h"
#include "util/posix/signals.h"

#if defined(OS_APPLE)
#include "test/mac/exception_swallower.h"
#endif

namespace crashpad {
namespace test {

namespace internal {

struct MultiprocessInfo {
  MultiprocessInfo()
      : pipe_c2p_read(-1),
        pipe_c2p_write(-1),
        pipe_p2c_read(-1),
        pipe_p2c_write(-1),
        child_pid(0) {}

  base::ScopedFD pipe_c2p_read;  // child to parent
  base::ScopedFD pipe_c2p_write;  // child to parent
  base::ScopedFD pipe_p2c_read;  // parent to child
  base::ScopedFD pipe_p2c_write;  // parent to child
  pid_t child_pid;  // valid only in parent
};

}  // namespace internal

Multiprocess::Multiprocess()
    : info_(nullptr),
      code_(EXIT_SUCCESS),
      reason_(kTerminationNormal) {
}

void Multiprocess::Run() {
  ASSERT_EQ(info_, nullptr);
  std::unique_ptr<internal::MultiprocessInfo> info(
      new internal::MultiprocessInfo);
  base::AutoReset<internal::MultiprocessInfo*> reset_info(&info_, info.get());

  ASSERT_NO_FATAL_FAILURE(PreFork());

#if defined(OS_APPLE)
  // If the child is expected to crash, set up an exception swallower to swallow
  // the exception instead of allowing it to be seen by the system’s crash
  // reporter.
  std::unique_ptr<ExceptionSwallower> exception_swallower;
  if (reason_ == kTerminationSignal && Signals::IsCrashSignal(code_)) {
    exception_swallower.reset(new ExceptionSwallower());
  }
#endif  // OS_APPLE

  pid_t pid = fork();
  ASSERT_GE(pid, 0) << ErrnoMessage("fork");

  if (pid > 0) {
    info_->child_pid = pid;

    RunParent();

    // Waiting for the child happens here instead of in RunParent() because even
    // if RunParent() returns early due to a Google Test fatal assertion
    // failure, the child should still be reaped.

    // This will make the parent hang up on the child as much as would be
    // visible from the child’s perspective. The child’s side of the pipe will
    // be broken, the child’s remote port will become a dead name, and an
    // attempt by the child to look up the service will fail. If this weren’t
    // done, the child might hang while waiting for a parent that has already
    // triggered a fatal assertion failure to do something.
    info.reset();
    info_ = nullptr;

    int status;
    pid_t wait_pid = HANDLE_EINTR(waitpid(pid, &status, 0));
    ASSERT_EQ(wait_pid, pid) << ErrnoMessage("waitpid");

    TerminationReason reason;
    int code;
    std::string message;
    if (WIFEXITED(status)) {
      reason = kTerminationNormal;
      code = WEXITSTATUS(status);
      message = base::StringPrintf("Child exited with code %d", code);
    } else if (WIFSIGNALED(status)) {
      reason = kTerminationSignal;
      code = WTERMSIG(status);
      message =
          base::StringPrintf("Child terminated by signal %d (%s)%s",
                             code,
                             strsignal(code),
                             WCOREDUMP(status) ? " (core dumped)" : "");
    } else {
      FAIL() << base::StringPrintf("Unknown termination reason 0x%x", status);
    }

    if (reason_ == kTerminationNormal) {
      message += base::StringPrintf(", expected exit with code %d", code_);
    } else if (reason_ == kTerminationSignal) {
      message += base::StringPrintf(", expected termination by signal %d (%s)",
                                    code_,
                                    strsignal(code_));
    }

    if (reason != reason_ || code != code_) {
      ADD_FAILURE() << message;
    }
  } else {
#if defined(OS_APPLE)
    if (exception_swallower.get()) {
      ExceptionSwallower::SwallowExceptions();
    }
#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
    if (reason_ == kTerminationSignal && Signals::IsCrashSignal(code_)) {
      Signals::InstallDefaultHandler(code_);
    }
#endif  // OS_APPLE

    RunChild();
  }
}

void Multiprocess::SetExpectedChildTermination(TerminationReason reason,
                                               ReturnCodeType code) {
  EXPECT_EQ(info_, nullptr)
      << "SetExpectedChildTermination() must be called before Run()";
  reason_ = reason;
  code_ = code;
}

void Multiprocess::SetExpectedChildTerminationBuiltinTrap() {
#if defined(ARCH_CPU_ARM64) || defined(ARCH_CPU_MIPS_FAMILY)
  SetExpectedChildTermination(kTerminationSignal, SIGTRAP);
#else
  SetExpectedChildTermination(kTerminationSignal, SIGILL);
#endif
}

Multiprocess::~Multiprocess() {
}

void Multiprocess::PreFork() {
  int pipe_fds_c2p[2];
  int rv = pipe(pipe_fds_c2p);
  ASSERT_EQ(rv, 0) << ErrnoMessage("pipe");

  info_->pipe_c2p_read.reset(pipe_fds_c2p[0]);
  info_->pipe_c2p_write.reset(pipe_fds_c2p[1]);

  int pipe_fds_p2c[2];
  rv = pipe(pipe_fds_p2c);
  ASSERT_EQ(rv, 0) << ErrnoMessage("pipe");

  info_->pipe_p2c_read.reset(pipe_fds_p2c[0]);
  info_->pipe_p2c_write.reset(pipe_fds_p2c[1]);
}

pid_t Multiprocess::ChildPID() const {
  EXPECT_NE(info_->child_pid, 0);
  return info_->child_pid;
}

FileHandle Multiprocess::ReadPipeHandle() const {
  int fd = info_->child_pid ? info_->pipe_c2p_read.get()
                            : info_->pipe_p2c_read.get();
  CHECK_NE(fd, -1);
  return fd;
}

FileHandle Multiprocess::WritePipeHandle() const {
  int fd = info_->child_pid ? info_->pipe_p2c_write.get()
                            : info_->pipe_c2p_write.get();
  CHECK_NE(fd, -1);
  return fd;
}

void Multiprocess::CloseReadPipe() {
  if (info_->child_pid) {
    info_->pipe_c2p_read.reset();
  } else {
    info_->pipe_p2c_read.reset();
  }
}

void Multiprocess::CloseWritePipe() {
  if (info_->child_pid) {
    info_->pipe_p2c_write.reset();
  } else {
    info_->pipe_c2p_write.reset();
  }
}

void Multiprocess::RunParent() {
  // The parent uses the read end of c2p and the write end of p2c.
  info_->pipe_c2p_write.reset();
  info_->pipe_p2c_read.reset();

  MultiprocessParent();

  info_->pipe_c2p_read.reset();
  info_->pipe_p2c_write.reset();
}

void Multiprocess::RunChild() {
  ScopedForbidReturn forbid_return;

  // The child uses the write end of c2p and the read end of p2c.
  info_->pipe_c2p_read.reset();
  info_->pipe_p2c_write.reset();

  MultiprocessChild();

  info_->pipe_c2p_write.reset();
  info_->pipe_p2c_read.reset();

  if (testing::Test::HasFailure()) {
    // Trigger the ScopedForbidReturn destructor.
    return;
  }

  // In a forked child, exit() is unsafe. Use _exit() instead.
  _exit(EXIT_SUCCESS);
}

}  // namespace test
}  // namespace crashpad
