//===-- ExecuteFunction implementation for Unix-like Systems --------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "src/__support/CPP/scope.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
#include "test/UnitTest/ExecuteFunction.h"

#ifdef LIBC_FULL_BUILD
#include "include/llvm-libc-macros/poll-macros.h"
#include "include/llvm-libc-macros/signal-macros.h"
#include "include/llvm-libc-macros/sys-wait-macros.h"
#include "include/llvm-libc-types/pid_t.h"
#include "include/llvm-libc-types/struct_pollfd.h"
#include "src/poll/poll.h"
#include "src/signal/kill.h"
#include "src/signal/signal.h"
#include "src/stdio/fflush.h"
#include "src/stdio/stderr.h"
#include "src/stdio/stdout.h"
#include "src/stdlib/exit.h"
#include "src/string/strsignal.h"
#include "src/sys/wait/waitpid.h"
#include "src/unistd/close.h"
#include "src/unistd/fork.h"
#include "src/unistd/pipe.h"
#ifdef __linux__
#include "src/sys/prctl/prctl.h"
#include <linux/prctl.h>
#endif

#define LIBC_IMPL LIBC_NAMESPACE

#else // Overlay mode
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#ifdef __linux__
#include <sys/prctl.h>
#endif

#define LIBC_IMPL
#endif

namespace LIBC_NAMESPACE_DECL {
namespace testutils {

bool ProcessStatus::exited_normally() { return WIFEXITED(platform_defined); }

int ProcessStatus::get_exit_code() {
  LIBC_ASSERT(exited_normally() && "Abnormal termination, no exit code");
  return WEXITSTATUS(platform_defined);
}

int ProcessStatus::get_fatal_signal() {
  if (exited_normally())
    return 0;
  return WTERMSIG(platform_defined);
}

ProcessStatus invoke_in_subprocess(cpp::function_ref<void(void)> func,
                                   int timeout_ms) {
  int pipe_fds[2];
  if (LIBC_IMPL::pipe(pipe_fds) == -1)
    return ProcessStatus::error("pipe(2) failed");

  // Don't copy the buffers into the child process and print twice.
  LIBC_IMPL::fflush(stderr);
  LIBC_IMPL::fflush(stdout);
  pid_t pid = LIBC_IMPL::fork();
  if (pid == -1)
    return ProcessStatus::error("fork(2) failed");

  if (!pid) {
    LIBC_IMPL::close(pipe_fds[0]);
#if defined(__linux__) && defined(PR_SET_DUMPABLE)
    LIBC_IMPL::prctl(PR_SET_DUMPABLE, 0);
#endif
    // The test may run under a runtime, such as a sanitizer, that installed
    // its own handlers for fatal signals. Such a handler can turn the signal
    // into a normal exit (e.g. ASan with handle_sigill=1 reports the SIGILL and
    // then calls _exit()), which hides how the child actually died. Restore the
    // default dispositions so that the child dies the same way it would in a
    // plain process. Sanitizers can't be used in full build mode, but we do
    // this there too, so that handlers installed by the test itself are
    // treated the same way in both modes.
    constexpr int FATAL_SIGNALS[] = {SIGABRT, SIGBUS,  SIGFPE,
                                     SIGILL,  SIGSEGV, SIGTRAP};
    for (int sig : FATAL_SIGNALS)
      LIBC_IMPL::signal(sig, SIG_DFL);
    func();
    LIBC_IMPL::exit(0);
  }
  LIBC_IMPL::close(pipe_fds[1]);
  cpp::scope_exit cleanup_pipe([&] { LIBC_IMPL::close(pipe_fds[0]); });

  pollfd poll_fd{pipe_fds[0], POLLIN, 0};
  // No events requested so this call will only return after the timeout or if
  // the pipes peer was closed, signaling the process exited.
  if (LIBC_IMPL::poll(&poll_fd, 1, timeout_ms) == -1)
    return ProcessStatus::error("poll(2) failed");

  // If the pipe wasn't closed by the child yet then timeout has expired.
  if (!(poll_fd.revents & POLLHUP)) {
    LIBC_IMPL::kill(pid, SIGKILL);
    return ProcessStatus::timed_out_ps();
  }

  int wstatus = 0;
  // Wait on the pid of the subprocess here so it gets collected by the system
  // and doesn't turn into a zombie.
  pid_t status = LIBC_IMPL::waitpid(pid, &wstatus, 0);
  if (status == -1) {
    return ProcessStatus::error("waitpid(2) failed");
  }
  LIBC_ASSERT(status == pid);
  return {wstatus};
}

const char *signal_as_string(int signum) {
  return LIBC_IMPL::strsignal(signum);
}

} // namespace testutils
} // namespace LIBC_NAMESPACE_DECL
