8229872: (fs) Increase buffer size used with getmntent
Summary: Dynamically allocate memory for getmntent
Reviewed-by: alanb
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystem.java Mon Sep 30 10:21:11 2019 +0200
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxFileSystem.java Tue Sep 24 14:54:57 2019 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, 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
@@ -79,10 +79,26 @@
ArrayList<UnixMountEntry> entries = new ArrayList<>();
try {
long fp = setmntent(Util.toBytes(fstab), Util.toBytes("r"));
+ int maxLineSize = 1024;
+ try {
+ for (;;) {
+ int lineSize = getlinelen(fp);
+ if (lineSize == -1)
+ break;
+ if (lineSize > maxLineSize)
+ maxLineSize = lineSize;
+ }
+ } catch (UnixException x) {
+ // nothing we need to do
+ } finally {
+ rewind(fp);
+ }
+
try {
for (;;) {
UnixMountEntry entry = new UnixMountEntry();
- int res = getmntent(fp, entry);
+ // count in NUL character at the end
+ int res = getmntent(fp, entry, maxLineSize + 1);
if (res < 0)
break;
entries.add(entry);
--- a/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java Mon Sep 30 10:21:11 2019 +0200
+++ b/src/java.base/linux/classes/sun/nio/fs/LinuxNativeDispatcher.java Tue Sep 24 14:54:57 2019 +0300
@@ -51,7 +51,17 @@
/**
* int getmntent(FILE *fp, struct mnttab *mp, int len);
*/
- static native int getmntent(long fp, UnixMountEntry entry)
+
+ static int getmntent(long fp, UnixMountEntry entry, int buflen) throws UnixException {
+ NativeBuffer buffer = NativeBuffers.getNativeBuffer(buflen);
+ try {
+ return getmntent0(fp, entry, buffer.address(), buflen);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ static native int getmntent0(long fp, UnixMountEntry entry, long buffer, int bufLen)
throws UnixException;
/**
--- a/src/java.base/linux/native/libnio/fs/LinuxNativeDispatcher.c Mon Sep 30 10:21:11 2019 +0200
+++ b/src/java.base/linux/native/libnio/fs/LinuxNativeDispatcher.c Tue Sep 24 14:54:57 2019 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, 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
@@ -169,12 +169,11 @@
}
JNIEXPORT jint JNICALL
-Java_sun_nio_fs_LinuxNativeDispatcher_getmntent(JNIEnv* env, jclass this,
- jlong value, jobject entry)
+Java_sun_nio_fs_LinuxNativeDispatcher_getmntent0(JNIEnv* env, jclass this,
+ jlong value, jobject entry, jlong buffer, jint bufLen)
{
struct mntent ent;
- char buf[1024];
- int buflen = sizeof(buf);
+ char * buf = (char*)jlong_to_ptr(buffer);
struct mntent* m;
FILE* fp = jlong_to_ptr(value);
jsize len;
@@ -184,7 +183,7 @@
char* fstype;
char* options;
- m = getmntent_r(fp, &ent, (char*)&buf, buflen);
+ m = getmntent_r(fp, &ent, buf, (int)bufLen);
if (m == NULL)
return -1;
name = m->mnt_fsname;
--- a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Mon Sep 30 10:21:11 2019 +0200
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Tue Sep 24 14:54:57 2019 +0300
@@ -119,6 +119,16 @@
static native void fclose(long stream) throws UnixException;
/**
+ * void rewind(FILE* stream);
+ */
+ static native void rewind(long stream) throws UnixException;
+
+ /**
+ * ssize_t getline(char **lineptr, size_t *n, FILE *stream);
+ */
+ static native int getlinelen(long stream) throws UnixException;
+
+ /**
* link(const char* existing, const char* new)
*/
static void link(UnixPath existing, UnixPath newfile) throws UnixException {
--- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Mon Sep 30 10:21:11 2019 +0200
+++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Tue Sep 24 14:54:57 2019 +0300
@@ -403,6 +403,51 @@
}
}
+JNIEXPORT void JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_rewind(JNIEnv* env, jclass this, jlong stream)
+{
+ FILE* fp = jlong_to_ptr(stream);
+ int saved_errno;
+
+ errno = 0;
+ rewind(fp);
+ saved_errno = errno;
+ if (ferror(fp)) {
+ throwUnixException(env, saved_errno);
+ }
+}
+
+/**
+ * This function returns line length without NUL terminator or -1 on EOF.
+ */
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_UnixNativeDispatcher_getlinelen(JNIEnv* env, jclass this, jlong stream)
+{
+ FILE* fp = jlong_to_ptr(stream);
+ size_t lineSize = 0;
+ char * lineBuffer = NULL;
+ int saved_errno;
+
+ ssize_t res = getline(&lineBuffer, &lineSize, fp);
+ saved_errno = errno;
+
+ /* Should free lineBuffer no matter result, according to man page */
+ if (lineBuffer != NULL)
+ free(lineBuffer);
+
+ if (feof(fp))
+ return -1;
+
+ /* On successfull return res >= 0, otherwise res is -1 */
+ if (res == -1)
+ throwUnixException(env, saved_errno);
+
+ if (res > INT_MAX)
+ throwUnixException(env, EOVERFLOW);
+
+ return (jint)res;
+}
+
JNIEXPORT jint JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_open0(JNIEnv* env, jclass this,
jlong pathAddress, jint oflags, jint mode)