//===-- Host.cpp ----------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// C includes
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <sys/types.h>

#ifndef _WIN32
#include <dlfcn.h>
#include <grp.h>
#include <netdb.h>
#include <pwd.h>
#include <spawn.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#endif

#if defined(__APPLE__)
#include <mach-o/dyld.h>
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#endif

#if defined(__FreeBSD__)
#include <pthread_np.h>
#endif

#if defined(__NetBSD__)
#include <lwp.h>
#endif

#include <csignal>

#include "lldb/Host/FileAction.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/MonitoringProcessLauncher.h"
#include "lldb/Host/ProcessLaunchInfo.h"
#include "lldb/Host/ProcessLauncher.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-forward.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"

#if defined(_WIN32)
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#include "lldb/Host/windows/ProcessLauncherWindows.h"
#else
#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#endif

#if defined(__APPLE__)
#ifndef _POSIX_SPAWN_DISABLE_ASLR
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
#endif

extern "C" {
int __pthread_chdir(const char *path);
int __pthread_fchdir(int fildes);
}

#endif

using namespace lldb;
using namespace lldb_private;

#if !defined(__APPLE__) && !defined(_WIN32)
// The system log is currently only meaningful on Darwin and Windows.
// On Darwin, this means os_log. On Windows this means Events Viewer.
// The meaning of a "system log" isn't as clear on other platforms, and
// therefore we don't providate a default implementation. Vendors are free
// to implement this function if they have a use for it.
void Host::SystemLog(Severity severity, llvm::StringRef message) {}
#endif

static constexpr Log::Category g_categories[] = {
    {{"system"}, {"system log"}, SystemLog::System}};

static Log::Channel g_system_channel(g_categories, SystemLog::System);
static Log g_system_log(g_system_channel);

template <> Log::Channel &lldb_private::LogChannelFor<SystemLog>() {
  return g_system_channel;
}

void LogChannelSystem::Initialize() {
  g_system_log.Enable(std::make_shared<SystemLogHandler>());
}

void LogChannelSystem::Terminate() { g_system_log.Disable(); }

#if !defined(__APPLE__) && !defined(_WIN32)
extern "C" char **environ;

Environment Host::GetEnvironment() { return Environment(environ); }

static thread_result_t
MonitorChildProcessThreadFunction(::pid_t pid,
                                  Host::MonitorChildProcessCallback callback);

llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
    const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid) {
  char thread_name[256];
  ::snprintf(thread_name, sizeof(thread_name),
             "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
  assert(pid <= UINT32_MAX);
  return ThreadLauncher::LaunchThread(thread_name, [pid, callback] {
    return MonitorChildProcessThreadFunction(pid, callback);
  });
}

#ifndef __linux__
// Scoped class that will disable thread canceling when it is constructed, and
// exception safely restore the previous value it when it goes out of scope.
class ScopedPThreadCancelDisabler {
public:
  ScopedPThreadCancelDisabler() {
    // Disable the ability for this thread to be cancelled
    int err = ::pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m_old_state);
    if (err != 0)
      m_old_state = -1;
  }

  ~ScopedPThreadCancelDisabler() {
    // Restore the ability for this thread to be cancelled to what it
    // previously was.
    if (m_old_state != -1)
      ::pthread_setcancelstate(m_old_state, 0);
  }

private:
  int m_old_state; // Save the old cancelability state.
};
#endif // __linux__

#ifdef __linux__
static thread_local volatile sig_atomic_t g_usr1_called;

static void SigUsr1Handler(int) { g_usr1_called = 1; }
#endif // __linux__

static bool CheckForMonitorCancellation() {
#ifdef __linux__
  if (g_usr1_called) {
    g_usr1_called = 0;
    return true;
  }
#else
  ::pthread_testcancel();
#endif
  return false;
}

