// Copyright 2014 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 "gn/exec_process.h"

#include <stddef.h>

#include <memory>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "util/build_config.h"

#if defined(OS_WIN)
#include <windows.h>

#include "base/win/scoped_handle.h"
#include "base/win/scoped_process_information.h"
#include "base/win/win_util.h"
#else
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>

#include "base/posix/eintr_wrapper.h"
#include "base/posix/file_descriptor_shuffle.h"
#endif

namespace internal {

#if defined(OS_WIN)
bool ExecProcess(const base::CommandLine& cmdline,
                 const base::FilePath& startup_dir,
                 std::string* std_out,
                 std::string* std_err,
                 int* exit_code) {
  return ExecProcess(cmdline.GetCommandLineString(), startup_dir, std_out,
                     std_err, exit_code);
}

bool ExecProcess(const std::u16string& cmdline_str,
                 const base::FilePath& startup_dir,
                 std::string* std_out,
                 std::string* std_err,
                 int* exit_code) {
  SECURITY_ATTRIBUTES sa_attr;
  // Set the bInheritHandle flag so pipe handles are inherited.
  sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
  sa_attr.bInheritHandle = TRUE;
  sa_attr.lpSecurityDescriptor = nullptr;

  // Create the pipe for the child process's STDOUT.
  HANDLE out_read = nullptr;
  HANDLE out_write = nullptr;
  if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) {
    NOTREACHED() << "Failed to create pipe";
    return false;
  }
  base::win::ScopedHandle scoped_out_read(out_read);
  base::win::ScopedHandle scoped_out_write(out_write);

  // Create the pipe for the child process's STDERR.
  HANDLE err_read = nullptr;
  HANDLE err_write = nullptr;
  if (!CreatePipe(&err_read, &err_write, &sa_attr, 0)) {
    NOTREACHED() << "Failed to create pipe";
    return false;
  }
  base::win::ScopedHandle scoped_err_read(err_read);
  base::win::ScopedHandle scoped_err_write(err_write);

  // Ensure the read handle to the pipe for STDOUT/STDERR is not inherited.
  if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
    NOTREACHED() << "Failed to disable pipe inheritance";
    return false;
  }
  if (!SetHandleInformation(err_read, HANDLE_FLAG_INHERIT, 0)) {
    NOTREACHED() << "Failed to disable pipe inheritance";
    return false;
  }

  STARTUPINFO start_info = {};

  start_info.cb = sizeof(STARTUPINFO);
  start_info.hStdOutput = out_write;
  // Keep the normal stdin.
  start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  // FIXME(brettw) set stderr here when we actually read it below.
  // start_info.hStdError = err_write;
  start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  start_info.dwFlags |= STARTF_USESTDHANDLES;

  std::u16string cmdline_writable = cmdline_str;

  // Create the child process.
  PROCESS_INFORMATION temp_process_info = {};
  if (!CreateProcess(
          nullptr, base::ToWCharT(&cmdline_writable[0]), nullptr, nullptr,
          TRUE,  // Handles are inherited.
          NORMAL_PRIORITY_CLASS, nullptr, base::ToWCharT(&startup_dir.value()),
          &start_info, &temp_process_info)) {
    return false;
  }
  base::win::ScopedProcessInformation proc_info(temp_process_info);

  // Close our writing end of pipes now. Otherwise later read would not be
  // able to detect end of child's output.
  scoped_out_write.Close();
  scoped_err_write.Close();

  // Read output from the child process's pipe for STDOUT
  const int kBufferSize = 1024;
  char buffer[kBufferSize];

  // FIXME(brettw) read from stderr here! This is complicated because we want
  // to read both of them at the same time, probably need overlapped I/O.
  // Also uncomment start_info code above.
  for (;;) {
    DWORD bytes_read = 0;
    BOOL success =
        ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr);
    if (!success || bytes_read == 0)
      break;
    std_out->append(buffer, bytes_read);
  }

  // Let's wait for the process to finish.
  WaitForSingleObject(proc_info.process_handle(), INFINITE);

  DWORD dw_exit_code;
  GetExitCodeProcess(proc_info.process_handle(), &dw_exit_code);
  *exit_code = static_cast<int>(dw_exit_code);

  return true;
}
#else
// Reads from the provided file descriptor and appends to output. Returns false
// if the fd is closed or there is an unexpected error (not
// EINTR/EAGAIN/EWOULDBLOCK).
bool ReadFromPipe(int fd, std::string* output) {
  char buffer[256];
  int bytes_read = HANDLE_EINTR(read(fd, buffer, sizeof(buffer)));
  if (bytes_read == -1) {
    return errno == EAGAIN || errno == EWOULDBLOCK;
  } else if (bytes_read <= 0) {
    return false;
  }
  output->append(buffer, bytes_read);
  return true;
}

