summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2019-12-09 22:06:08 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-12-09 22:06:08 +0000
commitcb0a6bce7f491bffe7ac07eb4150c075d5b521a6 (patch)
tree30bb722a10cea2066eafce371a2c0b6458024575
parent20d3ddf2d44e86f7f45e161d35c2c56a7b1d312f (diff)
parent6cba93206ceb6d2fce64c78c4da29155021c6fe3 (diff)
Merge "Add memfd_create to android.system.Os"
-rw-r--r--luni/src/main/java/android/system/Os.java5
-rw-r--r--luni/src/main/java/android/system/OsConstants.java1
-rw-r--r--luni/src/main/java/libcore/io/ForwardingOs.java1
-rw-r--r--luni/src/main/java/libcore/io/Linux.java1
-rw-r--r--luni/src/main/java/libcore/io/Os.java1
-rw-r--r--luni/src/main/native/android_system_OsConstants.cpp3
-rw-r--r--luni/src/main/native/libcore_io_Linux.cpp16
-rw-r--r--luni/src/test/java/libcore/android/system/OsTest.java68
-rw-r--r--luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java1
9 files changed, 97 insertions, 0 deletions
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index cc6b0a56d5..4c258c69e2 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -362,6 +362,11 @@ public final class Os {
public static StructStat lstat(String path) throws ErrnoException { return Libcore.os.lstat(path); }
/**
+ * See <a href="http://man7.org/linux/man-pages/man2/memfd_create.2.html">memfd_create(2)</a>.
+ */
+ public static @NonNull FileDescriptor memfd_create(@NonNull String name, int flags) throws ErrnoException { return Libcore.os.memfd_create(name, flags); }
+
+ /**
* See <a href="http://man7.org/linux/man-pages/man2/mincore.2.html">mincore(2)</a>.
*/
public static void mincore(long address, long byteCount, byte[] vector) throws ErrnoException { Libcore.os.mincore(address, byteCount, vector); }
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 9daccc697d..d8745511c2 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -374,6 +374,7 @@ public final class OsConstants {
public static final int MCAST_UNBLOCK_SOURCE = placeholder();
public static final int MCL_CURRENT = placeholder();
public static final int MCL_FUTURE = placeholder();
+ public static final int MFD_CLOEXEC = placeholder();
public static final int MSG_CTRUNC = placeholder();
public static final int MSG_DONTROUTE = placeholder();
public static final int MSG_EOR = placeholder();
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index c82cbe0fa3..c75f94e4ad 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -150,6 +150,7 @@ public class ForwardingOs implements Os {
public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { return os.lseek(fd, offset, whence); }
@UnsupportedAppUsage
public StructStat lstat(String path) throws ErrnoException { return os.lstat(path); }
+ public FileDescriptor memfd_create(String name, int flags) throws ErrnoException { return os.memfd_create(name, flags); }
public void mincore(long address, long byteCount, byte[] vector) throws ErrnoException { os.mincore(address, byteCount, vector); }
@UnsupportedAppUsage
public void mkdir(String path, int mode) throws ErrnoException { os.mkdir(path, mode); }
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
index e2a4c548d4..74608d392a 100644
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -121,6 +121,7 @@ public final class Linux implements Os {
public native String[] listxattr(String path) throws ErrnoException;
public native long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException;
public native StructStat lstat(String path) throws ErrnoException;
+ public native FileDescriptor memfd_create(String name, int flags) throws ErrnoException;
public native void mincore(long address, long byteCount, byte[] vector) throws ErrnoException;
public native void mkdir(String path, int mode) throws ErrnoException;
public native void mkfifo(String path, int mode) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index a7bae10450..048a973778 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -123,6 +123,7 @@ public interface Os {
public String[] listxattr(String path) throws ErrnoException;
public long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException;
public StructStat lstat(String path) throws ErrnoException;
+ public FileDescriptor memfd_create(String name, int flags) throws ErrnoException;
public void mincore(long address, long byteCount, byte[] vector) throws ErrnoException;
public void mkdir(String path, int mode) throws ErrnoException;
public void mkfifo(String path, int mode) throws ErrnoException;
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 31ef37da3c..6cf2c8b30b 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -375,6 +375,9 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) {
#endif
initConstant(env, c, "MCL_CURRENT", MCL_CURRENT);
initConstant(env, c, "MCL_FUTURE", MCL_FUTURE);
+#if defined(MFD_CLOEXEC)
+ initConstant(env, c, "MFD_CLOEXEC", MFD_CLOEXEC);
+#endif
initConstant(env, c, "MSG_CTRUNC", MSG_CTRUNC);
initConstant(env, c, "MSG_DONTROUTE", MSG_DONTROUTE);
initConstant(env, c, "MSG_EOR", MSG_EOR);
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
index 805b32fb47..9e44e63fe4 100644
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -1837,6 +1837,21 @@ static jobject Linux_lstat(JNIEnv* env, jobject, jstring javaPath) {
return doStat(env, javaPath, true);
}
+static jobject Linux_memfd_create(JNIEnv* env, jobject, jstring javaName, jint flags) {
+#if defined(__BIONIC__)
+ ScopedUtfChars name(env, javaName);
+ if (name.c_str() == NULL) {
+ return NULL;
+ }
+
+ int fd = throwIfMinusOne(env, "memfd_create", memfd_create(name.c_str(), flags));
+ return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
+#else
+ UNUSED(env, javaName, flags);
+ return NULL;
+#endif
+}
+
static void Linux_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
ScopedByteArrayRW vector(env, javaVector);
if (vector.get() == NULL) {
@@ -2623,6 +2638,7 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Linux, listxattr, "(Ljava/lang/String;)[Ljava/lang/String;"),
NATIVE_METHOD(Linux, lseek, "(Ljava/io/FileDescriptor;JI)J"),
NATIVE_METHOD(Linux, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
+ NATIVE_METHOD(Linux, memfd_create, "(Ljava/lang/String;I)Ljava/io/FileDescriptor;"),
NATIVE_METHOD(Linux, mincore, "(JJ[B)V"),
NATIVE_METHOD(Linux, mkdir, "(Ljava/lang/String;I)V"),
NATIVE_METHOD(Linux, mkfifo, "(Ljava/lang/String;I)V"),
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
index a56ff000b9..25d56bcbc3 100644
--- a/luni/src/test/java/libcore/android/system/OsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -1481,4 +1481,72 @@ public class OsTest extends TestCase {
assertTrue(address > 0);
Os.munmap(address, size);
}
+
+ public void testMemfdCreate() throws Exception {
+ FileDescriptor fd = null;
+ try {
+ fd = Os.memfd_create("test_memfd", 0);
+ assertNotNull(fd);
+ assertTrue(fd.valid());
+
+ StructStat stat = Os.fstat(fd);
+ assertEquals(0, stat.st_size);
+
+ final byte[] expected = new byte[] {1, 2, 3, 4};
+ Os.write(fd, expected, 0, expected.length);
+ stat = Os.fstat(fd);
+ assertEquals(expected.length, stat.st_size);
+
+ byte[] actual = new byte[expected.length];
+ // should be seekable
+ Os.lseek(fd, 0, SEEK_SET);
+ Os.read(fd, actual, 0, actual.length);
+ assertArrayEquals(expected, actual);
+ } finally {
+ if (fd != null) {
+ Os.close(fd);
+ fd = null;
+ }
+ }
+ }
+
+ public void testMemfdCreateFlags() throws Exception {
+ FileDescriptor fd = null;
+
+ // test that MFD_CLOEXEC is obeyed
+ try {
+ fd = Os.memfd_create("test_memfd", 0);
+ assertNotNull(fd);
+ assertTrue(fd.valid());
+ int flags = Os.fcntlVoid(fd, F_GETFD);
+ assertTrue("Expected flags to not include " + FD_CLOEXEC + ", actual value: " + flags,
+ 0 == (flags & FD_CLOEXEC));
+ } finally {
+ if (fd != null) {
+ Os.close(fd);
+ fd = null;
+ }
+ }
+ try {
+ fd = Os.memfd_create("test_memfd", MFD_CLOEXEC);
+ assertNotNull(fd);
+ assertTrue(fd.valid());
+ int flags = Os.fcntlVoid(fd, F_GETFD);
+ assertTrue("Expected flags to include " + FD_CLOEXEC + ", actual value: " + flags,
+ 0 != (flags & FD_CLOEXEC));
+ } finally {
+ if (fd != null) {
+ Os.close(fd);
+ fd = null;
+ }
+ }
+ }
+
+ public void testMemfdCreateErrno() throws Exception {
+ expectException(() -> Os.memfd_create(null, 0), NullPointerException.class, null,
+ "memfd_create(null, 0)");
+
+ expectException(() -> Os.memfd_create("test_memfd", 0xffff), ErrnoException.class, EINVAL,
+ "memfd_create(\"test_memfd\", 0xffff)");
+ }
}
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 17f031be2a..218678ee56 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -226,6 +226,7 @@ public class BlockGuardOsTest {
"kill(int,int)",
"listen(java.io.FileDescriptor,int)",
"listxattr(java.lang.String)",
+ "memfd_create(java.lang.String,int)",
"mincore(long,long,byte[])",
"mlock(long,long)",
"mmap(long,long,int,int,java.io.FileDescriptor,long)",