static thread_result_t
MonitorChildProcessThreadFunction(::pid_t pid,
                                  Host::MonitorChildProcessCallback callback) {
  Log *log = GetLog(LLDBLog::Process);
  LLDB_LOG(log, "pid = {0}", pid);

  int status = -1;

#ifdef __linux__
  // This signal is only used to interrupt the thread from waitpid
  struct sigaction sigUsr1Action;
  memset(&sigUsr1Action, 0, sizeof(sigUsr1Action));
  sigUsr1Action.sa_handler = SigUsr1Handler;
  ::sigaction(SIGUSR1, &sigUsr1Action, nullptr);
#endif // __linux__

  while (true) {
    log = GetLog(LLDBLog::Process);
    LLDB_LOG(log, "::waitpid({0}, &status, 0)...", pid);

    if (CheckForMonitorCancellation())
      return nullptr;

    const ::pid_t wait_pid = ::waitpid(pid, &status, 0);

    LLDB_LOG(log, "::waitpid({0}, &status, 0) => pid = {1}, status = {2:x}",
             pid, wait_pid, status);

    if (CheckForMonitorCancellation())
      return nullptr;

    if (wait_pid != -1)
      break;
    if (errno != EINTR) {
      LLDB_LOG(log, "pid = {0}, thread exiting because waitpid failed ({1})...",
               pid, llvm::sys::StrError());
      return nullptr;
    }
  }

  int signal = 0;
  int exit_status = 0;
  if (WIFEXITED(status)) {
    exit_status = WEXITSTATUS(status);
  } else if (WIFSIGNALED(status)) {
    signal = WTERMSIG(status);
    exit_status = -1;
  } else {
    llvm_unreachable("Unknown status");
  }

  // Scope for pthread_cancel_disabler
  {
#ifndef __linux__
    ScopedPThreadCancelDisabler pthread_cancel_disabler;
#endif

    if (callback)
      callback(pid, signal, exit_status);
  }

  LLDB_LOG(GetLog(LLDBLog::Process), "pid = {0} thread exiting...", pid);
  return nullptr;
}

#endif // #if !defined (__APPLE__) && !defined (_WIN32)

lldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); }

#ifndef _WIN32

lldb::thread_t Host::GetCurrentThread() {
  return lldb::thread_t(pthread_self());
}

const char *Host::GetSignalAsCString(int signo) {
  switch (signo) {
  case SIGHUP:
    return "SIGHUP"; // 1    hangup
  case SIGINT:
    return "SIGINT"; // 2    interrupt
  case SIGQUIT:
    return "SIGQUIT"; // 3    quit
  case SIGILL:
    return "SIGILL"; // 4    illegal instruction (not reset when caught)
  case SIGTRAP:
    return "SIGTRAP"; // 5    trace trap (not reset when caught)
  case SIGABRT:
    return "SIGABRT"; // 6    abort()
#if defined(SIGPOLL)
#if !defined(SIGIO) || (SIGPOLL != SIGIO)
  // Under some GNU/Linux, SIGPOLL and SIGIO are the same. Causing the build to
  // fail with 'multiple define cases with same value'
  case SIGPOLL:
    return "SIGPOLL"; // 7    pollable event ([XSR] generated, not supported)
#endif
#endif
#if defined(SIGEMT)
  case SIGEMT:
    return "SIGEMT"; // 7    EMT instruction
#endif
  case SIGFPE:
    return "SIGFPE"; // 8    floating point exception
  case SIGKILL:
    return "SIGKILL"; // 9    kill (cannot be caught or ignored)
  case SIGBUS:
    return "SIGBUS"; // 10    bus error
  case SIGSEGV:
    return "SIGSEGV"; // 11    segmentation violation
  case SIGSYS:
    return "SIGSYS"; // 12    bad argument to system call
  case SIGPIPE:
    return "SIGPIPE"; // 13    write on a pipe with no one to read it
  case SIGALRM:
    return "SIGALRM"; // 14    alarm clock
  case SIGTERM:
    return "SIGTERM"; // 15    software termination signal from kill
  case SIGURG:
    return "SIGURG"; // 16    urgent condition on IO channel
  case SIGSTOP:
    return "SIGSTOP"; // 17    sendable stop signal not from tty
  case SIGTSTP:
    return "SIGTSTP"; // 18    stop signal from tty
  case SIGCONT:
    return "SIGCONT"; // 19    continue a stopped process
  case SIGCHLD:
    return "SIGCHLD"; // 20    to parent on child stop or exit
  case SIGTTIN:
    return "SIGTTIN"; // 21    to readers pgrp upon background tty read
  case SIGTTOU:
    return "SIGTTOU"; // 22    like TTIN for output if (tp->t_local&LTOSTOP)
#if defined(SIGIO)
  case SIGIO:
    return "SIGIO"; // 23    input/output possible signal
#endif
  case SIGXCPU:
    return "SIGXCPU"; // 24    exceeded CPU time limit
  case SIGXFSZ:
    return "SIGXFSZ"; // 25    exceeded file size limit
  case SIGVTALRM:
    return "SIGVTALRM"; // 26    virtual time alarm
  case SIGPROF:
    return "SIGPROF"; // 27    profiling time alarm
#if defined(SIGWINCH)
  case SIGWINCH:
    return "SIGWINCH"; // 28    window size changes
#endif
#if defined(SIGINFO)
  case SIGINFO:
    return "SIGINFO"; // 29    information request
#endif
  case SIGUSR1:
    return "SIGUSR1"; // 30    user defined signal 1
  case SIGUSR2:
    return "SIGUSR2"; // 31    user defined signal 2
  default:
    break;
  }
  return nullptr;
}

