// Copyright 2015 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 "services/native_support/process_impl.h"

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include <algorithm>
#include <limits>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/environment.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "build/build_config.h"
#include "mojo/services/files/public/interfaces/types.mojom.h"
#include "services/native_support/make_pty_pair.h"
#include "services/native_support/process_controller_impl.h"
#include "services/native_support/process_io_redirection.h"

namespace native_support {

namespace {

class SetsidPreExecDelegate : public base::LaunchOptions::PreExecDelegate {
 public:
  SetsidPreExecDelegate() {}
  ~SetsidPreExecDelegate() override {}

  void RunAsyncSafe() override {
    static const char kErrorMessage[] = "setsid() failed";

    // Note: |setsid()| and |write()| are both async-signal-safe.
    if (setsid() == static_cast<pid_t>(-1))
      write(STDERR_FILENO, kErrorMessage, sizeof(kErrorMessage) - 1);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(SetsidPreExecDelegate);
};

}  // namespace

ProcessImpl::ProcessImpl(scoped_refptr<base::TaskRunner> worker_runner,
                         mojo::ApplicationConnection* connection,
                         mojo::InterfaceRequest<Process> request)
    : worker_runner_(worker_runner.Pass()), binding_(this, request.Pass()) {}

ProcessImpl::~ProcessImpl() {}

void ProcessImpl::Spawn(
    const mojo::String& path,
    mojo::Array<mojo::String> argv,
    mojo::Array<mojo::String> envp,
    mojo::files::FilePtr stdin_file,
    mojo::files::FilePtr stdout_file,
    mojo::files::FilePtr stderr_file,
    mojo::InterfaceRequest<ProcessController> process_controller,
    const SpawnCallback& callback) {
  std::vector<int> fds_to_inherit(3, -1);

  // stdin:
  base::ScopedFD stdin_fd;
  base::ScopedFD stdin_parent_fd;
  if (stdin_file) {
    int stdin_pipe_fds[2] = {-1, -1};
    CHECK_EQ(pipe(stdin_pipe_fds), 0);
    stdin_fd.reset(stdin_pipe_fds[0]);
    stdin_parent_fd.reset(stdin_pipe_fds[1]);
  } else {
    stdin_fd.reset(HANDLE_EINTR(open("/dev/null", O_RDONLY)));
  }
  fds_to_inherit[STDIN_FILENO] = stdin_fd.get();

  // stdout:
  base::ScopedFD stdout_fd;
  base::ScopedFD stdout_parent_fd;
  if (stdout_file) {
    int stdout_pipe_fds[2] = {-1, -1};
    CHECK_EQ(pipe(stdout_pipe_fds), 0);
    stdout_fd.reset(stdout_pipe_fds[1]);
    stdout_parent_fd.reset(stdout_pipe_fds[0]);
  } else {
    stdout_fd.reset(HANDLE_EINTR(open("/dev/null", O_WRONLY)));
  }
  fds_to_inherit[STDOUT_FILENO] = stdout_fd.get();

  // stderr:
  base::ScopedFD stderr_fd;
  base::ScopedFD stderr_parent_fd;
  if (stderr_file) {
    int stderr_pipe_fds[2] = {-1, -1};
    CHECK_EQ(pipe(stderr_pipe_fds), 0);
    stderr_fd.reset(stderr_pipe_fds[1]);
    stderr_parent_fd.reset(stderr_pipe_fds[0]);
  } else {
    stderr_fd.reset(HANDLE_EINTR(open("/dev/null", O_WRONLY)));
  }
  fds_to_inherit[STDERR_FILENO] = stderr_fd.get();

  std::unique_ptr<ProcessIORedirection> process_io_redirection(
      new ProcessIORedirectionForStdIO(
          stdin_file.Pass(), stdout_file.Pass(), stderr_file.Pass(),
          stdin_parent_fd.Pass(), stdout_parent_fd.Pass(),
          stderr_parent_fd.Pass()));

  SpawnImpl(path, argv.Pass(), envp.Pass(), std::move(process_io_redirection),
            fds_to_inherit, process_controller.Pass(), callback);
}

void ProcessImpl::SpawnWithTerminal(
    const mojo::String& path,
    mojo::Array<mojo::String> argv,
    mojo::Array<mojo::String> envp,
    mojo::files::FilePtr terminal_file,
    mojo::InterfaceRequest<ProcessController> process_controller,
    const SpawnWithTerminalCallback& callback) {
  DCHECK(terminal_file);

  std::vector<int> fds_to_inherit(3, -1);

  base::ScopedFD master_fd;
  base::ScopedFD slave_fd;
  int errno_value = 0;
  if (!MakePtyPair(&master_fd, &slave_fd, &errno_value)) {
    // TODO(vtl): Well, this is dumb (we should use errno_value).
    callback.Run(mojo::files::ERROR_UNKNOWN);
    return;
  }

  // stdin:
  base::ScopedFD stdin_fd(slave_fd.Pass());
  fds_to_inherit[STDIN_FILENO] = stdin_fd.get();

  // stdout:
  base::ScopedFD stdout_fd(HANDLE_EINTR(dup(stdin_fd.get())));
  fds_to_inherit[STDOUT_FILENO] = stdout_fd.get();

  // stderr:
  base::ScopedFD stderr_fd(HANDLE_EINTR(dup(stdin_fd.get())));
  fds_to_inherit[STDERR_FILENO] = stderr_fd.get();

  std::unique_ptr<ProcessIORedirection> process_io_redirection(
      new ProcessIORedirectionForTerminal(terminal_file.Pass(),
                                          master_fd.Pass()));

  SpawnImpl(path, argv.Pass(), envp.Pass(), std::move(process_io_redirection),
            fds_to_inherit, process_controller.Pass(), callback);
}

void ProcessImpl::SpawnImpl(
    const mojo::String& path,
    mojo::Array<mojo::String> argv,
    mojo::Array<mojo::String> envp,
    std::unique_ptr<ProcessIORedirection> process_io_redirection,
    const std::vector<int>& fds_to_inherit,
    mojo::InterfaceRequest<ProcessController> process_controller,
    const SpawnCallback& callback) {
  DCHECK(!path.is_null());
  DCHECK(process_controller.is_pending());

  size_t argc = std::max(argv.size(), static_cast<size_t>(1));
  std::vector<const char*> argv_ptrs(argc);
  if (argv.is_null()) {
    argv_ptrs[0] = path.data();
  } else {
    if (!argv.size() ||
        argv.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
      callback.Run(mojo::files::ERROR_INVALID_ARGUMENT);
      return;
    }
    // TODO(vtl): Currently, we don't support setting argv[0], due to
    // |base::CommandLine| limitations.
    argv_ptrs[0] = path.data();
    for (size_t i = 1; i < argv.size(); i++)
      argv_ptrs[i] = argv[i].data();
  }
  base::CommandLine command_line(static_cast<int>(argc), argv_ptrs.data());

  bool inherit_environment = true;
  base::EnvironmentMap environment_map;
  if (!envp.is_null()) {
    inherit_environment = false;
    for (size_t i = 0; i < envp.size(); i++) {
      std::string s(envp[i].data());
      size_t equals_pos = s.find_first_of('=');
      environment_map[s.substr(0, equals_pos)] =
          (equals_pos == std::string::npos) ? std::string()
                                            : s.substr(equals_pos + 1);
    }
  }

  base::FileHandleMappingVector fd_mapping;
  DCHECK(fds_to_inherit.size() >= 3);
  for (size_t i = 0; i < fds_to_inherit.size(); i++) {
    DCHECK_GE(fds_to_inherit[i], 0);
    fd_mapping.push_back(
        std::make_pair(fds_to_inherit[i], static_cast<int>(i)));
  }

  SetsidPreExecDelegate pre_exec_delegate;
  base::LaunchOptions launch_options;
  launch_options.wait = false;
  launch_options.environ.swap(environment_map);
  launch_options.clear_environ = !inherit_environment;
  launch_options.fds_to_remap = &fd_mapping;
  // launch_options.maximize_rlimits
  launch_options.new_process_group = false;
  // launch_options.clone_flags = 0;
#if defined(OS_LINUX)
  launch_options.allow_new_privs = true;
#endif
  // launch_options.kill_on_parent_death = true;
  // launch_options.current_directory
  launch_options.pre_exec_delegate = &pre_exec_delegate;

  base::Process process = LaunchProcess(command_line, launch_options);
  // Note: Failure is extremely unusual. E.g., it won't fail even if |path|
  // doesn't exist (since fork succeeds; it's the exec that fails).
  if (!process.IsValid()) {
    // TODO(vtl): Well, this is dumb (can we check errno?).
    callback.Run(mojo::files::ERROR_UNKNOWN);
    return;
  }

  new ProcessControllerImpl(worker_runner_, process_controller.Pass(),
                            process.Pass(), std::move(process_io_redirection));
  callback.Run(mojo::files::ERROR_OK);
}

}  // namespace native_support
