// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#define _WITH_DPRINTF
#include "src/main/cpp/blaze_util_platform.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>  // PATH_MAX
#include <poll.h>
#include <pwd.h>
#include <signal.h>
#include <spawn.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstdlib>
#include <fstream>
#include <iterator>
#include <set>
#include <string>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/startup_options.h"
#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/md5.h"
#include "src/main/cpp/util/numbers.h"
#include "src/main/cpp/util/path.h"
#include "src/main/cpp/util/path_platform.h"
#include "src/main/cpp/util/strings.h"

namespace blaze {

using blaze_util::GetLastErrorString;

using std::set;
using std::string;
using std::vector;

namespace embedded_binaries {

class PosixDumper : public Dumper {
 public:
  static PosixDumper* Create(string* error);
  ~PosixDumper() { Finish(nullptr); }
  void Dump(const void* data, const size_t size, const string& path) override;
  bool Finish(string* error) override;

 private:
  PosixDumper() : was_error_(false) {}

  set<string> dir_cache_;
  string error_msg_;
  bool was_error_;
};

Dumper* Create(string* error) { return PosixDumper::Create(error); }

PosixDumper* PosixDumper::Create(string* error) { return new PosixDumper(); }

void PosixDumper::Dump(const void* data, const size_t size,
                       const string& path) {
  if (was_error_) {
    return;
  }

  string dirname = blaze_util::Dirname(path);
  // Performance optimization: memoize the paths we already created a
  // directory for, to spare a stat in attempting to recreate an already
  // existing directory.
  if (dir_cache_.insert(dirname).second) {
    if (!blaze_util::MakeDirectories(dirname, 0777)) {
      was_error_ = true;
      string msg = GetLastErrorString();
      error_msg_ = string("couldn't create '") + path + "': " + msg;
    }
  }

  if (was_error_) {
    return;
  }

  if (!blaze_util::WriteFile(data, size, path, 0755)) {
    was_error_ = true;
    string msg = GetLastErrorString();
    error_msg_ = string("Failed to write zipped file '") + path + "': " + msg;
  }
}

bool PosixDumper::Finish(string* error) {
  if (was_error_ && error) {
    *error = error_msg_;
  }
  return !was_error_;
}

}  // namespace embedded_binaries

SignalHandler SignalHandler::INSTANCE;

// The number of the last received signal that should cause the client
// to shutdown.  This is saved so that the client's WTERMSIG can be set
// correctly.  (Currently only SIGPIPE uses this mechanism.)
static volatile sig_atomic_t signal_handler_received_signal = 0;

// Signal handler.
static void handler(int signum) {
  int saved_errno = errno;

  static volatile sig_atomic_t sigint_count = 0;

  switch (signum) {
    case SIGINT:
      if (++sigint_count >= 3) {
        SigPrintf(
            "\n%s caught third interrupt signal; server killed. (This may be "
            "expensive, see https://bazel.build/advanced/performance/"
            "iteration-speed#avoid-ctrl-c.)\n\n",
            SignalHandler::Get().GetProductName().c_str());
        if (SignalHandler::Get().GetServerProcessInfo()->server_pid_ != -1) {
          KillServerProcess(
              SignalHandler::Get().GetServerProcessInfo()->server_pid_,
              SignalHandler::Get().GetOutputBase());
        }
        _exit(1);
      }
      SigPrintf(
          "\n%s caught interrupt signal; cancelling pending invocation.\n\n",
          SignalHandler::Get().GetProductName().c_str());
      SignalHandler::Get().CancelServer();
      break;
    case SIGTERM:
      SigPrintf(
          "\n%s caught terminate signal; cancelling pending invocation.\n\n",
          SignalHandler::Get().GetProductName().c_str());
      SignalHandler::Get().CancelServer();
      break;
    case SIGPIPE:
      signal_handler_received_signal = SIGPIPE;
      break;
    case SIGQUIT:
      SigPrintf("\nSending SIGQUIT to JVM process %d (see %s).\n\n",
                SignalHandler::Get().GetServerProcessInfo()->server_pid_,
                SignalHandler::Get()
                    .GetServerProcessInfo()
                    ->jvm_log_file_.AsNativePath()
                    .c_str());
      kill(SignalHandler::Get().GetServerProcessInfo()->server_pid_, SIGQUIT);
      break;
  }

  errno = saved_errno;
}

void SignalHandler::Install(const string& product_name,
                            const blaze_util::Path& output_base,
                            const ServerProcessInfo* server_process_info,
                            SignalHandler::Callback cancel_server) {
  product_name_ = product_name;
  output_base_ = output_base;
  server_process_info_ = server_process_info;
  cancel_server_ = cancel_server;

  // Unblock all signals.
  sigset_t sigset;
  sigemptyset(&sigset);
  sigprocmask(SIG_SETMASK, &sigset, nullptr);

  // SIGWINCH is reserved for Bazel server internal use and cannot be passed to
  // it. The JVM is not attached to a terminal, making a signal insufficient to
  // react to window size change event anyway.
  signal(SIGINT, handler);
  signal(SIGTERM, handler);
  signal(SIGPIPE, handler);
  signal(SIGQUIT, handler);
}

ATTRIBUTE_NORETURN void SignalHandler::PropagateSignalOrExit(int exit_code) {
  if (signal_handler_received_signal) {
    // Kill ourselves with the same signal, so that callers see the
    // right WTERMSIG value.
    signal(signal_handler_received_signal, SIG_DFL);
    raise(signal_handler_received_signal);
    exit(1);  // (in case raise didn't kill us for some reason)
  } else {
    exit(exit_code);
  }
}

string GetProcessIdAsString() {
  return blaze_util::ToString(getpid());
}

string GetHomeDir() { return GetPathEnv("HOME"); }

string GetJavaBinaryUnderJavabase() { return "bin/java"; }

string Which(const string& executable) {
  const string path = GetPathEnv("PATH");
  if (path.empty()) {
    return "";
  }

  const vector<string> pieces = blaze_util::Split(path, ':');
  for (string piece : pieces) {
    if (piece.empty()) {
      piece = ".";
    }

    struct stat file_stat;
    const string candidate = blaze_util::JoinPath(piece, executable);
    if (access(candidate.c_str(), X_OK) == 0 &&
        stat(candidate.c_str(), &file_stat) == 0 &&
        S_ISREG(file_stat.st_mode)) {
      return candidate;
    }
  }
  return "";
}

// Converter of C++ data structures to a C-style array of strings.
//
// The primary consumer of this class is the execv family of functions
// (including posix_spawn) which require mutable arrays as their inputs even
// if they do not modify them.
class CharPP {
 public:
  // Constructs a new CharPP from a list of arguments.
  explicit CharPP(const vector<string>& args) {
    charpp_ = static_cast<char**>(malloc(sizeof(char*) * (args.size() + 1)));
    size_t i = 0;
    for (; i < args.size(); i++) {
      charpp_[i] = strdup(args[i].c_str());
    }
    charpp_[i] = nullptr;
  }

