//===-- 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 <errno.h>
#include <limits.h>
#include <stdlib.h>
#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), pid(LLDB_INVALID_PROCESS_ID), signo(-1),
        status(-1) {}

  lldb_private::Predicate<bool> process_reaped;
  lldb::pid_t pid;
  int signo;
  int status;
};

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;
}
