// 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 <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <utime.h>

#include <string>
#include <vector>

#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 {

// 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 EBADF:         // Bad file number or descriptor already closed.
    case ENAMETOOLONG:  // File name too long
    case ENODATA:    // No data available
    case EINVAL:     // Invalid argument
#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 ELOOP:      // Too many symbolic links encountered
    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";
  }
  jclass exception_class = env->FindClass(exception_classname);
  if (exception_class != NULL) {
    env->ThrowNew(exception_class,
                  (message + " (" + ErrorMessage(error_number) + ")").c_str());
  } else {
    abort();  // panic!
  }
}

// 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 = NULL;
  }

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

  jclass exception_class = env->FindClass(exception_classname);
  if (exception_class != NULL) {
     std::string message(file_path);
     message += " (";
     message += ErrorMessage(error_number);
     message += ")";
     env->ThrowNew(exception_class, message.c_str());
     return true;
  } else {
    abort();  // panic!
    return false;  // Not reachable.
  }
}

// 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 = NULL;
  if (readlink(path_chars, target, arraysize(target)) == -1) {
    PostException(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) {
    PostException(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) {
    PostException(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);
}

static jobject NewFileStatus(JNIEnv *env,
                             const portable_stat_struct &stat_ref) {
  static jclass file_status_class = NULL;
  if (file_status_class == NULL) {  // note: harmless race condition
    jclass local =
        env->FindClass("com/google/devtools/build/lib/unix/FileStatus");
    CHECK(local != NULL);
    file_status_class = static_cast<jclass>(env->NewGlobalRef(local));
  }

  static jmethodID method = NULL;
  if (method == NULL) {  // note: harmless race condition
    method = env->GetMethodID(file_status_class, "<init>", "(IIIIIIIJIJ)V");
    CHECK(method != NULL);
  }

  return env->NewObject(
      file_status_class, method, stat_ref.st_mode,
      StatSeconds(stat_ref, STAT_ATIME), StatNanoSeconds(stat_ref, STAT_ATIME),
      StatSeconds(stat_ref, STAT_MTIME), StatNanoSeconds(stat_ref, STAT_MTIME),
      StatSeconds(stat_ref, STAT_CTIME), StatNanoSeconds(stat_ref, STAT_CTIME),
      static_cast<jlong>(stat_ref.st_size),
      static_cast<int>(stat_ref.st_dev), static_cast<jlong>(stat_ref.st_ino));
}

static jobject NewErrnoFileStatus(JNIEnv *env,
                                  int saved_errno,
                                  const portable_stat_struct &stat_ref) {
  static jclass errno_file_status_class = NULL;
  if (errno_file_status_class == NULL) {  // note: harmless race condition
    jclass local =
        env->FindClass("com/google/devtools/build/lib/unix/ErrnoFileStatus");
    CHECK(local != NULL);
    errno_file_status_class = static_cast<jclass>(env->NewGlobalRef(local));
  }

  static jmethodID no_error_ctor = NULL;
  if (no_error_ctor == NULL) {  // note: harmless race condition
    no_error_ctor = env->GetMethodID(errno_file_status_class,
                                     "<init>", "(IIIIIIIJIJ)V");
    CHECK(no_error_ctor != NULL);
  }

  static jmethodID errorno_ctor = NULL;
  if (errorno_ctor == NULL) {  // note: harmless race condition
    errorno_ctor = env->GetMethodID(errno_file_status_class, "<init>", "(I)V");
    CHECK(errorno_ctor != NULL);
  }

  if (saved_errno != 0) {
    return env->NewObject(errno_file_status_class, errorno_ctor, saved_errno);
  }
  return env->NewObject(
      errno_file_status_class, no_error_ctor, stat_ref.st_mode,
      StatSeconds(stat_ref, STAT_ATIME), StatNanoSeconds(stat_ref, STAT_ATIME),
      StatSeconds(stat_ref, STAT_MTIME), StatNanoSeconds(stat_ref, STAT_MTIME),
      StatSeconds(stat_ref, STAT_CTIME), StatNanoSeconds(stat_ref, STAT_CTIME),
      static_cast<jlong>(stat_ref.st_size), static_cast<int>(stat_ref.st_dev),
      static_cast<jlong>(stat_ref.st_ino));
}

static void SetIntField(JNIEnv *env,
                        const jclass &clazz,
                        const jobject &object,
                        const char *name,
                        int val) {
  jfieldID fid = env->GetFieldID(clazz, name, "I");
  CHECK(fid != NULL);
  env->SetIntField(object, fid, val);
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_ErrnoFileStatus_00024ErrnoConstants_initErrnoConstants(  // NOLINT
  JNIEnv *env, jobject errno_constants) {
  jclass clazz = env->GetObjectClass(errno_constants);
  SetIntField(env, clazz, errno_constants, "ENOENT", ENOENT);
  SetIntField(env, clazz, errno_constants, "EACCES", EACCES);
  SetIntField(env, clazz, errno_constants, "ELOOP", ELOOP);
  SetIntField(env, clazz, errno_constants, "ENOTDIR", ENOTDIR);
  SetIntField(env, clazz, errno_constants, "ENAMETOOLONG", ENAMETOOLONG);
}

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

    // EACCES ENOENT ENOTDIR ELOOP -> IOException
    // ENAMETOOLONGEFAULT          -> RuntimeException
    // ENOMEM                      -> OutOfMemoryError

    if (PostRuntimeException(env, saved_errno, path_chars)) {
      ReleaseStringLatin1Chars(path_chars);
      return NULL;
    } else if (should_throw) {
      PostException(env, saved_errno, path_chars);
      ReleaseStringLatin1Chars(path_chars);
      return NULL;
    }
  }
  ReleaseStringLatin1Chars(path_chars);

  return should_throw
    ? NewFileStatus(env, statbuf)
    : NewErrnoFileStatus(env, saved_errno, statbuf);
}

/*
 * 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) {
  return StatCommon(env, path, portable_stat, true);
}

/*
 * 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) {
  return StatCommon(env, path, portable_lstat, true);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    statNullable
 * Signature: (Ljava/lang/String;)Lcom/google/devtools/build/lib/unix/FileStatus;
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_errnoStat(JNIEnv *env,
                                                      jclass clazz,
                                                      jstring path) {
  return StatCommon(env, path, portable_stat, false);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    lstatNullable
 * Signature: (Ljava/lang/String;)Lcom/google/devtools/build/lib/unix/FileStatus;
 */
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_errnoLstat(JNIEnv *env,
                                                       jclass clazz,
                                                       jstring path) {
  return StatCommon(env, path, portable_lstat, false);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    utime
 * Signature: (Ljava/lang/String;ZII)V
 * Throws:    java.io.IOException
 */
extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_utime(JNIEnv *env,
                                                  jclass clazz,
                                                  jstring path,
                                                  jboolean now,
                                                  jint modtime) {
  const char *path_chars = GetStringLatin1Chars(env, path);
#ifdef __linux
  struct timespec spec[2] = {{0, UTIME_OMIT}, {modtime, now ? UTIME_NOW : 0}};
  if (::utimensat(AT_FDCWD, path_chars, spec, 0) == -1) {
    PostException(env, errno, path_chars);
  }
#else
  struct utimbuf buf = { modtime, modtime };
  struct utimbuf *bufptr = now ? NULL : &buf;
  if (::utime(path_chars, bufptr) == -1) {
    // EACCES ENOENT EMULTIHOP ELOOP EINTR
    // ENOTDIR ENOLINK EPERM EROFS   -> IOException
    // EFAULT ENAMETOOLONG           -> RuntimeException
    PostException(env, errno, path_chars);
  }
#endif
  ReleaseStringLatin1Chars(path_chars);
}

/*
 * Class:     com.google.devtools.build.lib.unix.NativePosixFiles
 * Method:    umask
 * Signature: (I)I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_umask(JNIEnv *env,
                                                  jclass clazz,
                                                  jint new_umask) {
  return ::umask(new_umask);
}

/*
 * 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 {
      PostException(env, errno, path_chars);
    }
  }
  ReleaseStringLatin1Chars(path_chars);
  return result;
}

/*
 * 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.
      PostException(env, ENOTDIR, path_chars);
    }
    goto cleanup;
  } else if (errno != ENOENT) {
    PostException(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) {
        PostException(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) {
        PostException(env, errno, path_chars);
        goto cleanup;
      }
    }
  }
  if (::mkdir(path_chars, mode) != 0) {
    if (errno != EEXIST) {
      PostException(env, errno, path_chars);
      goto cleanup;
    }
    if (portable_stat(path_chars, &statbuf) != 0) {
      PostException(env, errno, path_chars);
      goto cleanup;
    }
    if (!S_ISDIR(statbuf.st_mode)) {
      // Exists but is not a directory.
      PostException(env, ENOTDIR, path_chars);
      goto cleanup;
    }
  }
cleanup:
  ReleaseStringLatin1Chars(path_chars);
}

static jobject NewDirents(JNIEnv *env,
                          jobjectArray names,
                          jbyteArray types) {
  // See http://java.sun.com/docs/books/jni/html/fldmeth.html#26855
  static jclass dirents_class = NULL;
  if (dirents_class == NULL) {  // note: harmless race condition
    jclass local = env->FindClass("com/google/devtools/build/lib/unix/NativePosixFiles$Dirents");
    CHECK(local != NULL);
    dirents_class = static_cast<jclass>(env->NewGlobalRef(local));
  }

  static jmethodID ctor = NULL;
  if (ctor == NULL) {  // note: harmless race condition
    ctor =
        env->GetMethodID(dirents_class, "<init>", "([Ljava/lang/String;[B)V");
    CHECK(ctor != NULL);
  }

  return env->NewObject(dirents_class, 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 '?';
  }
}

/*
 * 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)) == NULL && errno == EINTR) { }
  if (dirh == NULL) {
    // EACCES EMFILE ENFILE ENOENT ENOTDIR -> IOException
    // ENOMEM                              -> OutOfMemoryError
    PostException(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
  if (dirh == NULL) {
    return NULL;
  }
  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 == NULL) {
      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.
      PostException(env, errno, path_chars);
      ::closedir(dirh);
      return NULL;
    }
    // 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) {
    PostException(env, errno, path_chars);
    return NULL;
  }

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

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

  jbyteArray types_obj = NULL;
  if (read_types != 'n') {
    CHECK(len == types.size());
    types_obj = env->NewByteArray(len);
    CHECK(types_obj);
    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);
    PostException(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 == NULL) {
    return false;
  }
  bool ok = remove(path_chars) != -1;
  if (!ok) {
    if (errno != ENOENT && errno != ENOTDIR) {
      PostException(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) {
    PostException(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
}

// 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) {
  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 != NULL) {
      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;
  }
  CHECK(!env->ExceptionOccurred());
  PostException(env, errno, std::string(function) + " (" + path + ")");
}

// 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 on success. Returns NULL on error and posts an
// exception.
static DIR* 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 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) {
        PostDeleteTreesBelowException(env, errno, "fchmod", dir_path, NULL);
        return NULL;
      }
    }
    if (fchmodat(dir_fd, entry, 0700, 0) == -1) {
      PostDeleteTreesBelowException(env, errno, "fchmodat", dir_path, entry);
      return NULL;
    }
    fd = openat(dir_fd, entry, flags);
    if (fd == -1) {
      PostDeleteTreesBelowException(env, errno, "opendir", dir_path, entry);
      return NULL;
    }
  }
  DIR* dir = fdopendir(fd);
  if (dir == NULL) {
    PostDeleteTreesBelowException(env, errno, "fdopendir", dir_path, entry);
    close(fd);
    return NULL;
  }
  return dir;
}

// 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 on success. Returns -1 on error 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 (fchmod(dir_fd, 0700) == -1) {
      PostDeleteTreesBelowException(env, errno, "fchmod", dir_path, NULL);
      return -1;
    }
    if (unlinkat(dir_fd, entry, flags) == -1) {
      PostDeleteTreesBelowException(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) {
        PostDeleteTreesBelowException(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) {
  DIR *dir = ForceOpendir(env, *dir_path, dir_fd, entry);
  if (dir == NULL) {
    CHECK(env->ExceptionOccurred() != NULL);
    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://support.apple.com/kb/TA21420; 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.
  std::vector<std::string> dir_files, dir_subdirs;
  for (;;) {
    errno = 0;
    struct dirent* de = readdir(dir);
    if (de == NULL) {
      if (errno != 0) {
        PostDeleteTreesBelowException(env, errno, "readdir", *dir_path, NULL);
      }
      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) {
      CHECK(env->ExceptionOccurred() != NULL);
      break;
    }
    if (is_dir) {
      dir_subdirs.push_back(de->d_name);
    } else {
      dir_files.push_back(de->d_name);
    }
  }
  if (env->ExceptionOccurred() == NULL) {
    for (const auto &file : dir_files) {
      if (ForceDelete(env, *dir_path, dirfd(dir), file.c_str(), false) == -1) {
        CHECK(env->ExceptionOccurred() != NULL);
        break;
      }
    }
    // DeleteTreesBelow is recursive; don't hold on to file names unnecessarily.
    dir_files.clear();
  }
  if (env->ExceptionOccurred() == NULL) {
    for (const auto &subdir : dir_subdirs) {
      if (DeleteTreesBelow(env, dir_path, dirfd(dir), subdir.c_str()) == -1) {
        CHECK(env->ExceptionOccurred() != NULL);
        break;
      }
      if (ForceDelete(env, *dir_path, dirfd(dir), subdir.c_str(), true) == -1) {
        CHECK(env->ExceptionOccurred() != NULL);
        break;
      }
    }
  }
  if (closedir(dir) == -1) {
    // Prefer reporting the error encountered while processing entries,
    // not the (unlikely) error on close.
    if (env->ExceptionOccurred() == NULL) {
      PostDeleteTreesBelowException(env, errno, "closedir", *dir_path, NULL);
    }
  }
  dir_path->pop_back();
  return env->ExceptionOccurred() == NULL ? 0 : -1;
}

/*
 * 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) {
    CHECK(env->ExceptionOccurred() != NULL);
  }
  CHECK(dir_path.empty());
  ReleaseStringLatin1Chars(path_chars);
}

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

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 = NULL;
  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) {
      PostException(env, errno, path_chars);
    }
  } else {
    result = env->NewByteArray(size);
    env->SetByteArrayRegion(result, 0, size, value);
  }
  ReleaseStringLatin1Chars(path_chars);
  ReleaseStringLatin1Chars(name_chars);
  return result;
}

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);
}

extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_openWrite(
    JNIEnv *env, jclass clazz, jstring path, jboolean append) {
  const char *path_chars = GetStringLatin1Chars(env, path);
  int flags = (O_WRONLY | O_CREAT) | (append ? O_APPEND : O_TRUNC);
  int fd;
  while ((fd = open(path_chars, flags, 0666)) == -1 && errno == EINTR) {
  }
  if (fd == -1) {
    PostException(env, errno, path_chars);
  }
  ReleaseStringLatin1Chars(path_chars);
  return fd;
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_close(JNIEnv *env,
                                                               jclass clazz,
                                                               jint fd,
                                                               jobject ingore) {
  if (close(fd) == -1) {
    PostException(env, errno, "close");
  }
}

extern "C" JNIEXPORT void JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixFiles_write(
    JNIEnv *env, jclass clazz, jint fd, jbyteArray data, jint off, jint len) {
  int data_len = env->GetArrayLength(data);
  if (off < 0 || len < 0 || off > data_len || data_len - off < len) {
    jclass oob = env->FindClass("java/lang/IndexOutOfBoundsException");
    if (oob != nullptr) {
      env->ThrowNew(oob, nullptr);
    }
    return;
  }
  jbyte *buf = static_cast<jbyte *>(malloc(len));
  if (buf == nullptr) {
    PostException(env, ENOMEM, "write");
    return;
  }
  env->GetByteArrayRegion(data, off, len, buf);
  // GetByteArrayRegion may raise ArrayIndexOutOfBoundsException if one of the
  // indexes in the region is not valid. As we obtain the inidices from the
  // caller, we have to check.
  if (!env->ExceptionOccurred()) {
    jbyte *p = buf;
    while (len > 0) {
      ssize_t res = write(fd, p, len);
      if (res == -1) {
        if (errno != EINTR) {
          PostException(env, errno, "write");
          break;
        }
      } else {
        p += res;
        len -= res;
      }
    }
  }
  free(buf);
}

extern "C" JNIEXPORT jlong JNICALL
Java_com_google_devtools_build_lib_unix_NativePosixSystem_sysctlbynameGetLong(
    JNIEnv *env, jclass clazz, jstring name) {
  const char *name_chars = GetStringLatin1Chars(env, name);
  long r;
  size_t len = sizeof(r);
  if (portable_sysctlbyname(name_chars, &r, &len) == -1) {
    PostException(env, errno, std::string("sysctlbyname(") + name_chars + ")");
  }
  ReleaseStringLatin1Chars(name_chars);
  return (jlong)r;
}

/*
 * 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();
}

/*
 * Class:     com_google_devtools_build_lib_platform_SuspendCounter
 * Method:    suspendCountJNI
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_SuspendCounter_suspendCountJNI(
    JNIEnv *, jclass) {
  return portable_suspend_count();
}

/*
 * Class:     Java_com_google_devtools_build_lib_platform_MemoryPressureCounter
 * Method:    warningCountJNI
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_MemoryPressureCounter_warningCountJNI(
    JNIEnv *, jclass) {
  return portable_memory_pressure_warning_count();
}

/*
 * Class:     Java_com_google_devtools_build_lib_platform_MemoryPressure
 * Method:    criticalCountJNI
 * Signature: ()I
 */
extern "C" JNIEXPORT jint JNICALL
Java_com_google_devtools_build_lib_platform_MemoryPressureCounter_criticalCountJNI(
    JNIEnv *, jclass) {
  return portable_memory_pressure_critical_count();
}

}  // namespace blaze_jni
