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