// 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 EPERM:   // Operation not permitted
      exception_classname =
          "com/google/devtools/build/lib/unix/FilePermissionException";
      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 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
