changeset 9197:902aa2b3265c

8031581: PPC64: Addons and fixes for AIX to pass the jdk regression tests Reviewed-by: alanb, sla
author simonis
date Mon, 20 Jan 2014 17:16:05 +0100
parents 4231d71b18cf
children f86763a9c959
files make/CompileJavaClasses.gmk src/aix/classes/sun/nio/ch/sctp/SctpChannelImpl.java src/aix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java src/aix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java src/aix/native/java/net/aix_close.c src/share/classes/java/nio/file/CopyMoveHelper.java src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider src/share/native/java/util/zip/zip_util.c src/share/native/sun/management/DiagnosticCommandImpl.c src/share/transport/socket/socketTransport.c src/solaris/classes/java/lang/UNIXProcess.java.aix src/solaris/native/java/net/NetworkInterface.c src/solaris/native/java/net/net_util_md.c src/solaris/native/sun/management/OperatingSystemImpl.c src/solaris/native/sun/nio/ch/DatagramChannelImpl.c src/solaris/native/sun/nio/ch/FileDispatcherImpl.c src/solaris/native/sun/nio/ch/Net.c
diffstat 18 files changed, 596 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/make/CompileJavaClasses.gmk	Mon Jan 20 09:24:25 2014 +0100
+++ b/make/CompileJavaClasses.gmk	Mon Jan 20 17:16:05 2014 +0100
@@ -228,9 +228,9 @@
 # Exclude another implicitly not included file.
 EXFILES += sun/util/locale/AsciiUtil.java
 
-ifeq (, $(filter $(OPENJDK_TARGET_OS), solaris macosx))
+ifeq (, $(filter $(OPENJDK_TARGET_OS), solaris macosx aix))
   #
-  # only solaris and macosx
+  # only solaris, macosx and aix
   #
   EXFILES += sun/nio/fs/PollingWatchService.java
 endif
@@ -308,6 +308,11 @@
 AIX_SRC_DIRS :=
 ifeq ($(OPENJDK_TARGET_OS),aix)
      AIX_SRC_DIRS += $(JDK_TOPDIR)/src/aix/classes
