// Copyright 2014 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.

#include "src/main/native/unix_jni.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <jni.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>

// Linting disabled for this line because for google code we could use
// absl::Mutex but we cannot yet because Bazel doesn't depend on absl.
#include <mutex>  // NOLINT
#include <string>
#include <vector>

#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/port.h"
#include "src/main/native/latin1_jni_path.h"
#include "src/main/native/macros.h"

#if defined(O_DIRECTORY)
#define PORTABLE_O_DIRECTORY O_DIRECTORY
#else
#define PORTABLE_O_DIRECTORY 0
#endif

namespace blaze_jni {

#define FILE_BASENAME "unix_jni.cc"

struct DIROrError {
  DIR *dir;
  int error;
};

static void PostException(JNIEnv *env, const char *exception_classname,
                          const std::string &message) {
  jclass exception_class = env->FindClass(exception_classname);
  bool success = false;
  if (exception_class != nullptr) {
    success = env->ThrowNew(exception_class, message.c_str()) == 0;
  }
  if (!success) {
    BAZEL_LOG(FATAL) << "Failed to throw Java exception from JNI: "
                     << message.c_str();
  }
}

// See unix_jni.h.
void PostException(JNIEnv *env, int error_number, const std::string& message) {
  // Keep consistent with package-info.html!
  //
  // See /usr/include/asm/errno.h for UNIX error messages.
  // Select the most appropriate Java exception for a given UNIX error number.
  // (Consistent with errors generated by java.io package.)
  const char *exception_classname;
  switch (error_number) {
    case EFAULT:  // Illegal pointer (unlikely; perhaps from or via FUSE?)
      exception_classname = "java/lang/IllegalArgumentException";
      break;
    case ETIMEDOUT:  // Local socket timed out
      exception_classname = "java/net/SocketTimeoutException";
      break;
    case ENOENT:  // No such file or directory
      exception_classname = "java/io/FileNotFoundException";
      break;
    case EACCES:  // Permission denied
      exception_classname =
          "com/google/devtools/build/lib/vfs/FileAccessException";
      break;
    case EINTR:   // Interrupted system call
      exception_classname = "java/io/InterruptedIOException";
      break;
    case ENOMEM:  // Out of memory
      exception_classname = "java/lang/OutOfMemoryError";
      break;
    case ENOSYS:   // Function not implemented
    case ENOTSUP:  // Operation not supported on transport endpoint
                   // (aka EOPNOTSUPP)
      exception_classname = "java/lang/UnsupportedOperationException";
      break;
    case EINVAL:  // Invalid argument
      exception_classname =
          "com/google/devtools/build/lib/unix/InvalidArgumentIOException";
      break;
    case ELOOP:  // Too many symbolic links encountered
      exception_classname =
          "com/google/devtools/build/lib/vfs/FileSymlinkLoopException";
      break;
    case EBADF:         // Bad file number or descriptor already closed.
    case ENAMETOOLONG:  // File name too long
    case ENODATA:    // No data available
#if defined(EMULTIHOP)
    case EMULTIHOP:  // Multihop attempted
#endif
    case EPERM:      // Operation not permitted
    case ENOLINK:    // Link has been severed
    case EIO:        // I/O error
    case EAGAIN:     // Try again
    case EFBIG:      // File too large
    case EPIPE:      // Broken pipe
    case ENOSPC:     // No space left on device
    case EXDEV:      // Cross-device link
    case EROFS:      // Read-only file system
    case EEXIST:     // File exists
    case EMLINK:     // Too many links
    case EISDIR:     // Is a directory
    case ENOTDIR:    // Not a directory
    case ENOTEMPTY:  // Directory not empty
    case EBUSY:      // Device or resource busy
    case ENFILE:     // File table overflow
    case EMFILE:     // Too many open files
    default:
      exception_classname = "java/io/IOException";
  }
  PostException(env, exception_classname,
                message + " (" + ErrorMessage(error_number) + ")");
}

static void PostAssertionError(JNIEnv *env, const std::string& message) {
  PostException(env, "java/lang/AssertionError", message);
}

// "TOSTRING" macro from: https://stackoverflow.com/a/240370
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#define POST_EXCEPTION_FROM_ERRNO(env, error, message)                       \
  PostException(env, error,                                                  \
                std::string("[" FILE_BASENAME ":" TOSTRING(__LINE__) "] ") + \
                    std::string(message))

#define POST_ASSERTION_ERROR(env, message)                              \
  PostAssertionError(                                                   \
      env, std::string("[" FILE_BASENAME ":" TOSTRING(__LINE__) "] ") + \
               std::string(message))

// Throws RuntimeExceptions for IO operations which fail unexpectedly.
// See package-info.html.
// Returns true iff an exception was thrown.
static bool PostRuntimeException(JNIEnv *env, int error_number,
                                 const char *file_path) {
  const char *exception_classname;
  switch (error_number) {
    case EFAULT:   // Illegal pointer--not likely
    case EBADF:    // Bad file number
      exception_classname = "java/lang/IllegalArgumentException";
      break;
    case ENOMEM:   // Out of memory
      exception_classname = "java/lang/OutOfMemoryError";
      break;
    case ENOTSUP:  // Operation not supported on transport endpoint
                   // (aka EOPNOTSUPP)
      exception_classname = "java/lang/UnsupportedOperationException";
      break;
    default:
      exception_classname = nullptr;
  }

  if (exception_classname == nullptr) {
    return false;
  }

  jclass exception_class = env->FindClass(exception_classname);
  if (exception_class != nullptr) {
    std::string message(file_path);
    message += " (";
    message += ErrorMessage(error_number);
    message += ")";
    env->ThrowNew(exception_class, message.c_str());
    return true;
  } else {
    BAZEL_LOG(FATAL) << "Unable to find exception_class: "
                     << exception_classname;
    return false;
  }
}

static JavaVM *GetJavaVM(JNIEnv *env) {
  static JavaVM *java_vm = nullptr;
  static std::mutex java_vm_mtx;
  std::lock_guard<std::mutex> lock(java_vm_mtx);
  if (env != nullptr) {
    JavaVM *env_java_vm;
    jint value = env->GetJavaVM(&env_java_vm);
    if (value != 0) {
      return nullptr;
    }
    if (java_vm == nullptr) {
      java_vm = env_java_vm;
    } else if (java_vm != env_java_vm) {
      return nullptr;
    }
  }
  return java_vm;
}

static void PerformIntegerValueCallback(jobject object, const char *callback,
                                        int value) {
  JavaVM *java_vm = GetJavaVM(nullptr);
  JNIEnv *java_env;
  int status = java_vm->GetEnv((void **)&java_env, JNI_VERSION_1_8);
  bool attach_current_thread = false;
  if (status == JNI_EDETACHED) {
    attach_current_thread = true;
  } else {
    BAZEL_CHECK_EQ(status, JNI_OK);
  }
  if (attach_current_thread) {
    BAZEL_CHECK_EQ(java_vm->AttachCurrentThread((void **)&java_env, nullptr),
                   0);
  }
  jclass clazz = java_env->GetObjectClass(object);
  BAZEL_CHECK_NE(clazz, nullptr);
  jmethodID method_id = java_env->GetMethodID(clazz, callback, "(I)V");
  BAZEL_CHECK_NE(method_id, nullptr);
  java_env->CallVoidMethod(object, method_id, value);

  if (attach_current_thread) {
    BAZEL_CHECK_EQ(java_vm->DetachCurrentThread(), JNI_OK);
  }
}

// TODO(bazel-team): split out all the FileSystem class's native methods
// into a separate source file, fsutils.cc.

extern "C" JNIEXPORT jstring JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_readlink(JNIEnv *env,
                                                     jclass clazz,
                                                     jstring path) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  char target[PATH_MAX] = "";
  jstring r = nullptr;
  if (readlink(path_chars, target, arraysize(target)) == -1) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
  } else {
    r = NewStringLatin1(env, target);
  }
  ReleaseStringLatin1Chars(path_chars);
  return r;
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_chmod(JNIEnv *env,
                                                  jclass clazz,
                                                  jstring path,
                                                  jint mode) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  if (chmod(path_chars, static_cast<int>(mode)) == -1) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
}