#endif

#if !defined(__APPLE__) // see Host.mm

bool Host::GetBundleDirectory(const FileSpec &file, FileSpec &bundle) {
  bundle.Clear();
  return false;
}

bool Host::ResolveExecutableInBundle(FileSpec &file) { return false; }
#endif

#ifndef _WIN32

FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
  FileSpec module_filespec;
  Dl_info info;
  if (::dladdr(host_addr, &info)) {
    if (info.dli_fname) {
      module_filespec.SetFile(info.dli_fname, FileSpec::Style::native);
      FileSystem::Instance().Resolve(module_filespec);
    }
  }
  return module_filespec;
}

#endif

#if !defined(__linux__)
bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
  return false;
}
#endif

struct ShellInfo {
  ShellInfo() : process_reaped(false) {}

  lldb_private::Predicate<bool> process_reaped;
  lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
  int signo = -1;
  int status = -1;
};

static void
MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
                    int signo,  // Zero for no signal
                    int status) // Exit value of process if signal is zero
{
  shell_info->pid = pid;
  shell_info->signo = signo;
  shell_info->status = status;
  // Let the thread running Host::RunShellCommand() know that the process
  // exited and that ShellInfo has been filled in by broadcasting to it
  shell_info->process_reaped.SetValue(true, eBroadcastAlways);
}

Status Host::RunShellCommand(llvm::StringRef command,
                             const FileSpec &working_dir, int *status_ptr,
                             int *signo_ptr, std::string *command_output_ptr,
                             std::string *separated_error_output,
                             const Timeout<std::micro> &timeout,
                             bool run_in_shell) {
  return RunShellCommand(llvm::StringRef(), Args(command), working_dir,
                         status_ptr, signo_ptr, command_output_ptr,
                         separated_error_output, timeout, run_in_shell);
}

Status Host::RunShellCommand(llvm::StringRef shell_path,
                             llvm::StringRef command,
                             const FileSpec &working_dir, int *status_ptr,
                             int *signo_ptr, std::string *command_output_ptr,
                             std::string *separated_error_output,
                             const Timeout<std::micro> &timeout,
                             bool run_in_shell) {
  return RunShellCommand(shell_path, Args(command), working_dir, status_ptr,
                         signo_ptr, command_output_ptr, separated_error_output,
                         timeout, run_in_shell);
}

Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
                             int *status_ptr, int *signo_ptr,
                             std::string *command_output_ptr,
                             std::string *separated_error_output,
                             const Timeout<std::micro> &timeout,
                             bool run_in_shell) {
  return RunShellCommand(llvm::StringRef(), args, working_dir, status_ptr,
                         signo_ptr, command_output_ptr, separated_error_output,
                         timeout, run_in_shell);
}

