diff --git a/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c b/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c index d3ee3279e54..e8a1623a87d 100644 --- a/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c +++ b/jdk/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c @@ -333,7 +333,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_dup(JNIEnv* env, jclass this, jint fd) { int res = -1; RESTARTABLE(dup((int)fd), res); - if (fd == -1) { + if (res == -1) { throwUnixException(env, errno); } return (jint)res; @@ -361,13 +361,14 @@ Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this, JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream) { - int res; FILE* fp = jlong_to_ptr(stream); - do { - res = fclose(fp); - } while (res == EOF && errno == EINTR); - if (res == EOF) { + /* NOTE: fclose() wrapper is only used with read-only streams. + * If it ever is used with write streams, it might be better to add + * RESTARTABLE(fflush(fp)) before closing, to make sure the stream + * is completely written even if fclose() failed. + */ + if (fclose(fp) == EOF && errno != EINTR) { throwUnixException(env, errno); } } @@ -675,11 +676,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_fdopendir(JNIEnv* env, jclass this, int dfd JNIEXPORT void JNICALL Java_sun_nio_fs_UnixNativeDispatcher_closedir(JNIEnv* env, jclass this, jlong dir) { - int err; DIR* dirp = jlong_to_ptr(dir); - RESTARTABLE(closedir(dirp), err); - if (errno == -1) { + if (closedir(dirp) == -1 && errno != EINTR) { throwUnixException(env, errno); } } diff --git a/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java b/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java index 1dd7927b5e0..fca338f5628 100644 --- a/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java +++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2014, 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 @@ -37,6 +37,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Semaphore; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; import javax.management.MBeanServerFactory; @@ -56,10 +58,12 @@ import javax.security.auth.Subject; public class NotificationAccessControllerTest { public class NAC implements NotificationAccessController { - private boolean throwException; + private final boolean throwException; public NAC(boolean throwException) { this.throwException = throwException; } + + @Override public void addNotificationListener( String connectionId, ObjectName name, @@ -72,10 +76,14 @@ public class NotificationAccessControllerTest { (subject == null ? null : subject.getPrincipals())); if (throwException) if (name.getCanonicalName().equals("domain:name=1,type=NB") + && + subject != null && subject.getPrincipals().contains(new JMXPrincipal("role"))) throw new SecurityException(); } + + @Override public void removeNotificationListener( String connectionId, ObjectName name, @@ -88,10 +96,14 @@ public class NotificationAccessControllerTest { (subject == null ? null : subject.getPrincipals())); if (throwException) if (name.getCanonicalName().equals("domain:name=2,type=NB") + && + subject != null && subject.getPrincipals().contains(new JMXPrincipal("role"))) throw new SecurityException(); } + + @Override public void fetchNotification( String connectionId, ObjectName name, @@ -105,13 +117,17 @@ public class NotificationAccessControllerTest { echo("\tsubject: " + (subject == null ? null : subject.getPrincipals())); if (!throwException) - if (name.getCanonicalName().equals("domain:name=2,type=NB") && + if (name.getCanonicalName().equals("domain:name=2,type=NB") + && + subject != null + && subject.getPrincipals().contains(new JMXPrincipal("role"))) throw new SecurityException(); } } public class CustomJMXAuthenticator implements JMXAuthenticator { + @Override public Subject authenticate(Object credentials) { String role = ((String[]) credentials)[0]; echo("\nCreate principal with name = " + role); @@ -129,6 +145,7 @@ public class NotificationAccessControllerTest { public static class NB extends NotificationBroadcasterSupport implements NBMBean { + @Override public void emitNotification(int seqnum, ObjectName name) { if (name == null) { sendNotification(new Notification("nb", this, seqnum)); @@ -139,13 +156,20 @@ public class NotificationAccessControllerTest { } public class Listener implements NotificationListener { - public List notifs = new ArrayList(); + public final List notifs = new CopyOnWriteArrayList<>(); + + private final Semaphore s; + public Listener(Semaphore s) { + this.s = s; + } + @Override public void handleNotification(Notification n, Object h) { echo("handleNotification:"); echo("\tNotification = " + n); echo("\tNotification.SeqNum = " + n.getSequenceNumber()); echo("\tHandback = " + h); notifs.add(n); + s.release(); } } @@ -192,6 +216,17 @@ public class NotificationAccessControllerTest { JMXConnectorServer server = null; JMXConnector client = null; + /* + * (!enableChecks) + * - List must contain three notifs from sources nb1, nb2 and nb3 + * (enableChecks && !throwException) + * - List must contain one notif from source nb1 + * (enableChecks && throwException) + * - List must contain two notifs from sources nb2 and nb3 + */ + final int expected_notifs = + (!enableChecks ? 3 : (throwException ? 2 : 1)); + // Create a new MBeanServer // final MBeanServer mbs = MBeanServerFactory.createMBeanServer(); @@ -199,7 +234,7 @@ public class NotificationAccessControllerTest { try { // Create server environment map // - final Map env = new HashMap(); + final Map env = new HashMap<>(); env.put("jmx.remote.authenticator", new CustomJMXAuthenticator()); if (enableChecks) { env.put("com.sun.jmx.remote.notification.access.controller", @@ -222,7 +257,7 @@ public class NotificationAccessControllerTest { // Create server environment map // - final Map cenv = new HashMap(); + final Map cenv = new HashMap<>(); String[] credentials = new String[] { "role" , "password" }; cenv.put("jmx.remote.credentials", credentials); @@ -246,7 +281,9 @@ public class NotificationAccessControllerTest { // Add notification listener // - Listener li = new Listener(); + Semaphore s = new Semaphore(0); + + Listener li = new Listener(s); try { mbsc.addNotificationListener(nb1, li, null, null); if (enableChecks && throwException) { @@ -263,6 +300,9 @@ public class NotificationAccessControllerTest { } mbsc.addNotificationListener(nb2, li, null, null); + System.out.println("\n+++ Expecting to receive " + expected_notifs + + " notification" + (expected_notifs > 1 ? "s" : "") + + " +++"); // Invoke the "sendNotification" method // mbsc.invoke(nb1, "emitNotification", @@ -277,7 +317,7 @@ public class NotificationAccessControllerTest { // Wait for notifications to be emitted // - Thread.sleep(2000); + s.acquire(expected_notifs); // Remove notification listener // @@ -303,21 +343,7 @@ public class NotificationAccessControllerTest { sources.add(nb1); sources.add(nb2); sources.add(nb3); - if (!enableChecks) { - // List must contain three notifs from sources nb1, nb2 and nb3 - // - result = checkNotifs(3, li.notifs, sources); - } - if (enableChecks && !throwException) { - // List must contain one notif from source nb1 - // - result = checkNotifs(1, li.notifs, sources); - } - if (enableChecks && throwException) { - // List must contain two notifs from sources nb2 and nb3 - // - result = checkNotifs(2, li.notifs, sources); - } + result = checkNotifs(expected_notifs, li.notifs, sources); if (result > 0) { return result; }