static void link_common(JNIEnv *env,
                        jstring oldpath,
                        jstring newpath,
                        int (*link_function)(const char *, const char *)) {
  const char *oldpath_chars = GetStringLatin1Chars(env, oldpath);
  const char *newpath_chars = GetStringLatin1Chars(env, newpath);
  if (link_function(oldpath_chars, newpath_chars) == -1) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, newpath_chars);
  }
  ReleaseStringLatin1Chars(oldpath_chars);
  ReleaseStringLatin1Chars(newpath_chars);
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_link(JNIEnv *env,
                                                 jclass clazz,
                                                 jstring oldpath,
                                                 jstring newpath) {
  link_common(env, oldpath, newpath, ::link);
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_symlink(JNIEnv *env,
                                                    jclass clazz,
                                                    jstring oldpath,
                                                    jstring newpath) {
  link_common(env, oldpath, newpath, ::symlink);
}

namespace {

static jclass makeStaticClass(JNIEnv *env, const char *name) {
  jclass lookup_result = env->FindClass(name);
  BAZEL_CHECK_NE(lookup_result, nullptr);
  return static_cast<jclass>(env->NewGlobalRef(lookup_result));
}

static jmethodID getConstructorID(JNIEnv *env, jclass clazz,
                                  const char *parameters) {
  jmethodID method = env->GetMethodID(clazz, "<init>", parameters);
  BAZEL_CHECK_NE(method, nullptr);
  return method;
}

static jobject NewUnixFileStatus(JNIEnv *env,
                                 const portable_stat_struct &stat_ref) {
  static const jclass file_status_class =
      makeStaticClass(env, "com/google/devtools/build/lib/unix/UnixFileStatus");
  static const jmethodID file_status_class_ctor =
      getConstructorID(env, file_status_class, "(IJJJJ)V");
  return env->NewObject(
      file_status_class, file_status_class_ctor,
      static_cast<jint>(stat_ref.st_mode),
      static_cast<jlong>(StatEpochMilliseconds(stat_ref, STAT_MTIME)),
      static_cast<jlong>(StatEpochMilliseconds(stat_ref, STAT_CTIME)),
      static_cast<jlong>(stat_ref.st_size),
      static_cast<jlong>(stat_ref.st_ino));
}

// RAII class for jstring.
class JStringLatin1Holder {
  const char *const chars;

 public:
  JStringLatin1Holder(JNIEnv *env, jstring string)
      : chars(GetStringLatin1Chars(env, string)) {}

  ~JStringLatin1Holder() { ReleaseStringLatin1Chars(chars); }

  operator const char *() const { return chars; }

  operator std::string() const { return chars; }
};

}  // namespace

namespace {
static jobject StatCommon(JNIEnv *env, jstring path,
                          int (*stat_function)(const char *,
                                               portable_stat_struct *),
                          char error_handling) {
  JStringLatin1Holder path_chars(env, path);
  portable_stat_struct statbuf;
  int r;
  while ((r = stat_function(path_chars, &statbuf)) == -1 && errno == EINTR) { }
  if (r == -1) {
    // Save errno immediately, before we do any other syscalls.
    int saved_errno = errno;

    // Throw a RuntimeException if errno suggests a programming error.
    if (PostRuntimeException(env, saved_errno, path_chars)) {
      return nullptr;
    }

    // Throw an IOException if requested by the error handling mode.
    if (error_handling == 'a' ||
        (error_handling == 'f' && saved_errno != ENOENT &&
         saved_errno != ENOTDIR)) {
      POST_EXCEPTION_FROM_ERRNO(env, saved_errno, path_chars);
      return nullptr;
    }

    // Otherwise, return null.
    return nullptr;
  }

  return NewUnixFileStatus(env, statbuf);
}
}  // namespace

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    stat
 * Signature: (Ljava/lang/String;)Lcom/google/devtools/build/lib/unix/FileStatus;
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_stat(
    JNIEnv *env, jclass clazz, jstring path, jchar error_handling) {
  return StatCommon(env, path, portable_stat, error_handling);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    lstat
 * Signature: (Ljava/lang/String;)Lcom/google/devtools/build/lib/unix/FileStatus;
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_lstat(
    JNIEnv *env, jclass clazz, jstring path, jchar error_handling) {
  return StatCommon(env, path, portable_lstat, error_handling);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    utimensat
 * Signature: (Ljava/lang/String;ZJ)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_utimensat(
    JNIEnv *env, jclass clazz, jstring path, jboolean now, jlong millis) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  // If `now` is true use the current time, otherwise use `millis`.
  // On Linux, if the current user has write permission but isn't the owner of
  // the file, atime and mtime may be simultaneously set to UTIME_NOW, but any
  // other combination is forbidden. For simplicity, always set both.
  int64_t sec = millis / 1000;
  int32_t nsec = (millis % 1000) * 1000000;
  struct timespec times[2] = {
      {sec, now ? UTIME_NOW : nsec},
      {sec, now ? UTIME_NOW : nsec},
  };
  if (::utimensat(AT_FDCWD, path_chars, times, 0) == -1) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    mkdir
 * Signature: (Ljava/lang/String;I)Z
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_mkdir(JNIEnv *env,
                                                  jclass clazz,
                                                  jstring path,
                                                  jint mode) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  jboolean result = true;
  if (::mkdir(path_chars, mode) == -1) {
    // EACCES ENOENT ELOOP
    // ENOSPC ENOTDIR EPERM EROFS     -> IOException
    // EFAULT ENAMETOOLONG            -> RuntimeException
    // ENOMEM                         -> OutOfMemoryError
    // EEXIST                         -> return false
    if (errno == EEXIST) {
      result = false;
    } else {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    }
  }
  ReleaseStringLatin1Chars(path_chars);
  return result;
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    mkdirWritable
 * Signature: (Ljava/lang/String;I)Z
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_mkdirWritable(
    JNIEnv *env, jclass clazz, jstring path) {
  JStringLatin1Holder path_chars(env, path);

  portable_stat_struct statbuf;
  int r;
  do {
    r = portable_lstat(path_chars, &statbuf);
  } while (r != 0 && errno == EINTR);

  if (r != 0) {
    if (errno != ENOENT) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
      return false;
    }
    // Directory does not exist.
    // Use 0777 so that the permissions can be overridden by umask(2).
    if (::mkdir(path_chars, 0777) == -1) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    }
    return true;
  }
  // Path already exists, but might not be a directory.
  if (!S_ISDIR(statbuf.st_mode)) {
    POST_EXCEPTION_FROM_ERRNO(env, ENOTDIR, path_chars);
    return false;
  }
  // Make sure the permissions are correct.
  // Avoid touching permissions for group/other, which may have been overridden
  // by umask(2) when this directory was originally created.
  if ((statbuf.st_mode & S_IRWXU) != S_IRWXU) {
    if (::chmod(path_chars, statbuf.st_mode | S_IRWXU) == -1) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    }
  }
  return false;
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    mkdirs
 * Signature: (Ljava/lang/String;I)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_mkdirs(JNIEnv *env,
                                                                jclass clazz,
                                                                jstring path,
                                                                int mode) {
  char *path_chars = GetStringLatin1Chars(env, path);
  portable_stat_struct statbuf;
  int len;
  char *p;

  // First, check if the directory already exists and early-out.
  if (portable_stat(path_chars, &statbuf) == 0) {
    if (!S_ISDIR(statbuf.st_mode)) {
      // Exists but is not a directory.
      POST_EXCEPTION_FROM_ERRNO(env, ENOTDIR, path_chars);
    }
    goto cleanup;
  } else if (errno != ENOENT) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    goto cleanup;
  }

  // Find the first directory that already exists and leave a pointer just past
  // it.
  len = strlen(path_chars);
  p = path_chars + len - 1;
  for (; p > path_chars; --p) {
    if (*p == '/') {
      *p = 0;
      int res = portable_stat(path_chars, &statbuf);
      *p = '/';
      if (res == 0) {
        // Exists and must be a directory, or the initial stat would have failed
        // with ENOTDIR.
        break;
      } else if (errno != ENOENT) {
        POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
        goto cleanup;
      }
    }
  }
  // p now points at the '/' after the last directory that exists.
  // Successively create each directory
  for (const char *end = path_chars + len; p < end; ++p) {
    if (*p == '/') {
      *p = 0;
      int res = ::mkdir(path_chars, mode);
      *p = '/';
      // EEXIST is fine, just means we're racing to create the directory.
      // Note that somebody could have raced to create a file here, but that
      // will get handled by a ENOTDIR by a subsequent mkdir call.
      if (res != 0 && errno != EEXIST) {
        POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
        goto cleanup;
      }
    }
  }
  if (::mkdir(path_chars, mode) != 0) {
    if (errno != EEXIST) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
      goto cleanup;
    }
    if (portable_stat(path_chars, &statbuf) != 0) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
      goto cleanup;
    }
    if (!S_ISDIR(statbuf.st_mode)) {
      // Exists but is not a directory.
      POST_EXCEPTION_FROM_ERRNO(env, ENOTDIR, path_chars);
      goto cleanup;
    }
  }
