Merge "Check for leniency of calendar in getDisplayNames"
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 3a24856..1df80da 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -246,6 +246,7 @@
     public static final int FD_CLOEXEC = placeholder();
     public static final int FIONREAD = placeholder();
     public static final int F_DUPFD = placeholder();
+    /** @hide */ public static final int F_DUPFD_CLOEXEC = placeholder();
     public static final int F_GETFD = placeholder();
     public static final int F_GETFL = placeholder();
     public static final int F_GETLK = placeholder();
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index fb912a7..4e85908 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -218,6 +218,7 @@
     initConstant(env, c, "FD_CLOEXEC", FD_CLOEXEC);
     initConstant(env, c, "FIONREAD", FIONREAD);
     initConstant(env, c, "F_DUPFD", F_DUPFD);
+    initConstant(env, c, "F_DUPFD_CLOEXEC", F_DUPFD_CLOEXEC);
     initConstant(env, c, "F_GETFD", F_GETFD);
     initConstant(env, c, "F_GETFL", F_GETFL);
     initConstant(env, c, "F_GETLK", F_GETLK);
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 1e87223..57facc5 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -28,6 +28,7 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.net.SocketImpl;
+import java.net.UnknownHostException;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
 import java.util.concurrent.Callable;
@@ -447,4 +448,62 @@
             executor.shutdown();
         }
     }
+
+    // b/26354315
+    public void testDoNotCallCloseFromSocketCtor() {
+        // Original openJdk7 Socket implementation may call Socket#close() inside a constructor.
+        // In this case, classes that extend Socket wont be fully constructed when they
+        // receive #close() call. This test makes sure this won't happen
+
+        // Extend Socket
+        class SocketThatFailOnClose extends Socket {
+            public SocketThatFailOnClose(String host, int port)
+                throws UnknownHostException, IOException {
+                super(host, port);
+            }
+            public SocketThatFailOnClose(InetAddress address, int port) throws IOException {
+                super(address, port);
+            }
+            public SocketThatFailOnClose(String host, int port, InetAddress localAddr,
+                                         int localPort) throws IOException {
+                super(host, port, localAddr, localPort);
+            }
+            public SocketThatFailOnClose(InetAddress address, int port, InetAddress localAddr,
+                                         int localPort) throws IOException {
+                super(address, port, localAddr, localPort);
+            }
+            public SocketThatFailOnClose(String host, int port, boolean stream) throws IOException {
+                super(host, port, stream);
+            }
+            public SocketThatFailOnClose(InetAddress host, int port, boolean stream)
+                throws IOException {
+                super(host, port, stream);
+            }
+
+            @Override
+            public void close() {
+                fail("Do not call close from the Socket constructor");
+            }
+        }
+
+        // Test all Socket ctors
+        try {
+            new SocketThatFailOnClose("localhost", 1);
+        } catch(IOException expected) {}
+        try {
+            new SocketThatFailOnClose(InetAddress.getLocalHost(), 1);
+        } catch(IOException expected) {}
+        try {
+            new SocketThatFailOnClose("localhost", 1, null, 0);
+        } catch(IOException expected) {}
+        try {
+            new SocketThatFailOnClose(InetAddress.getLocalHost(), 1, null, 0);
+        } catch(IOException expected) {}
+        try {
+            new SocketThatFailOnClose("localhost", 1, true);
+        } catch(IOException expected) {}
+        try {
+            new SocketThatFailOnClose(InetAddress.getLocalHost(), 1, true);
+        } catch(IOException expected) {}
+    }
 }
diff --git a/ojluni/src/main/java/java/io/FileDescriptor.java b/ojluni/src/main/java/java/io/FileDescriptor.java
index f858e27..8da266b 100755
--- a/ojluni/src/main/java/java/io/FileDescriptor.java
+++ b/ojluni/src/main/java/java/io/FileDescriptor.java
@@ -25,6 +25,10 @@
 
 package java.io;
 
+import android.system.ErrnoException;
+import android.system.Os;
+import static android.system.OsConstants.F_DUPFD_CLOEXEC;
+
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -74,7 +78,7 @@
      *
      * @see     java.lang.System#in
      */
-    public static final FileDescriptor in = new FileDescriptor(0);
+    public static final FileDescriptor in = dupFd(0);
 
     /**
      * A handle to the standard output stream. Usually, this file
@@ -82,7 +86,7 @@
      * known as <code>System.out</code>.
      * @see     java.lang.System#out
      */
-    public static final FileDescriptor out = new FileDescriptor(1);
+    public static final FileDescriptor out = dupFd(1);
 
     /**
      * A handle to the standard error stream. Usually, this file
@@ -91,7 +95,7 @@
      *
      * @see     java.lang.System#err
      */
