// 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