cleanup:
  ReleaseStringLatin1Chars(path_chars);
}

namespace {
static jobject NewDirents(JNIEnv *env,
                          jobjectArray names,
                          jbyteArray types) {
  static const jclass dirents_class = makeStaticClass(
      env, "com/google/devtools/build/lib/unix/NativePosixFiles$Dirents");
  static const jmethodID dirents_ctor =
      getConstructorID(env, dirents_class, "([Ljava/lang/String;[B)V");
  return env->NewObject(dirents_class, dirents_ctor, names, types);
}

static char GetDirentType(struct dirent *entry,
                          int dirfd,
                          bool follow_symlinks) {
  switch (entry->d_type) {
    case DT_REG:
      return 'f';
    case DT_DIR:
      return 'd';
    case DT_LNK:
      if (!follow_symlinks) {
        return 's';
      }
      FALLTHROUGH_INTENDED;
    case DT_UNKNOWN:
      portable_stat_struct statbuf;
      if (portable_fstatat(dirfd, entry->d_name, &statbuf, 0) == 0) {
        if (S_ISREG(statbuf.st_mode)) return 'f';
        if (S_ISDIR(statbuf.st_mode)) return 'd';
      }
      // stat failed or returned something weird; fall through
      FALLTHROUGH_INTENDED;
    default:
      return '?';
  }
}
}  // namespace

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    readdir
 * Signature: (Ljava/lang/String;Z)Lcom/google/devtools/build/lib/unix/Dirents;
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_readdir(JNIEnv *env,
                                                    jclass clazz,
                                                    jstring path,
                                                    jchar read_types) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  DIR *dirh;
  while ((dirh = ::opendir(path_chars)) == nullptr && errno == EINTR) {
  }
  if (dirh == nullptr) {
    // EACCES EMFILE ENFILE ENOENT ENOTDIR -> IOException
    // ENOMEM                              -> OutOfMemoryError
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
  if (dirh == nullptr) {
    return nullptr;
  }
  int fd = dirfd(dirh);

  std::vector<std::string> entries;
  std::vector<jbyte> types;
  for (;;) {
    // Clear errno beforehand.  Because readdir() is not required to clear it at
    // EOF, this is the only way to reliably distinguish EOF from error.
    errno = 0;
    struct dirent *entry = ::readdir(dirh);
    if (entry == nullptr) {
      if (errno == 0) break;  // EOF
      // It is unclear whether an error can also skip some records.
      // That does not appear to happen with glibc, at least.
      if (errno == EINTR) continue;  // interrupted by a signal
      if (errno == EIO) continue;  // glibc returns this on transient errors
      // Otherwise, this is a real error we should report.
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
      ::closedir(dirh);
      return nullptr;
    }
    // Omit . and .. from results.
    if (entry->d_name[0] == '.') {
      if (entry->d_name[1] == '\0') continue;
      if (entry->d_name[1] == '.' && entry->d_name[2] == '\0') continue;
    }
    entries.push_back(entry->d_name);
    if (read_types != 'n') {
      types.push_back(GetDirentType(entry, fd, read_types == 'f'));
    }
  }

  if (::closedir(dirh) < 0 && errno != EINTR) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    return nullptr;
  }

  size_t len = entries.size();
  jclass jlStringClass = env->GetObjectClass(path);
  jobjectArray names_obj = env->NewObjectArray(len, jlStringClass, nullptr);
  if (names_obj == nullptr && env->ExceptionOccurred()) {
    return nullptr;  // async exception!
  }

  for (size_t ii = 0; ii < len; ++ii) {
    jstring s = NewStringLatin1(env, entries[ii].c_str());
    if (s == nullptr && env->ExceptionOccurred()) {
      return nullptr;  // async exception!
    }
    env->SetObjectArrayElement(names_obj, ii, s);
  }

  jbyteArray types_obj = nullptr;
  if (read_types != 'n') {
    BAZEL_CHECK_EQ(len, types.size());
    types_obj = env->NewByteArray(len);
    BAZEL_CHECK_NE(types_obj, nullptr);
    if (len > 0) {
      env->SetByteArrayRegion(types_obj, 0, len, &types[0]);
    }
  }

  return NewDirents(env, names_obj, types_obj);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    rename
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_rename(JNIEnv *env,
                                                   jclass clazz,
                                                   jstring oldpath,
                                                   jstring newpath) {
  const char *oldpath_chars = GetStringLatin1Chars(env, oldpath);
  const char *newpath_chars = GetStringLatin1Chars(env, newpath);
  if (::rename(oldpath_chars, newpath_chars) == -1) {
    // EISDIR EXDEV ENOTEMPTY EEXIST EBUSY
    // EINVAL EMLINK ENOTDIR EACCES EPERM
    // ENOENT EROFS ELOOP ENOSPC           -> IOException
    // EFAULT ENAMETOOLONG                 -> RuntimeException
    // ENOMEM                              -> OutOfMemoryError
    std::string filename(std::string(oldpath_chars) + " -> " + newpath_chars);
    POST_EXCEPTION_FROM_ERRNO(env, errno, filename);
  }
  ReleaseStringLatin1Chars(oldpath_chars);
  ReleaseStringLatin1Chars(newpath_chars);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    remove
 * Signature: (Ljava/lang/String;)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT bool JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_remove(JNIEnv *env,
                                                   jclass clazz,
                                                   jstring path) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  if (path_chars == nullptr) {
    return false;
  }
  bool ok = remove(path_chars) != -1;
  if (!ok) {
    if (errno != ENOENT && errno != ENOTDIR) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    }
  }
  ReleaseStringLatin1Chars(path_chars);
  return ok;
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    mkfifo
 * Signature: (Ljava/lang/String;I)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_mkfifo(JNIEnv *env,
                                                   jclass clazz,
                                                   jstring path,
                                                   jint mode) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  if (mkfifo(path_chars, mode) == -1) {
    POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
}