Status Host::RunShellCommand(llvm::StringRef shell_path, const Args &args,
                             const FileSpec &working_dir, int *status_ptr,
                             int *signo_ptr, std::string *command_output_ptr,
                             std::string *separated_error_output,
                             const Timeout<std::micro> &timeout,
                             bool run_in_shell) {
  Status error;
  ProcessLaunchInfo launch_info;
  launch_info.SetArchitecture(HostInfo::GetArchitecture());
  if (run_in_shell) {
    // Run the command in a shell
    FileSpec shell = HostInfo::GetDefaultShell();
    if (!shell_path.empty())
      shell.SetPath(shell_path);

    launch_info.SetShell(shell);
    launch_info.GetArguments().AppendArguments(args);
    const bool will_debug = false;
    const bool first_arg_is_full_shell_command = false;
    launch_info.ConvertArgumentsForLaunchingInShell(
        error, will_debug, first_arg_is_full_shell_command, 0);
  } else {
    // No shell, just run it
    const bool first_arg_is_executable = true;
    launch_info.SetArguments(args, first_arg_is_executable);
  }

  launch_info.GetEnvironment() = Host::GetEnvironment();

  if (working_dir)
    launch_info.SetWorkingDirectory(working_dir);
  llvm::SmallString<64> output_file_path;
  llvm::SmallString<64> error_file_path;

  if (command_output_ptr) {
    // Create a temporary file to get the stdout and redirect the output
    // of the command into this file. We will later read this file if all goes
    // well and fill the data into "command_output_ptr"
    if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
      tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%");
      llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
                                      output_file_path);
    } else {
      llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "",
                                         output_file_path);
    }
  }

  if (separated_error_output) {
    // Create a temporary file to get the stderr and redirect the output
    // of the command into this file. We will later read this file if all goes
    // well and fill the data into "separated_error_output".
    if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
      tmpdir_file_spec.AppendPathComponent("lldb-shell-error.%%%%%%");
      llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(),
                                      error_file_path);
    } else {
      llvm::sys::fs::createTemporaryFile("lldb-shell-error.%%%%%%", "",
                                         error_file_path);
    }
  }

  FileSpec output_file_spec(output_file_path.str());
  FileSpec error_file_spec(error_file_path.str());
  // Set up file descriptors.
  launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
  if (output_file_spec)
    launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false,
                                     true);
  else
    launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);

  if (error_file_spec)
    launch_info.AppendOpenFileAction(STDERR_FILENO, error_file_spec, false,
                                     true);
  else
    launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);

  std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo());
  launch_info.SetMonitorProcessCallback(
      std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3));

  error = LaunchProcess(launch_info);
  const lldb::pid_t pid = launch_info.GetProcessID();

  if (error.Success() && pid == LLDB_INVALID_PROCESS_ID)
    error = Status::FromErrorString("failed to get process ID");

  if (error.Success()) {
    if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) {
      error = Status::FromErrorString(
          "timed out waiting for shell command to complete");

      // Kill the process since it didn't complete within the timeout specified
      Kill(pid, SIGKILL);
      // Wait for the monitor callback to get the message
      shell_info_sp->process_reaped.WaitForValueEqualTo(
          true, std::chrono::seconds(1));
    } else {
      if (status_ptr)
        *status_ptr = shell_info_sp->status;

      if (signo_ptr)
        *signo_ptr = shell_info_sp->signo;

      if (command_output_ptr) {
        command_output_ptr->clear();
        uint64_t file_size =
            FileSystem::Instance().GetByteSize(output_file_spec);
        if (file_size > 0) {
          if (file_size > command_output_ptr->max_size()) {
            error = Status::FromErrorStringWithFormat(
                "shell command output is too large to fit into a std::string");
          } else {
            WritableDataBufferSP Buffer =
                FileSystem::Instance().CreateWritableDataBuffer(
                    output_file_spec);
            if (error.Success())
              command_output_ptr->assign(
                  reinterpret_cast<char *>(Buffer->GetBytes()),
                  Buffer->GetByteSize());
          }
        }
      }
      if (separated_error_output) {
        separated_error_output->clear();
        uint64_t file_size =
            FileSystem::Instance().GetByteSize(error_file_spec);
        if (file_size > 0) {
          if (file_size > separated_error_output->max_size()) {
            error = Status::FromErrorStringWithFormat(
                "shell command error output is too large to fit into a "
                "std::string");
          } else {
            WritableDataBufferSP Buffer =
                FileSystem::Instance().CreateWritableDataBuffer(
                    error_file_spec);
            if (error.Success())
              separated_error_output->assign(
                  reinterpret_cast<char *>(Buffer->GetBytes()),
                  Buffer->GetByteSize());
          }
        }
      }
    }
  }

  if (output_file_spec)
    llvm::sys::fs::remove(output_file_spec.GetPath());
  if (error_file_spec)
    llvm::sys::fs::remove(error_file_spec.GetPath());
  return error;
}