  // Constructs a new CharPP from a list of environment variables.
  explicit CharPP(const std::map<string, EnvVarValue>& env) {
    charpp_ = static_cast<char**>(malloc(sizeof(char*) * (env.size() + 1)));
    size_t i = 0;
    for (const auto& iter : env) {
      const string& var = iter.first;
      const EnvVarValue& value = iter.second;

      switch (value.action) {
        case SET:
          charpp_[i] = strdup((var + "=" + value.value).c_str());
          i++;
          break;

        case UNSET:
          break;

        default:
          assert(false);
      }
    }
    charpp_[i] = nullptr;
  }

  // Deletes all memory held by the CharPP.
  ~CharPP() {
    for (char** ptr = charpp_; *ptr != nullptr; ptr++) {
      free(*ptr);
    }
    free(charpp_);
  }

  // Obtains the raw pointer to the array of strings.
  char** get() {
    return charpp_;
  }

  // Prevent copies as we manually manage memory.
  CharPP(const CharPP&) = delete;
  CharPP& operator=(const CharPP&) = delete;

 private:
  char** charpp_;
};

ATTRIBUTE_NORETURN static void ExecuteProgram(
    const blaze_util::Path& exe, const vector<string>& args_vector) {
  BAZEL_LOG(INFO) << "Invoking binary " << exe.AsPrintablePath() << " in "
                  << blaze_util::GetCwd();

  // TODO(jmmv): This execution does not respect any settings we might apply
  // to the server process with ConfigureDaemonProcess when executed in the
  // background as a daemon.  Because we use that function to lower the
  // priority of Bazel on macOS from a QoS perspective, this could have
  // adverse scheduling effects on any tools invoked via ExecuteProgram.
  CharPP argv(args_vector);
  execv(exe.AsNativePath().c_str(), argv.get());
  string err = GetLastErrorString();
  BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
      << "execv of '" << exe.AsPrintablePath() << "' failed: " << err;
  // TODO(jmmv): Mark BAZEL_DIE as ATTRIBUTE_NORETURN so that the following
  // code is not necessary.
  std::abort();  // Not reachable.
}

void ExecuteServerJvm(const blaze_util::Path& exe,
                      const std::vector<string>& server_jvm_args) {
  ExecuteProgram(exe, server_jvm_args);
}

void ExecuteRunRequest(const blaze_util::Path& exe,
                       const std::vector<string>& run_request_args) {
  ExecuteProgram(exe, run_request_args);
}

const char kListSeparator = ':';

bool SymlinkDirectories(const string& target, const blaze_util::Path& link) {
  return symlink(target.c_str(), link.AsNativePath().c_str()) == 0;
}

// Notifies the client about the death of the server process by keeping a socket
// open in the server. If the server dies for any reason, the socket will be
// closed, which can be detected by the client.
class SocketBlazeServerStartup : public BlazeServerStartup {
 public:
  SocketBlazeServerStartup(int pipe_fd);
  virtual ~SocketBlazeServerStartup();
  virtual bool IsStillAlive();