namespace {
// Posts an exception generated by the DeleteTreesBelow algorithm and its helper
// functions.
//
// This is just a convenience wrapper over PostException to format the
// path that caused an error only when necessary, as we keep that path tokenized
// throughout the deletion process.
//
// env is the JNI environment in which to post the exception. error and function
// capture the errno value and the name of the system function that triggered
// it. The faulty path is specified by all the components of dir_path and the
// optional entry subcomponent, which may be NULL.
static void PostDeleteTreesBelowException(
    JNIEnv *env, int error, const char *function,
    const std::vector<std::string> &dir_path, const char *entry,
    const char *filename_and_line_prefix) {
  std::vector<std::string>::const_iterator iter = dir_path.begin();
  std::string path;
  if (iter != dir_path.end()) {
    path = *iter;
    while (++iter != dir_path.end()) {
      path += "/";
      path += *iter;
    }
    if (entry != nullptr) {
      path += "/";
      path += entry;
    }
  } else {
    // When scanning the top-level directory given to DeleteTreesBelow, the
    // dir_path buffer is still empty but we have the full path in entry.
    path = entry;
  }
  BAZEL_CHECK(!env->ExceptionOccurred());
  PostException(
      env, error,
      std::string(filename_and_line_prefix) + function + " (" + path + ")");
}

#define POST_DELETE_TREES_BELOW_EXCEPTION(env, error, function, dir_path, \
                                          entry)                          \
  PostDeleteTreesBelowException(env, error, function, dir_path, entry,    \
                                "[" FILE_BASENAME ":" TOSTRING(__LINE__) "] ")

