From abb21f4753cbfb0a1639180eab2c0f48b93d06ee Mon Sep 17 00:00:00 2001
From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com>
Date: Thu, 10 Jun 2021 16:42:56 +0700
Subject: [PATCH] Use utimensat on android

---
 .../native/libnio/fs/UnixNativeDispatcher.c   | 22 ++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
index 9df8be1e62c2..3b886283778b 100644
--- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
+++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
@@ -140,6 +140,7 @@ typedef int fstatat64_func(int, const char *, struct stat64 *, int);
 typedef int unlinkat_func(int, const char*, int);
 typedef int renameat_func(int, const char*, int, const char*);
 typedef int futimesat_func(int, const char *, const struct timeval *);
+typedef int utimensat_func(int, const char *, const struct timespec *, int flags);
 typedef int futimens_func(int, const struct timespec *);
 typedef int lutimes_func(const char *, const struct timeval *);
 typedef DIR* fdopendir_func(int);
@@ -149,6 +150,7 @@ static fstatat64_func* my_fstatat64_func = NULL;
 static unlinkat_func* my_unlinkat_func = NULL;
 static renameat_func* my_renameat_func = NULL;
 static futimesat_func* my_futimesat_func = NULL;
+static utimensat_func* my_utimensat_func = NULL;
 static futimens_func* my_futimens_func = NULL;
 static lutimes_func* my_lutimes_func = NULL;
 static fdopendir_func* my_fdopendir_func = NULL;
@@ -272,6 +274,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
 #ifndef _ALLBSD_SOURCE
     my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
     my_lutimes_func = (lutimes_func*) dlsym(RTLD_DEFAULT, "lutimes");
+#endif
+#ifdef __ANDROID__
+    my_utimensat_func = (utimensat_func*) dlsym(RTLD_DEFAULT, "utimensat");
 #endif
     my_futimens_func = (futimens_func*) dlsym(RTLD_DEFAULT, "futimens");
 #if defined(_AIX)
@@ -292,7 +297,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
     capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_FUTIMES;
     capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_LUTIMES;
 #else
-    if (my_futimesat_func != NULL)
+    if (my_futimesat_func != NULL || my_utimensat_func != NULL)
         capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_FUTIMES;
     if (my_lutimes_func != NULL)
         capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_LUTIMES;
@@ -304,7 +309,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
 
     if (my_openat64_func != NULL &&  my_fstatat64_func != NULL &&
         my_unlinkat_func != NULL && my_renameat_func != NULL &&
-        my_futimesat_func != NULL && my_fdopendir_func != NULL)
+        (my_futimesat_func != NULL || my_utimensat_func != NULL) && my_fdopendir_func != NULL)
     {
         capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_OPENAT;
     }
@@ -697,14 +702,21 @@ Java_sun_nio_fs_UnixNativeDispatcher_futimes(JNIEnv* env, jclass this, jint file
     times[1].tv_sec = modificationTime / 1000000;
     times[1].tv_usec = modificationTime % 1000000;
 
+    times[0].tv_nsec = (accessTime % 1000000) * 1000;
+    times[1].tv_nsec = (modificationTime % 1000000) * 1000;
+
 #ifdef _ALLBSD_SOURCE
     RESTARTABLE(futimes(filedes, &times[0]), err);
 #else
-    if (my_futimesat_func == NULL) {
-        JNU_ThrowInternalError(env, "my_futimesat_func is NULL");
+    if (my_futimesat_func == NULL && my_utimensat_func == NULL) {
+        JNU_ThrowInternalError(env, "my_futimesat_func and my_utimensat_func are NULL");
         return;
     }
-    RESTARTABLE((*my_futimesat_func)(filedes, NULL, &times[0]), err);
+    if (my_futimesat_func != NULL) {
+        RESTARTABLE((*my_futimesat_func)(filedes, NULL, &times[0]), err);
+    } else {
+        RESTARTABLE((*my_utimensat_func)(filedes, NULL, &times[0], 0), err);
+    }
 #endif
     if (err == -1) {
         throwUnixException(env, errno);
-- 
2.44.0