 private:
  int fd;
};

SocketBlazeServerStartup::SocketBlazeServerStartup(int fd)
    : fd(fd) {
}

SocketBlazeServerStartup::~SocketBlazeServerStartup() {
  close(fd);
}

bool SocketBlazeServerStartup::IsStillAlive() {
  struct pollfd pfd;
  pfd.fd = fd;
  pfd.events = POLLIN;
  int result;
  do {
    result = poll(&pfd, 1, 0);
  } while (result < 0 && errno == EINTR);
  if (result == 0) {
    // Timeout, server is still alive
    return true;
  } else {
    // Whether it's an error or pfd.revents & POLLHUP > 0, we assume child is
    // dead.
    return false;
  }
}

// Sets platform-specific attributes for the creation of the daemon process.
//
// Returns zero on success or -1 on error, in which case errno is set to the
// corresponding error details.
int ConfigureDaemonProcess(posix_spawnattr_t* attrp,
                           const StartupOptions &options);

void WriteSystemSpecificProcessIdentifier(const blaze_util::Path& server_dir,
                                          pid_t server_pid);

int ExecuteDaemon(const blaze_util::Path& exe,
                  const std::vector<string>& args_vector,
                  const std::map<string, EnvVarValue>& env,
                  const blaze_util::Path& daemon_output,
                  const bool daemon_output_append, const string& binaries_dir,
                  const blaze_util::Path& server_dir,
                  const StartupOptions& options,
                  BlazeServerStartup** server_startup) {
  const blaze_util::Path pid_file = server_dir.GetRelative(kServerPidFile);
  const string daemonize = blaze_util::JoinPath(binaries_dir, "daemonize");

  std::vector<string> daemonize_args = {"daemonize", "-l",
                                        daemon_output.AsNativePath(), "-p",
                                        pid_file.AsNativePath()};
  if (daemon_output_append) {
    daemonize_args.push_back("-a");
  }
#ifdef __linux__
  if (!options.cgroup_parent.empty()) {
    daemonize_args.push_back("-c");
    daemonize_args.push_back(options.cgroup_parent);
  }
#endif
  daemonize_args.push_back("--");
  daemonize_args.push_back(exe.AsNativePath());
  std::copy(args_vector.begin(), args_vector.end(),
            std::back_inserter(daemonize_args));

  int fds[2];

  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "socket creation failed: " << GetLastErrorString();
  }