// Tries to open a directory and, if the first attempt fails, retries after
// granting extra permissions to the directory.
//
// The directory to open is identified by the open descriptor of the parent
// directory (dir_fd) and the subpath to resolve within that directory (entry).
// dir_path contains the path components that were used when opening dir_fd and
// is only used for error reporting purposes.
//
// Returns a directory handle on success or an errno on error. If the error is
// other than ENOENT, posts an exception before returning.
static DIROrError ForceOpendir(JNIEnv *env,
                               const std::vector<std::string> &dir_path,
                               const int dir_fd, const char *entry) {
  static const int flags = O_RDONLY | O_NOFOLLOW | PORTABLE_O_DIRECTORY;
  int fd = openat(dir_fd, entry, flags);
  if (fd == -1) {
    if (errno == ENOENT) {
      return {nullptr, errno};
    }
    // If dir_fd is a readable but non-executable directory containing entry, we
    // could have obtained entry by readdir()-ing, but any attempt to open or
    // stat the entry would fail with EACCESS. In this case, we need to fix the
    // permissions on dir_fd (which we can do only if it's a "real" file
    // descriptor, not AT_FDCWD used as the starting point of DeleteTreesBelow
    // recursion).
    if (errno == EACCES && dir_fd != AT_FDCWD) {
      if (fchmod(dir_fd, 0700) == -1) {
        if (errno != ENOENT) {
          POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "fchmod", dir_path,
                                            nullptr);
        }
        return {nullptr, errno};
      }
    }
    if (fchmodat(dir_fd, entry, 0700, 0) == -1) {
      if (errno != ENOENT) {
        POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "fchmodat", dir_path,
                                          entry);
      }
      return {nullptr, errno};
    }
    fd = openat(dir_fd, entry, flags);
    if (fd == -1) {
      if (errno != ENOENT) {
        POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "opendir", dir_path,
                                          entry);
      }
      return {nullptr, errno};
    }
  }
  DIR* dir = fdopendir(fd);
  if (dir == nullptr) {
    if (errno != ENOENT) {
      POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "fdopendir", dir_path,
                                        entry);
    }
    close(fd);
    return {nullptr, errno};
  }
  return {dir, 0};
}

