summaryrefslogtreecommitdiffstats
path: root/luni/src/main
diff options
context:
space:
mode:
authorOliver Woodman <olly@google.com>2013-11-04 21:35:35 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-11-04 21:35:37 +0000
commit92918daeb43dbb9079f1f856c5a18329da82c15a (patch)
tree8797a4d3b446f6093a635c893f54bf1bcf857863 /luni/src/main
parent87093a8b17f669c5c1487549a43e2b811b6fafea (diff)
parent671a834be6d345a7df01ba19407dd1c96509c785 (diff)
downloadlibcore-92918daeb43dbb9079f1f856c5a18329da82c15a.zip
libcore-92918daeb43dbb9079f1f856c5a18329da82c15a.tar.gz
libcore-92918daeb43dbb9079f1f856c5a18329da82c15a.tar.bz2
Merge "Make getInetAddress generate less garbage." into klp-dev
Diffstat (limited to 'luni/src/main')
-rw-r--r--luni/src/main/java/java/net/NetworkInterface.java67
1 files changed, 47 insertions, 20 deletions
diff --git a/luni/src/main/java/java/net/NetworkInterface.java b/luni/src/main/java/java/net/NetworkInterface.java
index b35424d..3128b98 100644
--- a/luni/src/main/java/java/net/NetworkInterface.java
+++ b/luni/src/main/java/java/net/NetworkInterface.java
@@ -17,10 +17,8 @@
package java.net;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -28,7 +26,6 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
@@ -41,6 +38,8 @@ import static libcore.io.OsConstants.*;
* system or to identify the local interface of a joined multicast group.
*/
public final class NetworkInterface extends Object {
+ private static final File SYS_CLASS_NET = new File("/sys/class/net");
+
private final String name;
private final int interfaceIndex;
private final List<InterfaceAddress> interfaceAddresses;
@@ -110,17 +109,42 @@ public final class NetworkInterface extends Object {
return null;
}
+ return getByNameInternal(interfaceName, readIfInet6Lines());
+ }
+
+ /**
+ * Similar to {@link #getByName(String)} except that {@code interfaceName}
+ * is assumed to be valid.
+ */
+ private static NetworkInterface getByNameInternal(String interfaceName,
+ String[] ifInet6Lines) throws SocketException {
int interfaceIndex = readIntFile("/sys/class/net/" + interfaceName + "/ifindex");
List<InetAddress> addresses = new ArrayList<InetAddress>();
List<InterfaceAddress> interfaceAddresses = new ArrayList<InterfaceAddress>();
- collectIpv6Addresses(interfaceName, interfaceIndex, addresses, interfaceAddresses);
+
+ collectIpv6Addresses(interfaceName, interfaceIndex, addresses, interfaceAddresses,
+ ifInet6Lines);
collectIpv4Address(interfaceName, addresses, interfaceAddresses);
return new NetworkInterface(interfaceName, interfaceIndex, addresses, interfaceAddresses);
}
- private static void collectIpv6Addresses(String interfaceName, int interfaceIndex,
- List<InetAddress> addresses, List<InterfaceAddress> interfaceAddresses) throws SocketException {
+ private static String[] readIfInet6Lines() throws SocketException {
+ try {
+ return IoUtils.readFileAsString("/proc/net/if_inet6").split("\n");
+ } catch (IOException ioe) {
+ throw rethrowAsSocketException(ioe);
+ }
+ }
+
+ /**
+ * Visible for testing only.
+ *
+ * @hide
+ */
+ public static void collectIpv6Addresses(String interfaceName, int interfaceIndex,
+ List<InetAddress> addresses, List<InterfaceAddress> interfaceAddresses,
+ String[] ifInet6Lines) throws SocketException {
// Format of /proc/net/if_inet6.
// All numeric fields are implicit hex,
// but not necessarily two-digit (http://code.google.com/p/android/issues/detail?id=34022).
@@ -132,12 +156,9 @@ public final class NetworkInterface extends Object {
// 6. interface name
// "00000000000000000000000000000001 01 80 10 80 lo"
// "fe800000000000000000000000000000 407 40 20 80 wlan0"
- BufferedReader in = null;
+ final String suffix = " " + interfaceName;
try {
- in = new BufferedReader(new FileReader("/proc/net/if_inet6"));
- String suffix = " " + interfaceName;
- String line;
- while ((line = in.readLine()) != null) {
+ for (String line : ifInet6Lines) {
if (!line.endsWith(suffix)) {
continue;
}
@@ -160,10 +181,8 @@ public final class NetworkInterface extends Object {
addresses.add(inet6Address);
interfaceAddresses.add(new InterfaceAddress(inet6Address, prefixLength));
}
- } catch (Exception ex) {
+ } catch (NumberFormatException ex) {
throw rethrowAsSocketException(ex);
- } finally {
- IoUtils.closeQuietly(in);
}
}
@@ -197,8 +216,14 @@ public final class NetworkInterface extends Object {
@FindBugsSuppressWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
private static boolean isValidInterfaceName(String interfaceName) {
+ final String[] interfaceList = SYS_CLASS_NET.list();
+ // We have no interfaces listed under /sys/class/net
+ if (interfaceList == null) {
+ return false;
+ }
+
// Don't just stat because a crafty user might have / or .. in the supposed interface name.
- for (String validName : new File("/sys/class/net").list()) {
+ for (String validName : interfaceList) {
if (interfaceName.equals(validName)) {
return true;
}
@@ -275,11 +300,13 @@ public final class NetworkInterface extends Object {
@FindBugsSuppressWarnings("DMI_HARDCODED_ABSOLUTE_FILENAME")
private static List<NetworkInterface> getNetworkInterfacesList() throws SocketException {
- String[] interfaceNames = new File("/sys/class/net").list();
+ String[] interfaceNames = SYS_CLASS_NET.list();
NetworkInterface[] interfaces = new NetworkInterface[interfaceNames.length];
boolean[] done = new boolean[interfaces.length];
+
+ String[] ifInet6Lines = readIfInet6Lines();
for (int i = 0; i < interfaceNames.length; ++i) {
- interfaces[i] = NetworkInterface.getByName(interfaceNames[i]);
+ interfaces[i] = NetworkInterface.getByNameInternal(interfaceNames[i], ifInet6Lines);
// http://b/5833739: getByName can return null if the interface went away between our
// readdir(2) and our stat(2), so mark interfaces that disappeared as 'done'.
if (interfaces[i] == null) {
@@ -293,9 +320,9 @@ public final class NetworkInterface extends Object {
if (done[counter]) {
continue;
}
- int counter2 = counter;
+
// Checks whether the following interfaces are children.
- for (; counter2 < interfaces.length; counter2++) {
+ for (int counter2 = counter; counter2 < interfaces.length; counter2++) {
if (done[counter2]) {
continue;
}
@@ -304,7 +331,7 @@ public final class NetworkInterface extends Object {
interfaces[counter2].parent = interfaces[counter];
interfaces[counter].addresses.addAll(interfaces[counter2].addresses);
done[counter2] = true;
- }
+ }
}
result.add(interfaces[counter]);
done[counter] = true;