  posix_spawn_file_actions_t file_actions;
  if (posix_spawn_file_actions_init(&file_actions) == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
      << "Failed to create posix_spawn_file_actions: " << GetLastErrorString();
  }
  if (posix_spawn_file_actions_addclose(&file_actions, fds[0]) == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
      << "Failed to modify posix_spawn_file_actions: "<< GetLastErrorString();
  }

  posix_spawnattr_t attrp;
  if (posix_spawnattr_init(&attrp) == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "Failed to create posix_spawnattr: " << GetLastErrorString();
  }
  if (ConfigureDaemonProcess(&attrp, options) == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "Failed to modify posix_spawnattr: " << GetLastErrorString();
  }

  pid_t transient_pid;
  if (posix_spawn(&transient_pid, daemonize.c_str(), &file_actions, &attrp,
                  CharPP(daemonize_args).get(), CharPP(env).get()) == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
      << "Failed to execute JVM via " << daemonize
      << ": " << GetLastErrorString();
  }
  close(fds[1]);

  posix_spawnattr_destroy(&attrp);
  posix_spawn_file_actions_destroy(&file_actions);

  // Wait for daemonize to exit. This guarantees that the pid file exists.
  int status;
  if (waitpid(transient_pid, &status, 0) == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "waitpid failed: " << GetLastErrorString();
  }
  if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "daemonize didn't exit cleanly: " << GetLastErrorString();
  }

  std::ifstream pid_reader(pid_file.AsNativePath());
  if (!pid_reader) {
    string err = GetLastErrorString();
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "Failed to open " << pid_file.AsPrintablePath() << ": " << err;
  }
  pid_t server_pid;
  pid_reader >> server_pid;
  if (pid_reader.fail()) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "Failed to read pid from: " << pid_file.AsPrintablePath();
  }

  WriteSystemSpecificProcessIdentifier(server_dir, server_pid);

  *server_startup = new SocketBlazeServerStartup(fds[0]);
  return server_pid;
}

string GetHashedBaseDir(const string& root, const string& hashable) {
  unsigned char buf[blaze_util::Md5Digest::kDigestLength];
  blaze_util::Md5Digest digest;
  digest.Update(hashable.data(), hashable.size());
  digest.Finish(buf);
  return blaze_util::JoinPath(root, digest.String());
}

void CreateSecureOutputRoot(const blaze_util::Path& path) {
  struct stat fileinfo = {};

  if (!blaze_util::MakeDirectories(path, 0755)) {
    string err = GetLastErrorString();
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "mkdir('" << path.AsPrintablePath() << "'): " << err;
  }

  // The path already exists.
  // Check ownership and mode, and verify that it is a directory.

  if (lstat(path.AsNativePath().c_str(), &fileinfo) < 0) {
    string err = GetLastErrorString();
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "lstat('" << path.AsPrintablePath() << "'): " << err;
  }

  if (fileinfo.st_uid != geteuid()) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "'" << path.AsPrintablePath() << "' is not owned by me";
  }

  if ((fileinfo.st_mode & 022) != 0) {
    int new_mode = fileinfo.st_mode & (~022);
    if (chmod(path.AsNativePath().c_str(), new_mode) < 0) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "'" << path.AsPrintablePath() << "' has mode "
          << (fileinfo.st_mode & 07777) << ", chmod to " << new_mode
          << " failed";
    }
  }

  if (stat(path.AsNativePath().c_str(), &fileinfo) < 0) {
    string err = GetLastErrorString();
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "stat('" << path.AsPrintablePath() << "'): " << err;
  }

  if (!S_ISDIR(fileinfo.st_mode)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "'" << path.AsPrintablePath() << "' is not a directory";
  }

  ExcludePathFromBackup(path);
}

string GetEnv(const string& name) {
  char* result = getenv(name.c_str());
  return result != nullptr ? string(result) : "";
}

string GetPathEnv(const string& name) { return GetEnv(name); }