// Tries to delete a file within a directory and, if the first attempt fails,
// retries after granting extra write permissions to the directory.
//
// The file to delete is identified by the open descriptor of the parent
// directory (dir_fd) and the subpath to resolve within that directory (entry).
// dir_path contains the path components that were used when opening dir_fd and
// is only used for error reporting purposes.
//
// is_dir indicates whether the entry to delete is a directory or not.
//
// Returns 0 when the file doesn't exist or is successfully deleted. Otherwise,
// returns -1 and posts an exception.
static int ForceDelete(JNIEnv* env, const std::vector<std::string>& dir_path,
                       const int dir_fd, const char* entry,
                       const bool is_dir) {
  const int flags = is_dir ? AT_REMOVEDIR : 0;
  if (unlinkat(dir_fd, entry, flags) == -1) {
    if (errno == ENOENT) {
      return 0;
    }
    if (fchmod(dir_fd, 0700) == -1) {
      if (errno == ENOENT) {
        return 0;
      }
      POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "fchmod", dir_path,
                                        nullptr);
      return -1;
    }
    if (unlinkat(dir_fd, entry, flags) == -1) {
      if (errno == ENOENT) {
        return 0;
      }
      POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "unlinkat", dir_path,
                                        entry);
      return -1;
    }
  }
  return 0;
}

// Returns true if the given directory entry represents a subdirectory of dir.
//
// The file to check is identified by the open descriptor of the parent
// directory (dir_fd) and the directory entry within that directory (de).
// dir_path contains the path components that were used when opening dir_fd and
// is only used for error reporting purposes.
//
// This function prefers to extract the type information from the directory
// entry itself if available. If not available, issues a stat starting from
// dir_fd.
//
// Returns 0 on success and updates is_dir accordingly. Returns -1 on error and
// posts an exception.
static int IsSubdir(JNIEnv* env, const std::vector<std::string>& dir_path,
                    const int dir_fd, const struct dirent* de, bool* is_dir) {
  switch (de->d_type) {
    case DT_DIR:
      *is_dir = true;
      return 0;

    case DT_UNKNOWN: {
      struct stat st;
      if (fstatat(dir_fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) == -1) {
        if (errno == ENOENT) {
          *is_dir = false;
          return 0;
        }
        POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "fstatat", dir_path,
                                          de->d_name);
        return -1;
      }
      *is_dir = st.st_mode & S_IFDIR;
      return 0;
    }

    default:
      *is_dir = false;
      return 0;
  }
}

// Recursively deletes all trees under the given path.
//
// The directory to delete is identified by the open descriptor of the parent
// directory (dir_fd) and the subpath to resolve within that directory (entry).
// dir_path contains the path components that were used when opening dir_fd and
// is only used for error reporting purposes.
//
// dir_path is an in/out parameter updated with the path to the directory being
// processed. This avoids the need to construct unnecessary intermediate paths,
// as this algorithm works purely on file descriptors: the paths are only used
// for error reporting purposes, and therefore are only formatted at that
// point.
//
// Returns 0 on success. Returns -1 on error and posts an exception.
static int DeleteTreesBelow(JNIEnv* env, std::vector<std::string>* dir_path,
                            const int dir_fd, const char* entry) {
  DIROrError dir_or_error = ForceOpendir(env, *dir_path, dir_fd, entry);
  DIR *dir = dir_or_error.dir;
  if (dir == nullptr) {
    if (dir_or_error.error == ENOENT) {
      return 0;
    }
    BAZEL_CHECK_NE(env->ExceptionOccurred(), nullptr);
    return -1;
  }

  dir_path->push_back(entry);
  // On macOS and some other non-Linux OSes, on some filesystems, readdir(dir)
  // may return NULL after an entry in dir is deleted even if not all files have
  // been read yet - see
  // https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html;
  // "If a file is removed from or added to the directory after the most recent
  // call to opendir() or rewinddir(), whether a subsequent call to readdir()
  // returns an entry for that file is unspecified." We thus read all the names
  // of dir's entries before deleting. We don't want to simply use fts(3)
  // because we want to be able to chmod at any point in the directory hierarchy
  // to retry a filesystem operation after hitting an EACCES.
  // If in the future we hit any problems here due to the unspecified behavior
  // of readdir() when a file has been deleted by a different thread we can use
  // some form of locking to make sure the threads don't try to clean up the
  // same directory at the same time; or doing it in a loop until the directory
  // is really empty.
  std::vector<std::string> dir_files, dir_subdirs;
  for (;;) {
    errno = 0;
    struct dirent* de = readdir(dir);
    if (de == nullptr) {
      if (errno != 0 && errno != ENOENT) {
        POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "readdir", *dir_path,
                                          nullptr);
      }
      break;
    }

    if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) {
      continue;
    }

    bool is_dir;
    if (IsSubdir(env, *dir_path, dirfd(dir), de, &is_dir) == -1) {
      BAZEL_CHECK_NE(env->ExceptionOccurred(), nullptr);
      break;
    }
    if (is_dir) {
      dir_subdirs.push_back(de->d_name);
    } else {
      dir_files.push_back(de->d_name);
    }
  }
  if (env->ExceptionOccurred() == nullptr) {
    for (const auto &file : dir_files) {
      if (ForceDelete(env, *dir_path, dirfd(dir), file.c_str(), false) == -1) {
        BAZEL_CHECK_NE(env->ExceptionOccurred(), nullptr);
        break;
      }
    }
    // DeleteTreesBelow is recursive; don't hold on to file names unnecessarily.
    dir_files.clear();
  }
  if (env->ExceptionOccurred() == nullptr) {
    for (const auto &subdir : dir_subdirs) {
      if (DeleteTreesBelow(env, dir_path, dirfd(dir), subdir.c_str()) == -1) {
        BAZEL_CHECK_NE(env->ExceptionOccurred(), nullptr);
        break;
      }
      if (ForceDelete(env, *dir_path, dirfd(dir), subdir.c_str(), true) == -1) {
        BAZEL_CHECK_NE(env->ExceptionOccurred(), nullptr);
        break;
      }
    }
  }
  if (closedir(dir) == -1) {
    // Prefer reporting the error encountered while processing entries,
    // not the (unlikely) error on close.
    if (env->ExceptionOccurred() == nullptr) {
      POST_DELETE_TREES_BELOW_EXCEPTION(env, errno, "closedir", *dir_path,
                                        nullptr);
    }
  }
  dir_path->pop_back();
  return env->ExceptionOccurred() == nullptr ? 0 : -1;
}
}  // namespace

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    deleteTreesBelow
 * Signature: (Ljava/lang/String;)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_deleteTreesBelow(
    JNIEnv *env, jclass clazz, jstring path) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  std::vector<std::string> dir_path;
  if (DeleteTreesBelow(env, &dir_path, AT_FDCWD, path_chars) == -1) {
    BAZEL_CHECK_NE(env->ExceptionOccurred(), nullptr);
  }
  BAZEL_CHECK(dir_path.empty());
  ReleaseStringLatin1Chars(path_chars);
}

