This commit is contained in:
Michael McMahon 2014-08-26 15:18:38 +01:00
commit 545500cc52
2 changed files with 57 additions and 32 deletions

View File

@ -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);
}
}

View File

@ -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<Notification> notifs = new ArrayList<Notification>();
public final List<Notification> 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<String,Object> env = new HashMap<String,Object>();
final Map<String,Object> 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<String,Object> cenv = new HashMap<String,Object>();
final Map<String,Object> 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;
}