//===-- 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 <sys/stat.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(__linux__) || defined(__FreeBSD__) ||                              \
    defined(__FreeBSD_kernel__) || defined(__APPLE__) ||                       \
    defined(__NetBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
#if !defined(__ANDROID__)
#include <spawn.h>
#endif
#include <sys/syscall.h>
#include <sys/wait.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/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/ReproducerProvider.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-forward.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#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)
struct MonitorInfo {
  lldb::pid_t pid; // The process ID to monitor
  Host::MonitorChildProcessCallback
      callback; // The callback function to call when "pid" exits or signals
  bool monitor_signals; // If true, call the callback when "pid" gets signaled.
};

static thread_result_t MonitorChildProcessThreadFunction(void *arg);

llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
    const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
    bool monitor_signals) {
  MonitorInfo *info_ptr = new MonitorInfo();

  info_ptr->pid = pid;
  info_ptr->callback = callback;
  info_ptr->monitor_signals = monitor_signals;

  char thread_name[256];
  ::snprintf(thread_name, sizeof(thread_name),
             "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
  return ThreadLauncher::LaunchThread(
      thread_name, MonitorChildProcessThreadFunction, info_ptr, 0);
}

#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__
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
static __thread volatile sig_atomic_t g_usr1_called;
#else
static thread_local volatile sig_atomic_t g_usr1_called;
#endif

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(void *arg) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  const char *function = __FUNCTION__;
  LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg);

  MonitorInfo *info = (MonitorInfo *)arg;

  const Host::MonitorChildProcessCallback callback = info->callback;
  const bool monitor_signals = info->monitor_signals;

  assert(info->pid <= UINT32_MAX);
  const ::pid_t pid = monitor_signals ? -1 * getpgid(info->pid) : info->pid;

  delete info;

  int status = -1;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
#define __WALL 0
#endif
  const int options = __WALL;

#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 (1) {
    log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
    LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...",
              function, pid, options);

    if (CheckForMonitorCancellation())
      break;

    // Get signals from all children with same process group of pid
    const ::pid_t wait_pid = ::waitpid(pid, &status, options);

    if (CheckForMonitorCancellation())
      break;

    if (wait_pid == -1) {
      if (errno == EINTR)
        continue;
      else {
        LLDB_LOG(log,
                 "arg = {0}, thread exiting because waitpid failed ({1})...",
                 arg, llvm::sys::StrError());
        break;
      }
    } else if (wait_pid > 0) {
      bool exited = false;
      int signal = 0;
      int exit_status = 0;
      const char *status_cstr = nullptr;
      if (WIFSTOPPED(status)) {
        signal = WSTOPSIG(status);
        status_cstr = "STOPPED";
      } else if (WIFEXITED(status)) {
        exit_status = WEXITSTATUS(status);
        status_cstr = "EXITED";
        exited = true;
      } else if (WIFSIGNALED(status)) {
        signal = WTERMSIG(status);
        status_cstr = "SIGNALED";
        if (wait_pid == abs(pid)) {
          exited = true;
          exit_status = -1;
        }
      } else {
        status_cstr = "(\?\?\?)";
      }

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

        log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
        LLDB_LOGF(log,
                  "%s ::waitpid (pid = %" PRIi32
                  ", &status, options = %i) => pid = %" PRIi32
                  ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
                  function, pid, options, wait_pid, status, status_cstr, signal,
                  exit_status);

        if (exited || (signal != 0 && monitor_signals)) {
          bool callback_return = false;
          if (callback)
            callback_return = callback(wait_pid, exited, signal, exit_status);

          // If our process exited, then this thread should exit
          if (exited && wait_pid == abs(pid)) {
            LLDB_LOGF(log,
                      "%s (arg = %p) thread exiting because pid received "
                      "exit signal...",
                      __FUNCTION__, arg);
            break;
          }
          // If the callback returns true, it means this process should exit
          if (callback_return) {
            LLDB_LOGF(log,
                      "%s (arg = %p) thread exiting because callback "
                      "returned true...",
                      __FUNCTION__, arg);
            break;
          }
        }
      }
    }
  }

  log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS);
  LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg);

  return nullptr;
}

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

#if !defined(__APPLE__)

void Host::SystemLog(SystemLogType type, const char *format, va_list args) {
  vfprintf(stderr, format, args);
}

#endif

void Host::SystemLog(SystemLogType type, const char *format, ...) {
  {
    va_list args;
    va_start(args, format);
    SystemLog(type, format, args);
    va_end(args);
  }

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST));
  if (log && log->GetVerbose()) {
    // Log to log channel. This allows testcases to grep for log output.
    va_list args;
    va_start(args, format);
    log->VAPrintf(format, args);
    va_end(args);
  }
}

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;
#if !defined(__ANDROID__)
  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);
    }
  }
#endif
  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 bool
MonitorShellCommand(std::shared_ptr<ShellInfo> shell_info, lldb::pid_t pid,
                    bool exited, // True if the process did exit
                    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);
  return true;
}

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

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,
                             const Timeout<std::micro> &timeout,
                             bool run_in_shell, bool hide_stderr) {
  return RunShellCommand(shell_path, Args(command), working_dir, status_ptr,
                         signo_ptr, command_output_ptr, timeout, run_in_shell,
                         hide_stderr);
}

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

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,
                             const Timeout<std::micro> &timeout,
                             bool run_in_shell, bool hide_stderr) {
  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;

  if (command_output_ptr) {
    // Create a temporary file to get the stdout/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 "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);
    }
  }

  FileSpec output_file_spec(output_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 (output_file_spec && !hide_stderr)
    launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
  else
    launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);

  std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo());
  const bool monitor_signals = false;
  launch_info.SetMonitorProcessCallback(
      std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1,
                std::placeholders::_2, std::placeholders::_3,
                std::placeholders::_4),
      monitor_signals);

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

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

  if (error.Success()) {
    if (!shell_info_sp->process_reaped.WaitForValueEqualTo(true, timeout)) {
      error.SetErrorString("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.SetErrorStringWithFormat(
                "shell command output is too large to fit into a std::string");
          } else {
            auto Buffer =
                FileSystem::Instance().CreateDataBuffer(output_file_spec);
            if (error.Success())
              command_output_ptr->assign(Buffer->GetChars(),
                                         Buffer->GetByteSize());
          }
        }
      }
    }
  }

  llvm::sys::fs::remove(output_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__)
bool Host::OpenFileInExternalEditor(const FileSpec &file_spec,
                                    uint32_t line_no) {
  return false;
}

#endif

std::unique_ptr<Connection> Host::CreateDefaultConnection(llvm::StringRef url) {
#if defined(_WIN32)
  if (url.startswith("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) {

  if (llvm::Optional<ProcessInstanceInfoList> infos =
          repro::GetReplayProcessInstanceInfoList()) {
    process_infos = *infos;
    return process_infos.size();
  }

  uint32_t result = FindProcessesImpl(match_info, process_infos);

  if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
    g->GetOrCreate<repro::ProcessInfoProvider>()
        .GetNewProcessInfoRecorder()
        ->Record(process_infos);
  }

  return result;
}
