// Copyright 2017 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 "util/posix/fork_and_spawn.h"

#include <errno.h>
#include <spawn.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include "base/check.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "util/posix/close_multiple.h"

extern char** environ;

namespace crashpad {

namespace {

#if BUILDFLAG(IS_APPLE)

class PosixSpawnAttr {
 public:
  PosixSpawnAttr() {
    PCHECK((errno = posix_spawnattr_init(&attr_)) == 0)
        << "posix_spawnattr_init";
  }

  PosixSpawnAttr(const PosixSpawnAttr&) = delete;
  PosixSpawnAttr& operator=(const PosixSpawnAttr&) = delete;

  ~PosixSpawnAttr() {
    PCHECK((errno = posix_spawnattr_destroy(&attr_)) == 0)
        << "posix_spawnattr_destroy";
  }

  void SetFlags(short flags) {
    PCHECK((errno = posix_spawnattr_setflags(&attr_, flags)) == 0)
        << "posix_spawnattr_setflags";
  }

  const posix_spawnattr_t* Get() const { return &attr_; }

 private:
  posix_spawnattr_t attr_;
};

class PosixSpawnFileActions {
 public:
  PosixSpawnFileActions() {
    PCHECK((errno = posix_spawn_file_actions_init(&file_actions_)) == 0)
        << "posix_spawn_file_actions_init";
  }

  PosixSpawnFileActions(const PosixSpawnFileActions&) = delete;
  PosixSpawnFileActions& operator=(const PosixSpawnFileActions&) = delete;

  ~PosixSpawnFileActions() {
    PCHECK((errno = posix_spawn_file_actions_destroy(&file_actions_)) == 0)
        << "posix_spawn_file_actions_destroy";
  }

  void AddInheritedFileDescriptor(int fd) {
    PCHECK((errno = posix_spawn_file_actions_addinherit_np(&file_actions_,
                                                           fd)) == 0)
        << "posix_spawn_file_actions_addinherit_np";
  }

  const posix_spawn_file_actions_t* Get() const { return &file_actions_; }

 private:
  posix_spawn_file_actions_t file_actions_;
};

#endif

}  // namespace

bool ForkAndSpawn(const std::vector<std::string>& argv,
                  const std::vector<std::string>* envp,
                  int preserve_fd,
                  bool use_path,
                  void (*child_function)()) {
  // argv_c contains const char* pointers and is terminated by nullptr. This is
  // suitable for passing to posix_spawn() or posix_spawnp(). Although argv_c is
  // not used in the parent process, it must be built in the parent process
  // because it’s unsafe to do so in the child.
  std::vector<const char*> argv_c;
  argv_c.reserve(argv.size() + 1);
  for (const std::string& argument : argv) {
    argv_c.push_back(argument.c_str());
  }
  argv_c.push_back(nullptr);

  std::vector<const char*> envp_c;
  if (envp) {
    envp_c.reserve(envp->size() + 1);
    for (const std::string& variable : *envp) {
      envp_c.push_back(variable.c_str());
    }
    envp_c.push_back(nullptr);
  }

  // The three processes involved are parent, child, and grandchild. The child
  // exits immediately after spawning the grandchild, so the grandchild becomes
  // an orphan and its parent process ID becomes 1. This relieves the parent and
  // child of the responsibility to reap the grandchild with waitpid() or
  // similar. The grandchild is expected to outlive the parent process, so the
  // parent shouldn’t be concerned with reaping it. This approach means that
  // accidental early termination of the handler process will not result in a
  // zombie process.
  pid_t pid = fork();
  if (pid < 0) {
    PLOG(ERROR) << "fork";
    return false;
  }

  if (pid == 0) {
    // Child process.

    if (child_function) {
      child_function();
    }

    // Call setsid(), creating a new process group and a new session, both led
    // by this process. The new process group has no controlling terminal. This
    // disconnects it from signals generated by the parent process’ terminal.
    //
    // setsid() is done in the child instead of the grandchild so that the
    // grandchild will not be a session leader. If it were a session leader, an
    // accidental open() of a terminal device without O_NOCTTY would make that
    // terminal the controlling terminal.
    //
    // It’s not desirable for the grandchild to have a controlling terminal. The
    // grandchild manages its own lifetime, such as by monitoring clients on its
    // own and exiting when it loses all clients and when it deems it
    // appropraite to do so. It may serve clients in different process groups or
    // sessions than its original client, and receiving signals intended for its
    // original client’s process group could be harmful in that case.
    PCHECK(setsid() != -1) << "setsid";

    // &argv_c[0] is a pointer to a pointer to const char data, but because of
    // how C (not C++) works, posix_spawn() and posix_spawnp() want a pointer to
    // a const pointer to char data. They modifies neither the data nor the
    // pointers, so the const_cast is safe.
    char* const* argv_for_spawn = const_cast<char* const*>(argv_c.data());

    // This cast is safe for the same reason that the argv_for_spawn cast is.
    char* const* envp_for_spawn =
        envp ? const_cast<char* const*>(envp_c.data()) : environ;

#if BUILDFLAG(IS_APPLE)
    PosixSpawnAttr attr;
    attr.SetFlags(POSIX_SPAWN_CLOEXEC_DEFAULT);

    PosixSpawnFileActions file_actions;
    for (int fd = 0; fd <= STDERR_FILENO; ++fd) {
      file_actions.AddInheritedFileDescriptor(fd);
    }
    file_actions.AddInheritedFileDescriptor(preserve_fd);

    const posix_spawnattr_t* attr_p = attr.Get();
    const posix_spawn_file_actions_t* file_actions_p = file_actions.Get();
#else
    CloseMultipleNowOrOnExec(STDERR_FILENO + 1, preserve_fd);

    const posix_spawnattr_t* attr_p = nullptr;
    const posix_spawn_file_actions_t* file_actions_p = nullptr;
#endif

    auto posix_spawn_fp = use_path ? posix_spawnp : posix_spawn;
    if ((errno = posix_spawn_fp(&pid,
                                argv_for_spawn[0],
                                file_actions_p,
                                attr_p,
                                argv_for_spawn,
                                envp_for_spawn)) != 0) {
      PLOG(FATAL) << (use_path ? "posix_spawnp" : "posix_spawn");
    }

    // _exit() instead of exit(), because fork() was called.
    _exit(EXIT_SUCCESS);
  }

  // waitpid() for the child, so that it does not become a zombie process. The
  // child normally exits quickly.
  //
  // Failures from this point on may result in the accumulation of a zombie, but
  // should not be considered fatal. Log only warnings, but don’t treat these
  // failures as a failure of the function overall.
  int status;
  pid_t wait_pid = HANDLE_EINTR(waitpid(pid, &status, 0));
  if (wait_pid == -1) {
    PLOG(WARNING) << "waitpid";
    return true;
  }
  DCHECK_EQ(wait_pid, pid);

  if (WIFSIGNALED(status)) {
    int sig = WTERMSIG(status);
    LOG(WARNING) << base::StringPrintf(
        "intermediate process terminated by signal %d (%s)%s",
        sig,
        strsignal(sig),
        WCOREDUMP(status) ? " (core dumped)" : "");
  } else if (!WIFEXITED(status)) {
    LOG(WARNING) << base::StringPrintf(
        "intermediate process: unknown termination 0x%x", status);
  } else if (WEXITSTATUS(status) != EXIT_SUCCESS) {
    LOG(WARNING) << "intermediate process exited with code "
                 << WEXITSTATUS(status);
  }

  return true;
}

}  // namespace crashpad
