RFR: 8179887 - Build failure with glibc >= 2.24: error: 'int readdir_r(DIR*, dirent*, dirent**)' is deprecated
B. Blaser
bsrbnd at gmail.com
Thu Jun 28 17:16:14 UTC 2018
Hi Alan,
On 28 June 2018 at 13:49, Alan Bateman <Alan.Bateman at oracle.com> wrote:
> On 20/06/2018 11:08, Pengfei Li wrote:
>>
>> Hi
>>
>> I have tried the patch (
>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-May/052991.html )
>> on Ubuntu 18.04 machines (x86_64 & aarch64) with glibc=2.26.1 and build is
>> OK.
>>
>> There's a small issue within the following code in
>> src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
>> Unlike readdir_r(), readdir() does not return int value. The value of res
>> is always 0 before #ifdef.
>>
>> 727 /* EINTR not listed as a possible error */
>> 728 errno = 0;
>> 729 ptr = readdir64(dirp);
>> 730 res = errno;
>> 731
>> 732 #ifdef _AIX
>> 733 /* On AIX, readdir() returns EBADF (i.e. '9') and sets 'result'
>> to NULL for the */
>> 734 /* directory stream end. Otherwise, 'errno' will contain the
>> error code. */
>> 735 if (res != 0) {
>> 736 res = (ptr == NULL && res == EBADF) ? 0 : errno;
>> 737 }
>> 738 #endif
>>
>> May I know that if this core-libs change going to be merged recently, or
>> more platforms needs to be explored?
>>
> I see your other mail looking to to add #pragma GCC ... to avoid using
> configure --disable-warnings-as-errors.
>
> I think it would be better to just replace the usage readdir_r usage in that
> native method. I've tested the patch below on macOS, Linux and Solaris. The
> SAP folks maintain the AIX port and would need to test it on that platform
> as it eliminates the AIX specific code for dealing with end of stream that
> should be needed when using readdir.
>
> -Alan
I've checked AIX's 'readdir()' doc [1] and I guess you're right that
it never sets 'errno' to 'EBADF' while 'readdir_r()' may return it
(see [2]).
I missed this on my original patch.
So, your update seems fine to me even if I cannot evaluate it on AIX myself.
Thanks,
Bernard
[1] https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.basetrf1/opendir.htm
[2] https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.basetrf2/readdir_r.htm
> diff -r 9d62da00bf15 -r 5e67e87bd6fa
> src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
> --- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Sat May 26
> 06:59:49 2018 +0200
> +++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Mon Jun 25
> 14:17:03 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"
> @@ -720,41 +720,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;
> }
> }
More information about the core-libs-dev
mailing list