bool WaitForExit(int pid, int* exit_code) {
  int status;
  if (waitpid(pid, &status, 0) < 0) {
    PLOG(ERROR) << "waitpid";
    return false;
  }

  if (WIFEXITED(status)) {
    *exit_code = WEXITSTATUS(status);
    return true;
  } else if (WIFSIGNALED(status)) {
    if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM ||
        WTERMSIG(status) == SIGHUP)
      return false;
  }
  return false;
}

bool ExecProcess(const base::CommandLine& cmdline,
                 const base::FilePath& startup_dir,
                 std::string* std_out,
                 std::string* std_err,
                 int* exit_code) {
  *exit_code = EXIT_FAILURE;

  std::vector<std::string> argv = cmdline.argv();

  int out_fd[2], err_fd[2];
  pid_t pid;
  base::InjectiveMultimap fd_shuffle1, fd_shuffle2;
  std::unique_ptr<char*[]> argv_cstr(new char*[argv.size() + 1]);

  fd_shuffle1.reserve(3);
  fd_shuffle2.reserve(3);

  if (pipe(out_fd) < 0)
    return false;
  base::ScopedFD out_read(out_fd[0]), out_write(out_fd[1]);

  if (pipe(err_fd) < 0)
    return false;
  base::ScopedFD err_read(err_fd[0]), err_write(err_fd[1]);

  if (out_read.get() >= FD_SETSIZE || err_read.get() >= FD_SETSIZE)
    return false;

  switch (pid = fork()) {
    case -1:  // error
      return false;
    case 0:  // child
    {
#if defined(OS_MAC)
      // When debugging the app under Xcode, the child will receive a SIGTRAP
      // signal which will terminate the child process. Ignore the signal to
      // allow debugging under macOS.
      sigignore(SIGTRAP);
#endif

      // DANGER: no calls to malloc are allowed from now on:
      // http://crbug.com/36678
      //
      // STL iterators are also not allowed (including those implied
      // by range-based for loops), since debug iterators use locks.

      // Obscure fork() rule: in the child, if you don't end up doing exec*(),
      // you call _exit() instead of exit(). This is because _exit() does not
      // call any previously-registered (in the parent) exit handlers, which
      // might do things like block waiting for threads that don't even exist
      // in the child.
      int dev_null = open("/dev/null", O_WRONLY);
      if (dev_null < 0)
        _exit(127);

      fd_shuffle1.push_back(
          base::InjectionArc(out_write.get(), STDOUT_FILENO, true));
      fd_shuffle1.push_back(
          base::InjectionArc(err_write.get(), STDERR_FILENO, true));
      fd_shuffle1.push_back(base::InjectionArc(dev_null, STDIN_FILENO, true));
      // Adding another element here? Remeber to increase the argument to
      // reserve(), above.

      // DANGER: Do NOT convert to range-based for loop!
      for (size_t i = 0; i < fd_shuffle1.size(); ++i)
        fd_shuffle2.push_back(fd_shuffle1[i]);

      if (!ShuffleFileDescriptors(&fd_shuffle1))
        _exit(127);

      base::SetCurrentDirectory(startup_dir);

      // TODO(brettw) the base version GetAppOutput does a
      // CloseSuperfluousFds call here. Do we need this?

      // DANGER: Do NOT convert to range-based for loop!
      for (size_t i = 0; i < argv.size(); i++)
        argv_cstr[i] = const_cast<char*>(argv[i].c_str());
      argv_cstr[argv.size()] = nullptr;
      execvp(argv_cstr[0], argv_cstr.get());
      _exit(127);
    }
    default:  // parent
    {
      // Close our writing end of pipe now. Otherwise later read would not
      // be able to detect end of child's output (in theory we could still
      // write to the pipe).
      out_write.reset();
      err_write.reset();

      bool out_open = true, err_open = true;
      while (out_open || err_open) {
        fd_set read_fds;
        FD_ZERO(&read_fds);
        FD_SET(out_read.get(), &read_fds);
        FD_SET(err_read.get(), &read_fds);
        int res =
            HANDLE_EINTR(select(std::max(out_read.get(), err_read.get()) + 1,
                                &read_fds, nullptr, nullptr, nullptr));
        if (res <= 0)
          break;
        if (FD_ISSET(out_read.get(), &read_fds))
          out_open = ReadFromPipe(out_read.get(), std_out);
        if (FD_ISSET(err_read.get(), &read_fds))
          err_open = ReadFromPipe(err_read.get(), std_err);
      }

      return WaitForExit(pid, exit_code);
    }
  }

  return false;
}
#endif

}  // namespace internal