+
+  # these files are duplicated in AIX_SRC_DIRS
+  EXFILES += $(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java \
+      $(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java \
+      $(JDK_TOPDIR)/src/solaris/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java
 endif
 
 # The exception handling of swing beaninfo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aix/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Mon Jan 20 17:16:05 2014 +0100
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2009, 2012, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetAddress;
+import java.io.IOException;
+import java.util.Set;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.NotificationHandler;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+
+/**
+ * Unimplemented.
+ */
+public class SctpChannelImpl extends SctpChannel
+{
+    private static final String message = "SCTP not supported on this platform";
+
+    public SctpChannelImpl(SelectorProvider provider) {
+        super(provider);
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Association association() {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpChannel bind(SocketAddress local)
+                            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpChannel bindAddress(InetAddress address)
+         throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpChannel unbindAddress(InetAddress address)
+         throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public boolean connect(SocketAddress remote) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public boolean connect(SocketAddress remote, int maxOutStreams,
+       int maxInStreams) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public boolean isConnectionPending() {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public boolean finishConnect() throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SocketAddress> getAllLocalAddresses()
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SocketAddress> getRemoteAddresses()
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpChannel shutdown() throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> T getOption(SctpSocketOption<T> name)
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
+        throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SctpSocketOption<?>> supportedOptions() {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> MessageInfo receive(ByteBuffer dst, T attachment,
+            NotificationHandler<T> handler) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public int send(ByteBuffer src, MessageInfo messageInfo)
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    protected void implConfigureBlocking(boolean block) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public void implCloseSelectableChannel() throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Mon Jan 20 17:16:05 2014 +0100
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2009, 2012, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetAddress;
+import java.io.IOException;
+import java.util.Set;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.Association;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.MessageInfo;
+import com.sun.nio.sctp.NotificationHandler;
+import com.sun.nio.sctp.SctpMultiChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+
+/**
+ * Unimplemented.
+ */
+public class SctpMultiChannelImpl extends SctpMultiChannel
+{
+    private static final String message = "SCTP not supported on this platform";
+
+    public SctpMultiChannelImpl(SelectorProvider provider) {
+        super(provider);
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<Association> associations() {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpMultiChannel bind(SocketAddress local,
+            int backlog) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpMultiChannel bindAddress(InetAddress address)
+         throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpMultiChannel unbindAddress(InetAddress address)
+         throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SocketAddress> getAllLocalAddresses()
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SocketAddress> getRemoteAddresses
+            (Association association) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpMultiChannel shutdown(Association association)
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> T getOption(SctpSocketOption<T> name,
+            Association association) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
+            T value, Association association) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SctpSocketOption<?>> supportedOptions() {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> MessageInfo receive(ByteBuffer buffer, T attachment,
+            NotificationHandler<T> handler) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public int send(ByteBuffer buffer, MessageInfo messageInfo)
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpChannel branch(Association association)
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    protected void implConfigureBlocking(boolean block) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public void implCloseSelectableChannel() throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/aix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java	Mon Jan 20 17:16:05 2014 +0100
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, 2012, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.nio.ch.sctp;
+
+import java.net.SocketAddress;
+import java.net.InetAddress;
+import java.io.IOException;
+import java.util.Set;
+import java.nio.channels.spi.SelectorProvider;
+import com.sun.nio.sctp.SctpChannel;
+import com.sun.nio.sctp.SctpServerChannel;
+import com.sun.nio.sctp.SctpSocketOption;
+
+/**
+ * Unimplemented.
+ */
+public class SctpServerChannelImpl extends SctpServerChannel
+{
+    private static final String message = "SCTP not supported on this platform";
+
+    public SctpServerChannelImpl(SelectorProvider provider) {
+        super(provider);
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpChannel accept() throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpServerChannel bind(SocketAddress local,
+            int backlog) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpServerChannel bindAddress(InetAddress address)
+         throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public SctpServerChannel unbindAddress(InetAddress address)
+         throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SocketAddress> getAllLocalAddresses()
+            throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> T getOption(SctpSocketOption<T> name) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public <T> SctpServerChannel setOption(SctpSocketOption<T> name,
+            T value) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public Set<SctpSocketOption<?>> supportedOptions() {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    protected void implConfigureBlocking(boolean block) throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+
+    @Override
+    public void implCloseSelectableChannel() throws IOException {
+        throw new UnsupportedOperationException(message);
+    }
+}
--- a/src/aix/native/java/net/aix_close.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/aix/native/java/net/aix_close.c	Mon Jan 20 17:16:05 2014 +0100
@@ -234,6 +234,28 @@
     pthread_mutex_lock(&(fdEntry->lock));
 
     {
+        /* On fast machines we see that we enter dup2 before the
+         * accepting thread had a chance to get and process the signal.
+         * So in case we woke a thread up, give it some time to cope.
+         * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */
+        int num_woken = 0;
+
+        /*
+         * Send a wakeup signal to all threads blocked on this
+         * file descriptor.
+         */
+        threadEntry_t *curr = fdEntry->threads;
+        while (curr != NULL) {
+            curr->intr = 1;
+            pthread_kill( curr->thr, sigWakeup );
+            num_woken ++;
+            curr = curr->next;
+        }
+
+        if (num_woken > 0) {
+          usleep(num_woken * 50);
+        }
+
         /*
          * And close/dup the file descriptor
          * (restart if interrupted by signal)
@@ -245,17 +267,6 @@
                 rv = dup2(fd1, fd2);
             }
         } while (rv == -1 && errno == EINTR);
-
-        /*
-         * Send a wakeup signal to all threads blocked on this
-         * file descriptor.
-         */
-        threadEntry_t *curr = fdEntry->threads;
-        while (curr != NULL) {
-            curr->intr = 1;
-            pthread_kill( curr->thr, sigWakeup );
-            curr = curr->next;
-        }
     }
 
     /*
--- a/src/share/classes/java/nio/file/CopyMoveHelper.java	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/share/classes/java/nio/file/CopyMoveHelper.java	Mon Jan 20 17:16:05 2014 +0100
@@ -130,7 +130,7 @@
         // copy basic attributes to target
         if (opts.copyAttributes) {
             BasicFileAttributeView view =
-                Files.getFileAttributeView(target, BasicFileAttributeView.class, linkOptions);
+                Files.getFileAttributeView(target, BasicFileAttributeView.class);
             try {
                 view.setTimes(attrs.lastModifiedTime(),
                               attrs.lastAccessTime(),
--- a/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/share/classes/sun/nio/cs/ext/ExtendedCharsets.java	Mon Jan 20 17:16:05 2014 +0100
@@ -1297,7 +1297,7 @@
         }
         String osName = AccessController.doPrivileged(
             new GetPropertyAction("os.name"));
-        if ("SunOS".equals(osName) || "Linux".equals(osName)
+        if ("SunOS".equals(osName) || "Linux".equals(osName) || "AIX".equals(osName)
                || osName.contains("OS X")) {
             charset("x-COMPOUND_TEXT", "COMPOUND_TEXT",
                     new String[] {
--- a/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/share/classes/sun/tools/attach/META-INF/services/com.sun.tools.attach.spi.AttachProvider	Mon Jan 20 17:16:05 2014 +0100
@@ -31,3 +31,4 @@
 #[windows]sun.tools.attach.WindowsAttachProvider
 #[linux]sun.tools.attach.LinuxAttachProvider
 #[macosx]sun.tools.attach.BsdAttachProvider
+#[aix]sun.tools.attach.AixAttachProvider
--- a/src/share/native/java/util/zip/zip_util.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/share/native/java/util/zip/zip_util.c	Mon Jan 20 17:16:05 2014 +0100
@@ -659,7 +659,10 @@
     entries  = zip->entries  = calloc(total, sizeof(entries[0]));
     tablelen = zip->tablelen = ((total/2) | 1); // Odd -> fewer collisions
     table    = zip->table    = malloc(tablelen * sizeof(table[0]));
-    if (entries == NULL || table == NULL) goto Catch;
+    /* According to ISO C it is perfectly legal for malloc to return zero
+     * if called with a zero argument. We check this for 'entries' but not
+     * for 'table' because 'tablelen' can't be zero (see computation above). */
+    if ((entries == NULL && total != 0) || table == NULL) goto Catch;
     for (j = 0; j < tablelen; j++)
         table[j] = ZIP_ENDCHAIN;
 
--- a/src/share/native/sun/management/DiagnosticCommandImpl.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/share/native/sun/management/DiagnosticCommandImpl.c	Mon Jan 20 17:16:05 2014 +0100
@@ -23,6 +23,7 @@
  * questions.
  */
 
+#include <stdlib.h>
 #include <jni.h>
 #include "management.h"
 #include "sun_management_DiagnosticCommandImpl.h"
@@ -56,7 +57,8 @@
   jobject resultList;
 
   dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
-  if (dcmd_arg_info_array == NULL) {
+  /* According to ISO C it is perfectly legal for malloc to return zero if called with a zero argument */
+  if (dcmd_arg_info_array == NULL && num_arg != 0) {
     return NULL;
   }
   jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
@@ -117,19 +119,22 @@
       return NULL;
   }
   num_commands = (*env)->GetArrayLength(env, commands);
-  dcmd_info_array = (dcmdInfo*) malloc(num_commands *
-                                       sizeof(dcmdInfo));
+  dcmdInfoCls = (*env)->FindClass(env,
+                                  "sun/management/DiagnosticCommandInfo");
+  result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
+  if (result == NULL) {
+      JNU_ThrowOutOfMemoryError(env, 0);
+  }
+  if (num_commands == 0) {
+      /* Handle the 'zero commands' case specially to avoid calling 'malloc()' */
+      /* with a zero argument because that may legally return a NULL pointer.  */
+      return result;
+  }
+  dcmd_info_array = (dcmdInfo*) malloc(num_commands * sizeof(dcmdInfo));
   if (dcmd_info_array == NULL) {
       JNU_ThrowOutOfMemoryError(env, NULL);
   }
   jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
-  dcmdInfoCls = (*env)->FindClass(env,
-                                  "sun/management/DiagnosticCommandInfo");
-  result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
-  if (result == NULL) {
-      free(dcmd_info_array);
-      JNU_ThrowOutOfMemoryError(env, 0);
-  }
   for (i=0; i<num_commands; i++) {
       args = getDiagnosticCommandArgumentInfoArray(env,
                                                    (*env)->GetObjectArrayElement(env,commands,i),
--- a/src/share/transport/socket/socketTransport.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/share/transport/socket/socketTransport.c	Mon Jan 20 17:16:05 2014 +0100
@@ -506,6 +506,19 @@
     if (fd < 0) {
         return JDWPTRANSPORT_ERROR_NONE;
     }
+#ifdef _AIX
+    /*
+      AIX needs a workaround for I/O cancellation, see:
+      http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm
+      ...
+      The close subroutine is blocked until all subroutines which use the file
+      descriptor return to usr space. For example, when a thread is calling close
+      and another thread is calling select with the same file descriptor, the
+      close subroutine does not return until the select call returns.
+      ...
+    */
+    shutdown(fd, 2);
+#endif
     if (dbgsysSocketClose(fd) < 0) {
         /*
          * close failed - it's pointless to restore socketFD here because
--- a/src/solaris/classes/java/lang/UNIXProcess.java.aix	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/classes/java/lang/UNIXProcess.java.aix	Mon Jan 20 17:16:05 2014 +0100
@@ -338,9 +338,23 @@
      * This is tricky because we do not want the user-level InputStream to be
      * closed until the user invokes close(), and we need to continue to be
      * able to read any buffered data lingering in the OS pipe buffer.
+     *
+     * On AIX this is especially tricky, because the 'close()' system call
+     * will block if another thread is at the same time blocked in a file
+     * operation (e.g. 'read()') on the same file descriptor. We therefore
+     * combine this 'ProcessPipeInputStream' with the DeferredCloseInputStream
+     * approach used on Solaris (see "UNIXProcess.java.solaris"). This means
+     * that every potentially blocking operation on the file descriptor
+     * increments a counter before it is executed and decrements it once it
+     * finishes. The 'close()' operation will only be executed if there are
+     * no pending operations. Otherwise it is deferred after the last pending
+     * operation has finished.
+     *
      */
     static class ProcessPipeInputStream extends BufferedInputStream {
         private final Object closeLock = new Object();
+        private int useCount = 0;
+        private boolean closePending = false;
 
         ProcessPipeInputStream(int fd) {
             super(new FileInputStream(newFileDescriptor(fd)));
@@ -382,12 +396,83 @@
             } catch (IOException ignored) { }
         }
 
+        private void raise() {
+            synchronized (closeLock) {
+                useCount++;
+            }
+        }
+
+        private void lower() throws IOException {
+            synchronized (closeLock) {
+                useCount--;
+                if (useCount == 0 && closePending) {
+                    closePending = false;
+                    super.close();
+                }
+            }
+        }
+
+        @Override
+        public int read() throws IOException {
+            raise();
+            try {
+                return super.read();
+            } finally {
+                lower();
+            }
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            raise();
+            try {
+                return super.read(b);
+            } finally {
+                lower();
+            }
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            raise();
+            try {
+                return super.read(b, off, len);
+            } finally {
+                lower();
+            }
+        }
+
+        @Override
+        public long skip(long n) throws IOException {
+            raise();
+            try {
+                return super.skip(n);
+            } finally {
+                lower();
+            }
+        }
+
+        @Override
+        public int available() throws IOException {
+            raise();
+            try {
+                return super.available();
+            } finally {
+                lower();
+            }
+        }
+
         @Override
         public void close() throws IOException {
             // BufferedInputStream#close() is not synchronized unlike most other methods.
             // Synchronizing helps avoid racing with drainInputStream().
             synchronized (closeLock) {
-                super.close();
+                if (useCount == 0) {
+                    super.close();
+                }
+                else {
+                    closePending = true;
+                }
             }
         }
     }
--- a/src/solaris/native/java/net/NetworkInterface.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/native/java/net/NetworkInterface.c	Mon Jan 20 17:16:05 2014 +0100
@@ -1265,12 +1265,17 @@
         if (ifreqP->ifr_addr.sa_family != AF_INET6)
             continue;
 
+        if (ioctl(sock, SIOCGIFSITE6, (char *)&if2) >= 0) {
+            struct sockaddr_in6 *s6= (struct sockaddr_in6 *)&(ifreqP->ifr_addr);
+            s6->sin6_scope_id = if2.ifr_site6;
+        }
+
         /*
          * Add to the list
          */
         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
                     (struct sockaddr *)&(ifreqP->ifr_addr),
-                     AF_INET6, 0);
+                    AF_INET6, 0);
 
         /*
          * If an exception occurred then free the list
--- a/src/solaris/native/java/net/net_util_md.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/native/java/net/net_util_md.c	Mon Jan 20 17:16:05 2014 +0100
@@ -996,11 +996,7 @@
         { java_net_SocketOptions_SO_SNDBUF,             SOL_SOCKET,     SO_SNDBUF },
         { java_net_SocketOptions_SO_RCVBUF,             SOL_SOCKET,     SO_RCVBUF },
         { java_net_SocketOptions_SO_KEEPALIVE,          SOL_SOCKET,     SO_KEEPALIVE },
-#if defined(_AIX)
-        { java_net_SocketOptions_SO_REUSEADDR,          SOL_SOCKET,     SO_REUSEPORT },
-#else
         { java_net_SocketOptions_SO_REUSEADDR,          SOL_SOCKET,     SO_REUSEADDR },
-#endif
         { java_net_SocketOptions_SO_BROADCAST,          SOL_SOCKET,     SO_BROADCAST },
         { java_net_SocketOptions_IP_TOS,                IPPROTO_IP,     IP_TOS },
         { java_net_SocketOptions_IP_MULTICAST_IF,       IPPROTO_IP,     IP_MULTICAST_IF },
@@ -1285,6 +1281,7 @@
 NET_SetSockOpt(int fd, int level, int  opt, const void *arg,
                int len)
 {
+
 #ifndef IPTOS_TOS_MASK
 #define IPTOS_TOS_MASK 0x1e
 #endif
@@ -1305,9 +1302,6 @@
 #else
     static long maxsockbuf = -1;
 #endif
-
-    int addopt;
-    struct linger *ling;
 #endif
 
     /*
@@ -1479,10 +1473,12 @@
 
         }
     }
+#endif
 
+#if defined(_ALLBSD_SOURCE) || defined(_AIX)
     /*
      * On Solaris, SO_REUSEADDR will allow multiple datagram
-     * sockets to bind to the same port.  The network jck tests
+     * sockets to bind to the same port. The network jck tests check
      * for this "feature", so we need to emulate it by turning on
      * SO_REUSEPORT as well for that combination.
      */
@@ -1496,11 +1492,9 @@
         }
 
         if (sotype == SOCK_DGRAM) {
-            addopt = SO_REUSEPORT;
-            setsockopt(fd, level, addopt, arg, len);
+            setsockopt(fd, level, SO_REUSEPORT, arg, len);
         }
     }
-
 #endif
 
     return setsockopt(fd, level, opt, arg, len);
@@ -1670,7 +1664,7 @@
         if (timeout <= 0) {
           return read_rv > 0 ? 0 : -1;
         }
-        newTime = prevTime;
+        prevTime = newTime;
 
         if (read_rv > 0) {
           break;
--- a/src/solaris/native/sun/management/OperatingSystemImpl.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/native/sun/management/OperatingSystemImpl.c	Mon Jan 20 17:16:05 2014 +0100
@@ -433,7 +433,16 @@
     struct dirent* dentp;
     jlong fds = 0;
 
-    dirp = opendir("/proc/self/fd");
+#if defined(_AIX)
+/* AIX does not understand '/proc/self' - it requires the real process ID */
+#define FD_DIR aix_fd_dir
+    char aix_fd_dir[32];     /* the pid has at most 19 digits */
+    snprintf(aix_fd_dir, 32, "/proc/%d/fd", getpid());
+#else
+#define FD_DIR "/proc/self/fd"
+#endif
+
+    dirp = opendir(FD_DIR);
     if (dirp == NULL) {
         throw_internal_error(env, "Unable to open directory /proc/self/fd");
         return -1;
--- a/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c	Mon Jan 20 17:16:05 2014 +0100
@@ -81,7 +81,7 @@
     rv = connect(fd, 0, 0);
 #endif
 
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
     {
         int len;
         SOCKADDR sa;
@@ -115,6 +115,14 @@
         if (rv < 0 && errno == EADDRNOTAVAIL)
                 rv = errno = 0;
 #endif
+#if defined(_AIX)
+        /* See W. Richard Stevens, "UNIX Network Programming, Volume 1", p. 254:
+         * 'Setting the address family to AF_UNSPEC might return EAFNOSUPPORT
+         * but that is acceptable.
+         */
+        if (rv < 0 && errno == EAFNOSUPPORT)
+                rv = errno = 0;
+#endif
     }
 #endif
 
--- a/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c	Mon Jan 20 17:16:05 2014 +0100
@@ -147,6 +147,19 @@
     if (md == JNI_FALSE) {
         result = fdatasync(fd);
     } else {
+#ifdef _AIX
+        /* On AIX, calling fsync on a file descriptor that is opened only for
+         * reading results in an error ("EBADF: The FileDescriptor parameter is
+         * not a valid file descriptor open for writing.").
+         * However, at this point it is not possibly anymore to read the
+         * 'writable' attribute of the corresponding file channel so we have to
+         * use 'fcntl'.
+         */
+        int getfl = fcntl(fd, F_GETFL);
+        if (getfl >= 0 && (getfl & O_ACCMODE) == O_RDONLY) {
+            return 0;
+        }
+#endif
         result = fsync(fd);
     }
     return handle(env, result, "Force failed");
--- a/src/solaris/native/sun/nio/ch/Net.c	Mon Jan 20 09:24:25 2014 +0100
+++ b/src/solaris/native/sun/nio/ch/Net.c	Mon Jan 20 17:16:05 2014 +0100
@@ -104,12 +104,24 @@
 
 #endif /* IPV6_ADD_MEMBERSHIP */
 
+#if defined(_AIX)
+
+struct my_ip_mreq_source {
+        struct in_addr  imr_multiaddr;
+        struct in_addr  imr_sourceaddr;
+        struct in_addr  imr_interface;
+};
+
+#else
+
 struct my_ip_mreq_source {
         struct in_addr  imr_multiaddr;
         struct in_addr  imr_interface;
         struct in_addr  imr_sourceaddr;
 };
 
+#endif /* _AIX */
+
 struct my_group_source_req {
         uint32_t                gsr_interface;  /* interface index */
         struct sockaddr_storage gsr_group;      /* group address */
@@ -199,7 +211,7 @@
 JNIEXPORT jboolean JNICALL
 Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
 {
-#ifdef MACOSX
+#if defined(MACOSX) || defined(_AIX)
     /* for now IPv6 sockets cannot join IPv4 multicast groups */
     return JNI_FALSE;
 #else