// Copyright 2011 The Goma 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 "spawner_posix.h"

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <spawn.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <vector>
#include <sstream>

#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "file_helper.h"
#include "fileflag.h"
#include "glog/logging.h"
#include "glog/stl_logging.h"
#include "mypath.h"
#include "path.h"
#include "platform_thread.h"

namespace {

static const int kInvalidProcessStatus = -256;

struct SubprocExit {
  SubprocExit() {
    // Since we send the structure, we should initialize not only variables but
    // also alighment paddings.  Otherwise, memory sanitizer would fail.
    memset(this, 0, sizeof(*this));
    status = kInvalidProcessStatus;
  }
  int lineno;
  int last_errno;

  // status of spawned process.
  int status;
  struct rusage ru;
};

void __attribute__((__noreturn__)) SubprocExitReport(
    int fd, const SubprocExit& se, int exit_value) {
  if (write(fd, &se, sizeof(se)) != sizeof(se)) {
    close(fd);
    _exit(exit_value ? exit_value : 1);
  }
  _exit(exit_value);
}

}  // namespace

namespace devtools_goma {

SpawnerPosix::SpawnerPosix()
    : monitor_pid_(Spawner::kInvalidPid),
      prog_pid_(Spawner::kInvalidPid),
      is_signaled_(false),
      sent_sig_(0),
      status_(kInvalidProcessStatus),
      process_mem_kb_(-1),
      signal_(0) {}

SpawnerPosix::~SpawnerPosix() {
  if (!console_out_file_.empty())
    remove(console_out_file_.c_str());
}

const int Spawner::kInvalidPid = -1;

int SpawnerPosix::Run(const string& cmd, const std::vector<string>& args,
                      const std::vector<string>& envs, const string& cwd) {
  if (console_output_) {
    std::ostringstream filenamebuf;
    filenamebuf << "goma_tmp." << rand() << "."
                << absl::ToUnixMillis(absl::Now()) << ".out";
    console_out_file_ = file::JoinPath(GetGomaTmpDir(), filenamebuf.str());
    stdout_filename_ = console_out_file_;
  }

  const bool need_redirect =
      !(stdin_filename_.empty() &&
        stdout_filename_.empty() &&
        stderr_filename_.empty()) || detach_;
  ScopedFd stdin_fd;
  ScopedFd stdout_fd;
  ScopedFd stderr_fd;
  if (need_redirect) {
    ScopedFd devnullfd(ScopedFd::OpenNull());
    stdin_fd.reset(dup(devnullfd.fd()));
    if (!stdin_filename_.empty())
      stdin_fd.reset(ScopedFd::OpenForRead(stdin_filename_));
    stdout_fd.reset(dup(devnullfd.fd()));
    if (!stdout_filename_.empty()) {
      stdout_fd.reset(ScopedFd::Create(stdout_filename_, 0600));
    }
    stderr_fd.reset(dup(devnullfd.fd()));
    if (!stderr_filename_.empty()) {
      stderr_fd.reset(ScopedFd::Create(stderr_filename_, 0600));
    } else if (!stdout_filename_.empty() &&
               console_output_option_ == MERGE_STDOUT_STDERR) {
      // stdout is not empty, but stderr is empty.
      stderr_fd.reset(dup(stdout_fd.fd()));
    }
  }

  // Pipe for passing SubprocExit information.
  // pipe(7) says write(2) of less than PIPE_BUF bytes must be atomic.
  int pipe_fd[2];
  PCHECK(pipe(pipe_fd) == 0);
  exit_fd_.reset(pipe_fd[0]);
  ScopedFd child_exit_fd(pipe_fd[1]);
  // Make another pipe. Use this for report pid.
  PCHECK(pipe(pipe_fd) == 0);
  ScopedFd exit_pid_fd(pipe_fd[0]);
  ScopedFd child_pid_fd(pipe_fd[1]);

  // We can't use posix_spawn, because we'd like to control
  // current directory of each subprocess.
  const char* dir = cwd.c_str();
  const char* prog = cmd.c_str();
  std::vector<const char*> argvp;
  for (const auto& arg : args)
    argvp.push_back(arg.c_str());
  argvp.push_back(nullptr);
  std::vector<const char*> envp;
  for (const auto& env : envs)
    envp.push_back(env.c_str());
  envp.push_back(nullptr);

  // SubprocessImpl will try to send SIGINT or SIGTERM to kill the subprocess
  // but ignore them in this process. This process will wait for child process
  // termination (child process will be killed by SIGINT or SIGTERM to
  // the process group).
  // Also block SIGCHLD until it resets SIGCHLD in child process.
  sigset_t sigset;
  sigemptyset(&sigset);
  sigaddset(&sigset, SIGINT);
  sigaddset(&sigset, SIGTERM);
  sigaddset(&sigset, SIGCHLD);
  PCHECK(sigprocmask(SIG_BLOCK, &sigset, nullptr) == 0);
  pid_t pid = fork();
  if (pid < 0) {
    PLOG(ERROR) << "fork failed. pid=" << pid;
    monitor_pid_ = Spawner::kInvalidPid;
    return Spawner::kInvalidPid;
  }
  if (pid == 0) {
    // child process.
    // You can use only async-signal safe functions here.
    //
    SubprocExit se;

    if (stdin_fd.valid() && dup2(stdin_fd.fd(), STDIN_FILENO) < 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    if (stdout_fd.valid() && dup2(stdout_fd.fd(), STDOUT_FILENO) < 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    if (stderr_fd.valid() && dup2(stderr_fd.fd(), STDERR_FILENO) < 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    for (int i = STDERR_FILENO + 1; i < 256; ++i) {
      if (i == child_exit_fd.fd() || i == child_pid_fd.fd()) {
        continue;
      }
      close(i);
    }

    if (detach_) {
      // Create own session.
      if (setsid() < 0) {
        se.lineno = __LINE__ -1;
        se.last_errno = errno;
        SubprocExitReport(child_exit_fd.fd(), se, 1);
      }
      pid_t pid;
      if ((pid = fork())) {
        if (pid < 0) {
          se.lineno = __LINE__ - 2;
          se.last_errno = errno;
          SubprocExitReport(child_exit_fd.fd(), se, 1);
        }
        exit(0);
      }
    }

    // Reset SIGCHLD handler.  we'll get exit status of prog_pid
    // by blocking waitpid() later.
    struct sigaction sa;
    memset(&sa, 0, sizeof sa);
    sa.sa_handler = SIG_DFL;
    if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }

    sigset_t unblock_sigset;
    sigemptyset(&unblock_sigset);
    sigaddset(&unblock_sigset, SIGCHLD);
    sigaddset(&unblock_sigset, SIGINT);
    sigaddset(&unblock_sigset, SIGTERM);
    if (sigprocmask(SIG_UNBLOCK, &unblock_sigset, nullptr) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }

    if (chdir(dir) < 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }

    posix_spawnattr_t spawnattr;
    posix_spawnattr_init(&spawnattr);

    // Reset SIGINT and SIGTERM signal handlers in child process.
    if (posix_spawnattr_setflags(&spawnattr, POSIX_SPAWN_SETSIGDEF) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    sigset_t default_sigset;
    sigemptyset(&default_sigset);
    sigaddset(&default_sigset, SIGINT);
    sigaddset(&default_sigset, SIGTERM);
    if (posix_spawnattr_setsigdefault(&spawnattr, &default_sigset) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }

    // Don't mask any signals in child process.
    if (posix_spawnattr_setflags(&spawnattr, POSIX_SPAWN_SETSIGMASK) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    sigset_t sigmask;
    sigemptyset(&sigmask);
    if (posix_spawnattr_setsigmask(&spawnattr, &sigmask) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    if (umask_ >= 0) {
      umask(umask_);
    }

    // Let spawned process has its own pid/pgid.
    if (posix_spawnattr_setflags(&spawnattr, POSIX_SPAWN_SETPGROUP) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }

    pid_t prog_pid = Spawner::kInvalidPid;
    // TODO: use POSIX_SPAWN_USEVFORK (_GNU_SOURCE).
    if (posix_spawn(
            &prog_pid, prog, nullptr, &spawnattr,
            const_cast<char**>(&argvp[0]), const_cast<char**>(&envp[0])) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    // report prog_pid to parent.
    if (write(child_pid_fd.fd(), &prog_pid, sizeof(prog_pid)) !=
        sizeof(prog_pid)) {
      se.lineno = __LINE__ - 2;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }

    while (waitpid(prog_pid, &se.status, 0) == -1) {
      if (errno != EINTR) break;
    }
    if (getrusage(RUSAGE_CHILDREN, &se.ru) != 0) {
      se.lineno = __LINE__ - 1;
      se.last_errno = errno;
      SubprocExitReport(child_exit_fd.fd(), se, 1);
    }
    int exit_status = -1;

    // The monitor process is considered as finishing successfully
    // (exit_status = 0) regardless of spawned process exit status.
    if (WIFSIGNALED(se.status) || WIFEXITED(se.status)) {
      exit_status = 0;
    }
    SubprocExitReport(child_exit_fd.fd(), se, exit_status);
  }

  // close writers (otherwise read(2) will be blocked)
  child_exit_fd.Close();
  child_pid_fd.Close();

  monitor_pid_ = pid;
  int r = read(exit_pid_fd.fd(), &prog_pid_, sizeof(prog_pid_));
  if (r != sizeof(prog_pid_)) {
    PLOG(ERROR) << "failed to get prog_pid for monitor_pid=" << monitor_pid_;
    prog_pid_ = Spawner::kInvalidPid;
  }
  PCHECK(sigprocmask(SIG_UNBLOCK, &sigset, nullptr) == 0);

  return monitor_pid_;
}

Spawner::ProcessStatus SpawnerPosix::Kill() {
  int sig = SIGINT;
  CHECK_NE(monitor_pid_, Spawner::kInvalidPid)
      << "Kill should not be called before the process has started.";

  if (!is_signaled_) {
    is_signaled_ = true;  // try to kill in Wait()
  } else {
    sig = SIGTERM;
  }

  ProcessStatus status = status_ == kInvalidProcessStatus
                             ? ProcessStatus::RUNNING
                             : ProcessStatus::EXITED;
  sent_sig_ = sig;
  sig_timer_.Start();

  if (status == ProcessStatus::RUNNING && prog_pid_ != Spawner::kInvalidPid) {
    if (kill(-prog_pid_, sig) != 0) {
      PLOG(WARNING) << " kill "
                    << " prog_pgrp=" << prog_pid_;
      if (kill(prog_pid_, sig) != 0) {
        PLOG(WARNING) << " kill "
                      << " prog_pid=" << prog_pid_;
      }
    }
  }
  return status;
}

SpawnerPosix::ProcessStatus SpawnerPosix::Wait(WaitPolicy wait_policy) {
  if (monitor_pid_ != Spawner::kInvalidPid) {
    const bool need_kill = (wait_policy == NEED_KILL);
    const int waitpid_options = (wait_policy == WAIT_INFINITE) ? 0 : WNOHANG;
    int r;
    int status = -1;
    while ((r = waitpid(monitor_pid_, &status, waitpid_options)) == -1) {
      if (errno == EINTR) {
        // Retry after 10 milliseconds wait.
        absl::SleepFor(absl::Milliseconds(10));
        continue;
      }
      PLOG(FATAL) << "waitpid failed, monitor process id=" << monitor_pid_
                  << " waitpid_options=" << waitpid_options;
    }

    DCHECK_NE(r, -1);
    if (r == 0) {
      // monitor still running
      if (!need_kill) {
        CHECK_EQ(wait_policy, NO_HANG)
            << "process is alive in not NO_HANG policy."
            << " monitor_pid=" << monitor_pid_ << " prog_pid=" << prog_pid_;
        return ProcessStatus::RUNNING;
      }
      CHECK_EQ(wait_policy, NEED_KILL)
          << "try to kill process in other than NEED_KILL policy."
          << " monitor_pid=" << monitor_pid_ << " prog_pid=" << prog_pid_;

      CHECK_EQ(ProcessStatus::RUNNING, Kill())
          << "Should not call Kill when monitor process is not running.";

      while ((r = waitpid(monitor_pid_, &status, 0)) == -1) {
        if (errno == EINTR) {
          // Retry after 10 milliseconds wait.
          absl::SleepFor(absl::Milliseconds(10));
          continue;
        }
        PLOG(FATAL) << "waitpid failed, monitor process id=" << monitor_pid_
                    << " waitpid_options=" << waitpid_options;
      }

      CHECK_EQ(r, monitor_pid_)
          << "unexpected waitpid returns, r=" << r << " status=" << status
          << " monitor_pid=" << monitor_pid_ << " prog_pid=" << prog_pid_;

      CHECK(WIFEXITED(status) || WIFSIGNALED(status))
          << "unexpected state change, r=" << r << " status=" << status
          << " monitor_pid=" << monitor_pid_ << " prog_pid=" << prog_pid_;
    } else if (r == monitor_pid_) {
      // monitor changed the status.
      CHECK(WIFEXITED(status))
          << "unexpected waitpid status:"
          << " status=" << status << " monitor_pid=" << monitor_pid_
          << " prog_pid=" << prog_pid_;

      if (WEXITSTATUS(status) != 0) {
        LOG(ERROR) << "monitor process died with non-zero exit status,"
                   << " exit_status=" << WEXITSTATUS(status)
                   << " status=" << status;
      }
    } else {
      LOG(FATAL) << "Unexpected waitpid is returned: r=" << r
                 << " status=" << status << " wait_policy=" << wait_policy
                 << " monitor_pid=" << monitor_pid_
                 << " prog_pid=" << prog_pid_;
    }
  }

  string sig_source;
  if (exit_fd_.valid()) {
    SubprocExit se;
    int r = read(exit_fd_.fd(), &se, sizeof(se));
    if (r == sizeof(se)) {
      if (se.lineno > 0 || se.last_errno > 0) {
        LOG(WARNING) << "subproc abort: monitor_pid=" << monitor_pid_ << " at "
                     << __FILE__ << ":" << se.lineno
                     << " err=" << strerror(se.last_errno) << "["
                     << se.last_errno << "]";
      }
      process_mem_kb_ = se.ru.ru_maxrss;
      if (se.status != kInvalidProcessStatus) {
        if (WIFSIGNALED(se.status)) {
          signal_ = WTERMSIG(se.status);
          sig_source = "wtermsig";
          status_ = 1;
        } else if (WIFEXITED(se.status)) {
          sig_source = "subproc_exit";
          status_ = WEXITSTATUS(se.status);
        } else {
          LOG(FATAL) << "Unexpected status from subproc."
                     << " monitor_pid=" << monitor_pid_
                     << " prog_pid=" << prog_pid_ << " status=" << se.status;
        }
      }

      if (signal_ != 0 && signal_ != sent_sig_) {
        LOG(ERROR) << "subproc was terminated unexpectedly."
                   << " monitor_pid=" << monitor_pid_
                   << " sent_sig=" << sent_sig_ << " prog_pid=" << prog_pid_
                   << " signal=" << signal_ << " status=" << se.status;
      }
    } else {
      sig_source = "exit_fd_read_err";
      PLOG(ERROR) << "read SubprocExit:"
                  << " monitor_pid=" << monitor_pid_ << " ret=" << r;
    }
  } else {
    sig_source = "exit_fd_invalid";
  }
  if (console_output_) {
    DCHECK(!console_out_file_.empty());
    ReadFileToString(console_out_file_, console_output_);
  }
  LOG_IF(INFO, sent_sig_ != 0)
      << "signal=" << sent_sig_ << " sent to monitor_pid=" << monitor_pid_
      << " prog_pid=" << prog_pid_
       << " " << sig_timer_.GetInMilliseconds() << "msec ago,"
      << " terminated by signal=" << signal_ << " from " << sig_source
      << " exit=" << status_;
  monitor_pid_ = Spawner::kInvalidPid;
  return ProcessStatus::EXITED;
}

bool SpawnerPosix::IsChildRunning() const {
  return monitor_pid_ != Spawner::kInvalidPid &&
         status_ == kInvalidProcessStatus;
}

}  // namespace devtools_goma