// The functions below implement process launching for non-Apple-based
// platforms
#if !defined(__APPLE__)
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
  std::unique_ptr<ProcessLauncher> delegate_launcher;
#if defined(_WIN32)
  delegate_launcher.reset(new ProcessLauncherWindows());
#else
  delegate_launcher.reset(new ProcessLauncherPosixFork());
#endif
  MonitoringProcessLauncher launcher(std::move(delegate_launcher));

  Status error;
  HostProcess process = launcher.LaunchProcess(launch_info, error);

  // TODO(zturner): It would be better if the entire HostProcess were returned
  // instead of writing it into this structure.
  launch_info.SetProcessID(process.GetProcessId());

  return error;
}
#endif // !defined(__APPLE__)

#ifndef _WIN32
void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); }

#endif

#if !defined(__APPLE__)
llvm::Error Host::OpenFileInExternalEditor(llvm::StringRef editor,
                                           const FileSpec &file_spec,
                                           uint32_t line_no) {
  return llvm::errorCodeToError(
      std::error_code(ENOTSUP, std::system_category()));
}

bool Host::IsInteractiveGraphicSession() { return false; }
#endif

std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) {
#if defined(_WIN32)
  if (url.starts_with("file://"))
    return std::unique_ptr<Connection>(new ConnectionGenericFile());
#endif
  return std::unique_ptr<Connection>(new ConnectionFileDescriptor());
}

#if defined(LLVM_ON_UNIX)
WaitStatus WaitStatus::Decode(int wstatus) {
  if (WIFEXITED(wstatus))
    return {Exit, uint8_t(WEXITSTATUS(wstatus))};
  else if (WIFSIGNALED(wstatus))
    return {Signal, uint8_t(WTERMSIG(wstatus))};
  else if (WIFSTOPPED(wstatus))
    return {Stop, uint8_t(WSTOPSIG(wstatus))};
  llvm_unreachable("Unknown wait status");
}
#endif

void llvm::format_provider<WaitStatus>::format(const WaitStatus &WS,
                                               raw_ostream &OS,
                                               StringRef Options) {
  if (Options == "g") {
    char type;
    switch (WS.type) {
    case WaitStatus::Exit:
      type = 'W';
      break;
    case WaitStatus::Signal:
      type = 'X';
      break;
    case WaitStatus::Stop:
      type = 'S';
      break;
    }
    OS << formatv("{0}{1:x-2}", type, WS.status);
    return;
  }

  assert(Options.empty());
  const char *desc;
  switch (WS.type) {
  case WaitStatus::Exit:
    desc = "Exited with status";
    break;
  case WaitStatus::Signal:
    desc = "Killed by signal";
    break;
  case WaitStatus::Stop:
    desc = "Stopped by signal";
    break;
  }
  OS << desc << " " << int(WS.status);
}

uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                             ProcessInstanceInfoList &process_infos) {
  return FindProcessesImpl(match_info, process_infos);
}

char SystemLogHandler::ID;

SystemLogHandler::SystemLogHandler() {}

void SystemLogHandler::Emit(llvm::StringRef message) {
  Host::SystemLog(lldb::eSeverityInfo, message);
}