////////////////////////////////////////////////////////////////////////
// Linux extended file attributes

namespace {
typedef ssize_t getxattr_func(const char *path, const char *name,
                              void *value, size_t size, bool *attr_not_found);

static jbyteArray getxattr_common(JNIEnv *env,
                                  jstring path,
                                  jstring name,
                                  getxattr_func getxattr) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  const char *name_chars = GetStringLatin1Chars(env, name);

  // TODO(bazel-team): on ERANGE, try again with larger buffer.
  jbyte value[4096];
  jbyteArray result = nullptr;
  bool attr_not_found = false;
  ssize_t size = getxattr(path_chars, name_chars, value, arraysize(value),
                          &attr_not_found);
  if (size == -1) {
    if (!attr_not_found) {
      POST_EXCEPTION_FROM_ERRNO(env, errno, path_chars);
    }
  } else {
    result = env->NewByteArray(size);
    // Result may be NULL if allocation failed. In that case, we'll return the
    // NULL and an OOME will be thrown when we are back in Java.
    if (result != nullptr) {
      env->SetByteArrayRegion(result, 0, size, value);
    }
  }
  ReleaseStringLatin1Chars(path_chars);
  ReleaseStringLatin1Chars(name_chars);
  return result;
}
}  // namespace

extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_getxattr(JNIEnv *env,
                                                     jclass clazz,
                                                     jstring path,
                                                     jstring name) {
  return getxattr_common(env, path, name, portable_getxattr);
}

extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_lgetxattr(JNIEnv *env,
                                                      jclass clazz,
                                                      jstring path,
                                                      jstring name) {
  return getxattr_common(env, path, name, portable_lgetxattr);
}

