8207340: (fs) UnixNativeDispatcher close and readdir usages should be fixed
authoralanb
Tue, 17 Jul 2018 08:10:48 +0100
changeset 51102 90144bc10fe6
parent 51101 babe5786dea9
child 51103 cecc2e10edf4
8207340: (fs) UnixNativeDispatcher close and readdir usages should be fixed Reviewed-by: bpb
src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
--- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c	Mon Jul 16 21:53:49 2018 -0700
+++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c	Tue Jul 17 08:10:48 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,7 @@
 #define fstat64 fstat
 #define lstat64 lstat
 #define dirent64 dirent
-#define readdir64_r readdir_r
+#define readdir64 readdir
 #endif
 
 #include "jni.h"
@@ -425,9 +425,17 @@
 
 JNIEXPORT void JNICALL
 Java_sun_nio_fs_UnixNativeDispatcher_close0(JNIEnv* env, jclass this, jint fd) {
-    int err;
-    /* TDB - need to decide if EIO and other errors should cause exception */
-    RESTARTABLE(close((int)fd), err);
+    int res;
+
+#if defined(_AIX)
+    /* AIX allows close to be restarted after EINTR */
+    RESTARTABLE(close((int)fd), res);
+#else
+    res = close((int)fd);
+#endif
+    if (res == -1 && errno != EINTR) {
+        throwUnixException(env, errno);
+    }
 }
 
 JNIEXPORT jint JNICALL
@@ -720,41 +728,23 @@
 
 JNIEXPORT jbyteArray JNICALL
 Java_sun_nio_fs_UnixNativeDispatcher_readdir(JNIEnv* env, jclass this, jlong value) {
-    struct dirent64* result;
-    struct {
-        struct dirent64 buf;
-        char name_extra[PATH_MAX + 1 - sizeof result->d_name];
-    } entry;
-    struct dirent64* ptr = &entry.buf;
-    int res;
     DIR* dirp = jlong_to_ptr(value);
+    struct dirent64* ptr;
 
-    /* EINTR not listed as a possible error */
-    /* TDB: reentrant version probably not required here */
-    res = readdir64_r(dirp, ptr, &result);
-
-#ifdef _AIX
-    /* On AIX, readdir_r() returns EBADF (i.e. '9') and sets 'result' to NULL for the */
-    /* directory stream end. Otherwise, 'errno' will contain the error code. */
-    if (res != 0) {
-        res = (result == NULL && res == EBADF) ? 0 : errno;
-    }
-#endif
-
-    if (res != 0) {
-        throwUnixException(env, res);
+    errno = 0;
+    ptr = readdir64(dirp);
+    if (ptr == NULL) {
+        if (errno != 0) {
+            throwUnixException(env, errno);
+        }
         return NULL;
     } else {
-        if (result == NULL) {
-            return NULL;
-        } else {
-            jsize len = strlen(ptr->d_name);
-            jbyteArray bytes = (*env)->NewByteArray(env, len);
-            if (bytes != NULL) {
-                (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
-            }
-            return bytes;
+        jsize len = strlen(ptr->d_name);
+        jbyteArray bytes = (*env)->NewByteArray(env, len);
+        if (bytes != NULL) {
+            (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)(ptr->d_name));
         }
+        return bytes;
     }
 }