bool ExistsEnv(const string& name) { return getenv(name.c_str()) != nullptr; }

void SetEnv(const string& name, const string& value) {
  setenv(name.c_str(), value.c_str(), 1);
}

void UnsetEnv(const string& name) {
  unsetenv(name.c_str());
}

bool WarnIfStartedFromDesktop() { return false; }

void SetupStdStreams() {
  // Set non-buffered output mode for stderr/stdout. The server already
  // line-buffers messages where it makes sense, so there's no need to do set
  // line-buffering here. On the other hand the server sometimes sends binary
  // output (when for example a query returns results as proto), in which case
  // we must not perform line buffering on the client side. So turn off
  // buffering here completely.
  setvbuf(stdout, nullptr, _IONBF, 0);
  setvbuf(stderr, nullptr, _IONBF, 0);

  // Ensure we have three open fds.  Otherwise we can end up with
  // bizarre things like stdout going to the lock file, etc.
  if (fcntl(STDIN_FILENO, F_GETFL) == -1) open("/dev/null", O_RDONLY);
  if (fcntl(STDOUT_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
  if (fcntl(STDERR_FILENO, F_GETFL) == -1) open("/dev/null", O_WRONLY);
}

// A signal-safe version of fprintf(stderr, ...).
//
// WARNING: any output from the blaze client may be interleaved
// with output from the blaze server.  In --curses mode,
// the Blaze server often erases the previous line of output.
// So, be sure to end each such message with TWO newlines,
// otherwise it may be erased by the next message from the
// Blaze server.
// Also, it's a good idea to start each message with a newline,
// in case the Blaze server has written a partial line.
void SigPrintf(const char *format, ...) {
  char buf[1024];
  va_list ap;
  va_start(ap, format);
  int r = vsnprintf(buf, sizeof buf, format, ap);
  va_end(ap);
  if (write(STDERR_FILENO, buf, r) <= 0) {
    // We don't care, just placate the compiler.
  }
}

static int setlk(int fd, struct flock *lock) {
#ifdef __linux__
// If we're building with glibc <2.20, or another libc which predates
// OFD locks, define the constant ourselves.  This assumes that the libc
// and kernel definitions for struct flock are identical.
#ifndef F_OFD_SETLK
#define F_OFD_SETLK 37
#endif
#endif
#ifdef F_OFD_SETLK
  // Prefer OFD locks if available.  POSIX locks can be lost "accidentally"
  // due to any close() on the lock file, and are not reliably preserved
  // across execve() on Linux, which we need for --batch mode.
  if (fcntl(fd, F_OFD_SETLK, lock) == 0) return 0;
  if (errno != EINVAL) {
    if (errno != EACCES && errno != EAGAIN) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "unexpected result from F_OFD_SETLK: " << GetLastErrorString();
    }
    return -1;
  }
  // F_OFD_SETLK was added in Linux 3.15.  Older kernels return EINVAL.
  // Fall back to F_SETLK in that case.
#endif
  if (fcntl(fd, F_SETLK, lock) == 0) return 0;
  if (errno != EACCES && errno != EAGAIN) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "unexpected result from F_SETLK: " << GetLastErrorString();
  }
  return -1;
}