-    public static final FileDescriptor err = new FileDescriptor(2);
+    public static final FileDescriptor err = dupFd(2);
 
     /**
      * Tests if this file descriptor object is valid.
@@ -169,6 +173,15 @@
         return isSocket(descriptor);
     }
 
+    // Android-added.
+    private static FileDescriptor dupFd(int fd) {
+        try {
+            return new FileDescriptor(Os.fcntlInt(new FileDescriptor(fd), F_DUPFD_CLOEXEC, 0));
+        } catch (ErrnoException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     private static native boolean isSocket(int descriptor);
 
     // package private methods used by FIS, FOS and RAF
diff --git a/ojluni/src/main/java/java/net/Socket.java b/ojluni/src/main/java/java/net/Socket.java
index 72f7469..2aa057f 100755
--- a/ojluni/src/main/java/java/net/Socket.java
+++ b/ojluni/src/main/java/java/net/Socket.java
@@ -426,7 +426,12 @@
             if (address != null)
                 connect(address);
         } catch (IOException e) {
-            close();
+            // Do not call #close, classes that extend this class may do not expect a call
+            // to #close coming from the superclass constructor.
+            if (impl != null) {
+                impl.close();
+            }
+            closed = true;
             throw e;
         }
     }
diff --git a/ojluni/src/main/java/java/net/URI.java b/ojluni/src/main/java/java/net/URI.java
index 8c2b9b4..82b8cb6 100755
--- a/ojluni/src/main/java/java/net/URI.java
+++ b/ojluni/src/main/java/java/net/URI.java
@@ -2612,6 +2612,10 @@
     private static final long L_DASH = lowMask("-");
     private static final long H_DASH = highMask("-");
 
+    // UNDERSCORE, for use in domainlabel and toplabel
+    private static final long L_UNDERSCORE = lowMask("_");
+    private static final long H_UNDERSCORE = highMask("_");
+
     // Dot, for use in hostnames
     private static final long L_DOT = lowMask(".");
     private static final long H_DOT = highMask(".");
@@ -3371,8 +3375,8 @@
         }
 
         // hostname      = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
-        // domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
-        // toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
+        // domainlabel   = alphanum | alphanum *( alphanum | "-" | "_" ) alphanum
+        // toplabel      = alpha | alpha *( alphanum | "-" | "_" ) alphanum
         //
         private int parseHostname(int start, int n)
             throws URISyntaxException
@@ -3382,14 +3386,21 @@
             int l = -1;                 // Start of last parsed label
 
             do {
-                // domainlabel = alphanum [ *( alphanum | "-" ) alphanum ]
+                // domainlabel = alphanum [ *( alphanum | "-" | "_" ) alphanum ]
+                //
+                // The RFCs don't permit underscores in hostnames, but URI has to because a certain
+                // large website doesn't seem to care about standards and specs.
+                // http://code.google.com/p/android/issues/detail?id=37577
+                // http://b/17579865
+                // http://b/18016625
+                // http://b/18023709
                 q = scan(p, n, L_ALPHANUM, H_ALPHANUM);
                 if (q <= p)
                     break;
                 l = p;
                 if (q > p) {
                     p = q;
-                    q = scan(p, n, L_ALPHANUM | L_DASH, H_ALPHANUM | H_DASH);
+                    q = scan(p, n, L_ALPHANUM | L_DASH | L_UNDERSCORE, H_ALPHANUM | H_DASH | H_UNDERSCORE);
                     if (q > p) {
                         if (charAt(q - 1) == '-')
                             fail("Illegal character in hostname", q - 1);
diff --git a/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java b/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java
index 37c1d5b..8fcfae6 100755
--- a/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java
@@ -32,7 +32,6 @@
 
     static {
         Util.load();
-        init();
     }
 
     FileDispatcherImpl(boolean append) {
@@ -148,6 +147,4 @@
 
     static native void closeIntFD(int fd) throws IOException;
 
-    static native void init();
-
 }
diff --git a/ojluni/src/main/native/FileDispatcherImpl.c b/ojluni/src/main/native/FileDispatcherImpl.c
index 2533b3a..80413f4 100755
--- a/ojluni/src/main/native/FileDispatcherImpl.c
+++ b/ojluni/src/main/native/FileDispatcherImpl.c
@@ -56,22 +56,6 @@
 #define fdatasync fsync
 #endif
 
-static int preCloseFD = -1;     /* File descriptor to which we dup other fd's
-                                   before closing them for real */
-
-
-JNIEXPORT void JNICALL
-FileDispatcherImpl_init(JNIEnv *env, jclass cl)
-{
-    int sp[2];
-    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
-        return;
-    }
-    preCloseFD = sp[0];
-    close(sp[1]);
-}
-
 JNIEXPORT jint JNICALL
 FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,
                              jobject fdo, jlong address, jint len)
@@ -256,11 +240,15 @@
 FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
 {
     jint fd = fdval(env, fdo);
-    if (preCloseFD >= 0) {
-        if (dup2(preCloseFD, fd) < 0) {
-            JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
-        }
+    int preCloseFD = open("/dev/null", O_RDWR | O_CLOEXEC);
+    if (preCloseFD < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "open(\"/dev/null\") failed");
+        return;
     }
+    if (dup2(preCloseFD, fd) < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
+    }
+    close(preCloseFD);
 }
 
 JNIEXPORT void JNICALL
@@ -284,7 +272,6 @@
   NATIVE_METHOD(FileDispatcherImpl, readv0, "(Ljava/io/FileDescriptor;JI)J"),
   NATIVE_METHOD(FileDispatcherImpl, pread0, "(Ljava/io/FileDescriptor;JIJ)I"),
   NATIVE_METHOD(FileDispatcherImpl, read0, "(Ljava/io/FileDescriptor;JI)I"),
-  NATIVE_METHOD(FileDispatcherImpl, init, "()V"),
 };
 
 void register_sun_nio_ch_FileDispatcherImpl(JNIEnv* env) {