/*
 * Class:     com_google_devtools_build_lib_platform_SleepPreventionModule_SleepPrevention
 * Method:    pushDisableSleep
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SleepPreventionModule_00024SleepPrevention_pushDisableSleep(
    JNIEnv *, jclass) {
  return portable_push_disable_sleep();
}

/*
 * Class:     com_google_devtools_build_lib_platform_SleepPreventionModule_SleepPrevention
 * Method:    popDisableSleep
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SleepPreventionModule_00024SleepPrevention_popDisableSleep(
    JNIEnv *, jclass) {
  return portable_pop_disable_sleep();
}

jobject g_suspend_module;

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemSuspensionModule
 * Method:    registerJNI
 * Signature: ()V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_platform_SystemSuspensionModule_registerJNI(
    JNIEnv *env, jobject local_object) {

  if (g_suspend_module != nullptr) {
    POST_ASSERTION_ERROR(env,
                         "Singleton SystemSuspensionModule already registered");
    return;
  }

  JavaVM *java_vm = GetJavaVM(env);
  if (java_vm == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to get javaVM registering SystemSuspensionModule");
    return;
  }

  g_suspend_module = env->NewGlobalRef(local_object);
  if (g_suspend_module == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to create global ref for SystemSuspensionModule");
    return;
  }
  portable_start_suspend_monitoring();
}

void suspend_callback(SuspensionReason value) {
  if (g_suspend_module != nullptr) {
    PerformIntegerValueCallback(g_suspend_module, "suspendCallback", value);
  }
}

jobject g_thermal_module;

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemThermalModule
 * Method:    registerJNI
 * Signature: ()V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_platform_SystemThermalModule_registerJNI(
    JNIEnv *env, jobject local_object) {

  if (g_thermal_module != nullptr) {
    POST_ASSERTION_ERROR(env,
                         "Singleton SystemThermalModule already registered");
    return;
  }

  JavaVM *java_vm = GetJavaVM(env);
  if (java_vm == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to get javaVM registering SystemThermalModule");
    return;
  }

  g_thermal_module = env->NewGlobalRef(local_object);
  if (g_thermal_module == nullptr) {
    POST_ASSERTION_ERROR(env,
                         "Unable to create global ref for SystemThermalModule");
    return;
  }
  portable_start_thermal_monitoring();
}

void thermal_callback(int value) {
  if (g_thermal_module != nullptr) {
    PerformIntegerValueCallback(g_thermal_module, "thermalCallback", value);
  }
}

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemThermalModule
 * Method:    thermalLoad
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SystemThermalModule_thermalLoad(
    JNIEnv *env, jclass) {
  return portable_thermal_load();
}

jobject g_system_load_advisory_module;

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemLoadAdvisoryModule
 * Method:    registerJNI
 * Signature: ()V
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_platform_SystemLoadAdvisoryModule_registerJNI(
    JNIEnv *env, jobject local_object) {

  if (g_system_load_advisory_module != nullptr) {
    POST_ASSERTION_ERROR(
        env, "Singleton SystemLoadAdvisoryModule already registered");
    return;
  }

  JavaVM *java_vm = GetJavaVM(env);
  if (java_vm == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to get javaVM registering SystemLoadAdvisoryModule");
    return;
  }

  g_system_load_advisory_module = env->NewGlobalRef(local_object);
  if (g_system_load_advisory_module == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to create global ref for SystemLoadAdvisoryModule");
    return;
  }
  portable_start_system_load_advisory_monitoring();
}

void system_load_advisory_callback(int value) {
  if (g_system_load_advisory_module != nullptr) {
    PerformIntegerValueCallback(g_system_load_advisory_module,
                                "systemLoadAdvisoryCallback", value);
  }
}

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemLoadAdvisoryModule
 * Method:    systemLoadAdvisory
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SystemLoadAdvisoryModule_systemLoadAdvisory(
    JNIEnv *env, jclass) {
  return portable_system_load_advisory();
}

jobject g_memory_pressure_module;

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemMemoryPressureMonitor
 * Method:    registerJNI
 * Signature: ()I
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_platform_SystemMemoryPressureMonitor_registerJNI(
    JNIEnv *env, jobject local_object) {

  if (g_memory_pressure_module != nullptr) {
    POST_ASSERTION_ERROR(
        env, "Singleton SystemMemoryPressureModule already registered");
    return;
  }

  JavaVM *java_vm = GetJavaVM(env);
  if (java_vm == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to get javaVM registering SystemMemoryPressureModule");
    return;
  }

  g_memory_pressure_module = env->NewGlobalRef(local_object);
  if (g_memory_pressure_module == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to create global ref for SystemMemoryPressureModule");
    return;
  }
  portable_start_memory_pressure_monitoring();
}

void memory_pressure_callback(MemoryPressureLevel level) {
  if (g_memory_pressure_module != nullptr) {
    PerformIntegerValueCallback(g_memory_pressure_module,
                                "memoryPressureCallback", level);
  }
}

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemMemoryPressureMonitor
 * Method:    systemMemoryPressure
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SystemMemoryPressureMonitor_systemMemoryPressure(
    JNIEnv *env, jclass) {
  return portable_memory_pressure();
}

jobject g_disk_space_module;

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemDiskSpaceModule
 * Method:    registerJNI
 * Signature: ()I
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_platform_SystemDiskSpaceModule_registerJNI(
    JNIEnv *env, jobject local_object) {

  if (g_disk_space_module != nullptr) {
    POST_ASSERTION_ERROR(env,
                         "Singleton SystemDiskSpaceModule already registered");
    return;
  }

  JavaVM *java_vm = GetJavaVM(env);
  if (java_vm == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to get javaVM registering SystemDiskSpaceModule");
    return;
  }

  g_disk_space_module = env->NewGlobalRef(local_object);
  if (g_disk_space_module == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to create global ref for SystemDiskSpaceModule");
    return;
  }
  portable_start_disk_space_monitoring();
}

void disk_space_callback(DiskSpaceLevel level) {
  if (g_disk_space_module != nullptr) {
    PerformIntegerValueCallback(g_disk_space_module, "diskSpaceCallback",
                                level);
  }
}

jobject g_cpu_speed_module;

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemCPUSpeedModule
 * Method:    registerJNI
 * Signature: ()I
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_platform_SystemCPUSpeedModule_registerJNI(
    JNIEnv *env, jobject local_object) {

  if (g_cpu_speed_module != nullptr) {
    POST_ASSERTION_ERROR(env,
                         "Singleton SystemCPUSpeedModule already registered");
    return;
  }

  JavaVM *java_vm = GetJavaVM(env);
  if (java_vm == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to get javaVM registering SystemCPUSpeedModule");
    return;
  }

  g_cpu_speed_module = env->NewGlobalRef(local_object);
  if (g_cpu_speed_module == nullptr) {
    POST_ASSERTION_ERROR(
        env, "Unable to create global ref for SystemCPUSpeedModule");
    return;
  }
  portable_start_cpu_speed_monitoring();
}

void cpu_speed_callback(int speed) {
  if (g_cpu_speed_module != nullptr) {
    PerformIntegerValueCallback(g_cpu_speed_module, "cpuSpeedCallback", speed);
  }
}

/*
 * Class:     Java_com_google_devtools_build_lib_platform_SystemCPUSpeedModule
 * Method:    cpuSpeed
 * Signature: ()I
 *
 * Returns 1-100 to represent CPU speed. Returns -1 in case of error.
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SystemCPUSpeedModule_cpuSpeed(
    JNIEnv *env, jclass) {
  return portable_cpu_speed();
}

}  // namespace blaze_jni