uint64_t AcquireLock(const blaze_util::Path& output_base, bool batch_mode,
                     bool block, BlazeLock* blaze_lock) {
  blaze_util::Path lockfile = output_base.GetRelative("lock");
  int lockfd = open(lockfile.AsNativePath().c_str(), O_CREAT | O_RDWR, 0644);

  if (lockfd < 0) {
    string err = GetLastErrorString();
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "cannot open lockfile '" << lockfile.AsPrintablePath()
        << "' for writing: " << err;
  }

  // Keep server from inheriting a useless fd if we are not in batch mode
  if (!batch_mode) {
    string err = GetLastErrorString();
    if (fcntl(lockfd, F_SETFD, FD_CLOEXEC) == -1) {
      BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
          << "fcntl(F_SETFD) failed for lockfile: " << err;
    }
  }

  struct flock lock = {};
  lock.l_type = F_WRLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = 0;
  // This doesn't really matter now, but allows us to subdivide the lock
  // later if that becomes meaningful.  (Ranges beyond EOF can be locked.)
  lock.l_len = 4096;

  // Take the exclusive server lock.  If we fail, we busy-wait until the lock
  // becomes available.
  //
  // We used to rely on fcntl(F_SETLKW) to lazy-wait for the lock to become
  // available, which is theoretically fine, but doing so prevents us from
  // determining if the PID of the server holding the lock has changed under the
  // hood.  There have been multiple bug reports where users (especially macOS
  // ones) mention that the Blaze invocation hangs on a non-existent PID.  This
  // should help troubleshoot those scenarios in case there really is a bug
  // somewhere.
  bool multiple_attempts = false;
  string owner;
  const uint64_t start_time = GetMillisecondsMonotonic();
  while (setlk(lockfd, &lock) == -1) {
    string buffer(4096, 0);
    ssize_t r = pread(lockfd, &buffer[0], buffer.size(), 0);
    if (r < 0) {
      BAZEL_LOG(WARNING) << "pread() lock file: " << strerror(errno);
      r = 0;
    }
    buffer.resize(r);
    if (owner != buffer) {
      // Each time we learn a new lock owner, print it out.
      owner = buffer;
      BAZEL_LOG(USER) << "Another command holds the client lock: \n" << owner;
      if (block) {
        BAZEL_LOG(USER) << "Waiting for it to complete...";
        fflush(stderr);
      }
    }

    if (!block) {
      BAZEL_DIE(blaze_exit_code::LOCK_HELD_NOBLOCK_FOR_LOCK)
          << "Exiting because the lock is held and --noblock_for_lock was "
             "given.";
    }

    TrySleep(500);
    multiple_attempts = true;
  }
  const uint64_t end_time = GetMillisecondsMonotonic();

  // If we took the lock on the first try, force the reported wait time to 0 to
  // avoid unnecessary noise in the logs.  In this metric, we are only
  // interested in knowing how long it took for other commands to complete, not
  // how fast acquiring a lock is.
  const uint64_t wait_time = !multiple_attempts ? 0 : end_time - start_time;

  // Identify ourselves in the lockfile.
  // The contents are printed for human consumption when another client
  // fails to take the lock, but not parsed otherwise.
  (void) ftruncate(lockfd, 0);
  lseek(lockfd, 0, SEEK_SET);
  // Arguably we should ensure this fits in the 4KB we lock.  In practice no one
  // will have a cwd long enough to overflow that, and nothing currently uses
  // the rest of the lock file anyway.
  dprintf(lockfd, "pid=%d\nowner=client\n", getpid());
  string cwd = blaze_util::GetCwd();
  dprintf(lockfd, "cwd=%s\n", cwd.c_str());
  if (const char *tty = ttyname(STDIN_FILENO)) {  // NOLINT (single-threaded)
    dprintf(lockfd, "tty=%s\n", tty);
  }
  blaze_lock->lockfd = lockfd;
  return wait_time;
}

void ReleaseLock(BlazeLock* blaze_lock) {
  close(blaze_lock->lockfd);
}

bool KillServerProcess(int pid, const blaze_util::Path& output_base) {
  // Kill the process and make sure it's dead before proceeding.
  errno = 0;
  if (killpg(pid, SIGKILL) == -1) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "Attempted to kill stale server process (pid=" << pid
        << ") using SIGKILL: " << GetLastErrorString();
  }
  if (!AwaitServerProcessTermination(pid, output_base,
                                     kPostKillGracePeriodSeconds)) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "Attempted to kill stale server process (pid=" << pid
        << ") using SIGKILL, but it did not die in a timely fashion.";
  }
  return true;
}

void TrySleep(unsigned int milliseconds) {
  time_t seconds_part = (time_t)(milliseconds / 1000);
  long nanoseconds_part = ((long)(milliseconds % 1000)) * 1000 * 1000;
  struct timespec sleeptime = {seconds_part, nanoseconds_part};
  nanosleep(&sleeptime, nullptr);
}

