// 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 "build_config.h"

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

#include "base/win/scoped_handle.h"
#include "base/win/scoped_process_information.h"
#else
#include <errno.h>
#include <fcntl.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 base::string16& 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;

  base::string16 cmdline_writable = cmdline_str;

  // Create the child process.
  PROCESS_INFORMATION temp_process_info = {};
  if (!CreateProcess(nullptr, &cmdline_writable[0], nullptr, nullptr,
                     TRUE,  // Handles are inherited.
                     NORMAL_PRIORITY_CLASS, nullptr,
                     startup_dir.value().c_str(), &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
