8207340: (fs) UnixNativeDispatcher close and readdir usages should be fixed
Reviewed-by: bpb
--- 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;
}
}