string GetUserName() {
  string user = GetEnv("USER");
  if (!user.empty()) {
    return user;
  }
  errno = 0;
  passwd *pwent = getpwuid(getuid());  // NOLINT (single-threaded)
  if (pwent == nullptr || pwent->pw_name == nullptr) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "$USER is not set, and unable to look up name of current user: "
        << GetLastErrorString();
  }
  return pwent->pw_name;
}

bool IsEmacsTerminal() {
  string emacs = GetEnv("EMACS");
  // GNU Emacs <25.1 (and ~all non-GNU emacsen) set EMACS=t, but >=25.1 doesn't
  // do that and instead sets INSIDE_EMACS=<stuff> (where <stuff> can look like
  // e.g. "25.1.1,comint").  So we check both variables for maximum
  // compatibility.
  return emacs == "t" || ExistsEnv("INSIDE_EMACS");
}

bool IsStandardTerminal() {
  string term = GetEnv("TERM");
  bool isEmacs = IsEmacsTerminal();

  // Emacs 22+ terminal emulation uses 'eterm-color' as its terminfo name and,
  // more importantly, supports color in terminals.
  // see https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS.22#L331-L333
  if (isEmacs && term == "eterm-color") {
    return true;
  }
  if (term.empty() || term == "dumb" || term == "emacs" ||
      term == "xterm-mono" || term == "symbolics" || term == "9term" ||
      isEmacs) {
    return false;
  }
  return isatty(STDOUT_FILENO) && isatty(STDERR_FILENO);
}

int GetTerminalColumns() {
  struct winsize ws;
  if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
    return ws.ws_col;
  }
  string columns_env = GetEnv("COLUMNS");
  if (!columns_env.empty()) {
    char* endptr;
    int columns = blaze_util::strto32(columns_env.c_str(), &endptr, 10);
    if (*endptr == '\0') {  // $COLUMNS is a valid number
      return columns;
    }
  }
  return 80;  // default if not a terminal.
}

// Raises a resource limit to the maximum allowed value.
//
// This function raises the limit of the resource given in "resource" from its
// soft limit to its hard limit. If the hard limit is unlimited and
// allow_infinity is false, uses the kernel-level limit because setting the
// soft limit to unlimited may not work.
//
// Note that this is a best-effort operation. Any failure during this process
// will result in a warning but execution will continue.
static bool UnlimitResource(const int resource, const bool allow_infinity) {
  struct rlimit rl;
  if (getrlimit(resource, &rl) == -1) {
    BAZEL_LOG(WARNING) << "failed to get resource limit " << resource << ": "
                       << strerror(errno);
    return false;
  }

  if (rl.rlim_cur == rl.rlim_max) {
    // Nothing to do. Return early to prevent triggering any warnings caused by
    // the code below. This way, we will only show warnings the first time the
    // Blaze server is started and not on each command invocation.
    return true;
  }

  const rlim_t explicit_limit = GetExplicitSystemLimit(resource);
  if (explicit_limit <= 0) {
    // If not implemented (-1) or on an error (0), do nothing and try to
    // increase the soft limit to the hard one. This might fail, but it's good
    // to try anyway.
    rl.rlim_cur = rl.rlim_max;
  } else {
    if ((rl.rlim_max == RLIM_INFINITY && !allow_infinity) ||
       rl.rlim_max > explicit_limit) {
      rl.rlim_cur = explicit_limit;
    } else {
      rl.rlim_cur = rl.rlim_max;
    }
  }

  if (setrlimit(resource, &rl) == -1) {
    BAZEL_LOG(WARNING) << "failed to raise resource limit " << resource
                       << " to " << static_cast<intmax_t>(rl.rlim_cur) << ": "
                       << strerror(errno);
    return false;
  }

  return true;
}

bool UnlimitResources() {
  bool success = true;
  success &= UnlimitResource(RLIMIT_NOFILE, false);
  success &= UnlimitResource(RLIMIT_NPROC, false);
  return success;
}

bool UnlimitCoredumps() {
  return UnlimitResource(RLIMIT_CORE, true);
}

void EnsurePythonPathOption(vector<string>* options) {
  // do nothing.
}

}   // namespace blaze.
