summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dalvik/src/main/java/dalvik/system/DexPathList.java47
-rw-r--r--luni/src/main/java/java/lang/Runtime.java4
-rw-r--r--luni/src/main/java/libcore/io/IoUtils.java16
3 files changed, 36 insertions, 31 deletions
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index 1253223..048cc83 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -25,6 +25,11 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.regex.Pattern;
import java.util.zip.ZipFile;
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.io.StructStat;
+import static libcore.io.OsConstants.*;
/**
* A pair of lists of entries, associated with a {@code ClassLoader}.
@@ -154,36 +159,20 @@ import java.util.zip.ZipFile;
* Helper for {@link #splitPaths}, which does the actual splitting
* and filtering and adding to a result.
*/
- private static void splitAndAdd(String path, boolean wantDirectories,
+ private static void splitAndAdd(String searchPath, boolean wantDirectories,
ArrayList<File> resultList) {
- if (path == null) {
+ if (searchPath == null) {
return;
}
-
- String[] strings = path.split(Pattern.quote(File.pathSeparator));
-
- for (String s : strings) {
- File file = new File(s);
-
- if (! (file.exists() && file.canRead())) {
- continue;
- }
-
- /*
- * Note: There are other entities in filesystems than
- * regular files and directories.
- */
- if (wantDirectories) {
- if (!file.isDirectory()) {
- continue;
- }
- } else {
- if (!file.isFile()) {
- continue;
+ for (String path : searchPath.split(":")) {
+ try {
+ StructStat sb = Libcore.os.stat(path);
+ if ((wantDirectories && S_ISDIR(sb.st_mode)) ||
+ (!wantDirectories && S_ISREG(sb.st_mode))) {
+ resultList.add(new File(path));
}
+ } catch (ErrnoException ignored) {
}
-
- resultList.add(file);
}
}
@@ -370,14 +359,12 @@ import java.util.zip.ZipFile;
*/
public String findLibrary(String libraryName) {
String fileName = System.mapLibraryName(libraryName);
-
for (File directory : nativeLibraryDirectories) {
- File file = new File(directory, fileName);
- if (file.exists() && file.isFile() && file.canRead()) {
- return file.getPath();
+ String path = new File(directory, fileName).getPath();
+ if (IoUtils.canOpenReadOnly(path)) {
+ return path;
}
}
-
return null;
}
diff --git a/luni/src/main/java/java/lang/Runtime.java b/luni/src/main/java/java/lang/Runtime.java
index c4c12db..58142d3 100644
--- a/luni/src/main/java/java/lang/Runtime.java
+++ b/luni/src/main/java/java/lang/Runtime.java
@@ -44,6 +44,7 @@ import java.lang.ref.FinalizerReference;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
+import libcore.io.IoUtils;
import libcore.io.Libcore;
import static libcore.io.OsConstants._SC_NPROCESSORS_CONF;
@@ -372,7 +373,8 @@ public class Runtime {
for (String directory : mLibPaths) {
String candidate = directory + filename;
candidates.add(candidate);
- if (new File(candidate).exists()) {
+
+ if (IoUtils.canOpenReadOnly(candidate)) {
String error = nativeLoad(candidate, loader);
if (error == null) {
return; // We successfully loaded the library. Job done.
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index 7177f3f..0373ea9 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -147,6 +147,22 @@ public final class IoUtils {
}
}
+ /**
+ * Checks whether {@code path} can be opened read-only. Similar to File.exists, but doesn't
+ * require read permission on the parent, so it'll work in more cases, and allow you to
+ * remove read permission from more directories.
+ */
+ public static boolean canOpenReadOnly(String path) {
+ try {
+ // Use open(2) rather than stat(2) so we require fewer permissions. http://b/6485312.
+ FileDescriptor fd = Libcore.os.open(path, O_RDONLY, 0);
+ Libcore.os.close(fd);
+ return true;
+ } catch (ErrnoException errnoException) {
+ return false;
+ }
+ }
+
public static void throwInterruptedIoException() throws InterruptedIOException {
// This is typically thrown in response to an
// InterruptedException which does not leave the thread in an