// 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 "tools/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 <sys/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
    {
      // 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
