提交 676d04bd 编写于 作者: A asaha

Merge

...@@ -499,4 +499,14 @@ f712dceafb546ea5833aeea507b5736e7e45f1ae jdk8u66-b31 ...@@ -499,4 +499,14 @@ f712dceafb546ea5833aeea507b5736e7e45f1ae jdk8u66-b31
e8b5e10a19d66a77d04f12d4677e6fec66f79651 jdk8u71-b01 e8b5e10a19d66a77d04f12d4677e6fec66f79651 jdk8u71-b01
25d689a73bc037e1710f95f6d4acf0671d22047d jdk8u71-b02 25d689a73bc037e1710f95f6d4acf0671d22047d jdk8u71-b02
ab54163c8610f6238a1d5f1f67cbd19ba13d08a0 jdk8u71-b03 ab54163c8610f6238a1d5f1f67cbd19ba13d08a0 jdk8u71-b03
5ea62bb625b6b8f828098884d13eb2e3114a7c97 jdk8u71-b04
1a9ced1852957b65e0c156602c3101aff17274fb jdk8u71-b05
be9d91d310a02c2974d2bdabc31d8a6df8ad596e jdk8u71-b06
be5faa9c77042f202106c18f4e8ea211137b4a3b jdk8u72-b00
5ad1e9e8e8417f80c91d7e0f1f44cdf89b34ead3 jdk8u72-b01
ab0c1040414d038ccbcfcc8ceb1ccf2f44ead8e4 jdk8u72-b02
bdbb8a650d90d3481802a4f5297b522a16bd3f63 jdk8u72-b03
b6645d81ccd773820aca99548640ace9c2f39225 jdk8u72-b04
2bae9d627eb83f2ea23f4fa86e8eb46920cd1be6 jdk8u72-b05
93148bc60f510af5160b6727533733c66284a84f jdk8u72-b06
7cfd2c51c501df909833aa0fb6e40c50c61621ed jdk8u75-b00 7cfd2c51c501df909833aa0fb6e40c50c61621ed jdk8u75-b00
...@@ -205,6 +205,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \ ...@@ -205,6 +205,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA, \
-framework Foundation \ -framework Foundation \
-framework Security -framework SystemConfiguration, \ -framework Security -framework SystemConfiguration, \
LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \ LDFLAGS_SUFFIX_windows := -export:winFileHandleOpen -export:handleLseek \
-export:getErrorString \
jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \
shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \ shell32.lib delayimp.lib -DELAYLOAD:shell32.dll \
advapi32.lib version.lib, \ advapi32.lib version.lib, \
......
...@@ -242,7 +242,7 @@ SUNWprivate_1.1 { ...@@ -242,7 +242,7 @@ SUNWprivate_1.1 {
getDefaultConfig; getDefaultConfig;
Java_sun_font_FontConfigManager_getFontConfig; Java_sun_font_FontConfigManager_getFontConfig;
Java_sun_font_FontConfigManager_getFontConfigAASettings; Java_sun_font_FontConfigManager_getFontConfigAASettings;
Java_sun_awt_X11FontManager_getFontPathNative; Java_sun_awt_FcFontManager_getFontPathNative;
Java_sun_font_SunFontManager_populateFontFileNameMap; Java_sun_font_SunFontManager_populateFontFileNameMap;
# CDE private entry point # CDE private entry point
......
...@@ -270,7 +270,7 @@ SUNWprivate_1.1 { ...@@ -270,7 +270,7 @@ SUNWprivate_1.1 {
getDefaultConfig; getDefaultConfig;
Java_sun_font_FontConfigManager_getFontConfig; Java_sun_font_FontConfigManager_getFontConfig;
Java_sun_font_FontConfigManager_getFontConfigAASettings; Java_sun_font_FontConfigManager_getFontConfigAASettings;
Java_sun_awt_X11FontManager_getFontPathNative; Java_sun_awt_FcFontManager_getFontPathNative;
Java_sun_font_SunFontManager_populateFontFileNameMap; Java_sun_font_SunFontManager_populateFontFileNameMap;
# CDE private entry point # CDE private entry point
......
...@@ -65,7 +65,7 @@ SUNWprivate_1.1 { ...@@ -65,7 +65,7 @@ SUNWprivate_1.1 {
Java_sun_font_FontConfigManager_getFontConfig; Java_sun_font_FontConfigManager_getFontConfig;
Java_sun_font_FontConfigManager_getFontConfigAASettings; Java_sun_font_FontConfigManager_getFontConfigAASettings;
Java_sun_font_FontConfigManager_getFontConfigVersion; Java_sun_font_FontConfigManager_getFontConfigVersion;
Java_sun_awt_X11FontManager_getFontPathNative; Java_sun_awt_FcFontManager_getFontPathNative;
Java_sun_awt_FontDescriptor_initIDs; Java_sun_awt_FontDescriptor_initIDs;
Java_sun_awt_PlatformFont_initIDs; Java_sun_awt_PlatformFont_initIDs;
......
...@@ -188,7 +188,7 @@ SUNWprivate_1.1 { ...@@ -188,7 +188,7 @@ SUNWprivate_1.1 {
Java_sun_font_FontConfigManager_getFontConfig; Java_sun_font_FontConfigManager_getFontConfig;
Java_sun_font_FontConfigManager_getFontConfigAASettings; Java_sun_font_FontConfigManager_getFontConfigAASettings;
Java_sun_font_FontConfigManager_getFontConfigVersion; Java_sun_font_FontConfigManager_getFontConfigVersion;
Java_sun_awt_X11FontManager_getFontPathNative; Java_sun_awt_FcFontManager_getFontPathNative;
Java_sun_awt_X11GraphicsEnvironment_initDisplay; Java_sun_awt_X11GraphicsEnvironment_initDisplay;
Java_sun_awt_X11GraphicsEnvironment_initGLX; Java_sun_awt_X11GraphicsEnvironment_initGLX;
Java_sun_awt_X11GraphicsEnvironment_initXRender; Java_sun_awt_X11GraphicsEnvironment_initXRender;
......
...@@ -284,6 +284,8 @@ SUNWprivate_1.1 { ...@@ -284,6 +284,8 @@ SUNWprivate_1.1 {
# ZipFile.c needs this one # ZipFile.c needs this one
throwFileNotFoundException; throwFileNotFoundException;
# zip_util.c needs this
getErrorString;
# Java_sun_misc_VM_getState; threads.c # Java_sun_misc_VM_getState; threads.c
# Java_sun_misc_VM_threadsSuspended; threads.c # Java_sun_misc_VM_threadsSuspended; threads.c
......
# #
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -28,8 +28,7 @@ ...@@ -28,8 +28,7 @@
SUNWprivate_1.1 { SUNWprivate_1.1 {
global: global:
JNI_OnLoad; JNI_OnLoad;
Java_java_net_AbstractPlainDatagramSocketImpl_init; Java_java_net_PlainDatagramSocketImpl_dataAvailable;
Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable;
Java_java_net_PlainSocketImpl_socketListen; Java_java_net_PlainSocketImpl_socketListen;
Java_java_net_PlainDatagramSocketImpl_getTTL; Java_java_net_PlainDatagramSocketImpl_getTTL;
Java_java_net_PlainDatagramSocketImpl_init; Java_java_net_PlainDatagramSocketImpl_init;
......
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
...@@ -27,9 +28,10 @@ package sun.lwawt.macosx; ...@@ -27,9 +28,10 @@ package sun.lwawt.macosx;
import java.awt.*; import java.awt.*;
import java.awt.image.*; import java.awt.image.*;
import sun.awt.image.ImageRepresentation;
import java.io.*; import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.text.Normalizer; import java.text.Normalizer;
import java.text.Normalizer.Form; import java.text.Normalizer.Form;
...@@ -54,7 +56,8 @@ public class CDataTransferer extends DataTransferer { ...@@ -54,7 +56,8 @@ public class CDataTransferer extends DataTransferer {
"PDF", "PDF",
"URL", "URL",
"PNG", "PNG",
"JFIF" "JFIF",
"XPICT"
}; };
static { static {
...@@ -78,6 +81,7 @@ public class CDataTransferer extends DataTransferer { ...@@ -78,6 +81,7 @@ public class CDataTransferer extends DataTransferer {
public static final int CF_URL = 7; public static final int CF_URL = 7;
public static final int CF_PNG = 8; public static final int CF_PNG = 8;
public static final int CF_JPEG = 9; public static final int CF_JPEG = 9;
public static final int CF_XPICT = 10;
private CDataTransferer() {} private CDataTransferer() {}
...@@ -122,26 +126,43 @@ public class CDataTransferer extends DataTransferer { ...@@ -122,26 +126,43 @@ public class CDataTransferer extends DataTransferer {
@Override @Override
public Object translateBytes(byte[] bytes, DataFlavor flavor, public Object translateBytes(byte[] bytes, DataFlavor flavor,
long format, Transferable transferable) throws IOException { long format, Transferable transferable) throws IOException {
if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass()))
{
String charset = getDefaultTextCharset();
if (transferable != null && transferable.isDataFlavorSupported(javaTextEncodingFlavor)) {
try {
charset = new String((byte[])transferable.getTransferData(javaTextEncodingFlavor), "UTF-8");
} catch (UnsupportedFlavorException cannotHappen) {
}
}
return new URL(new String(bytes, charset));
}
if (format == CF_STRING) { if (format == CF_URL && URL.class.equals(flavor.getRepresentationClass())) {
bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8"); String[] strings = dragQueryFile(bytes);
if(strings == null || strings.length == 0) {
return null;
}
return new URL(strings[0]);
} else if(isUriListFlavor(flavor)) {
// dragQueryFile works fine with files and url,
// it parses and extracts values from property list.
// maxosx always returns property list for
// CF_URL and CF_FILE
String[] strings = dragQueryFile(bytes);
if(strings == null) {
return null;
}
String separator = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
if(strings.length > 0) {
sb.append(strings[0]);
for(int i = 1; i < strings.length; i++) {
sb.append(strings[i]);
sb.append(separator);
}
} }
bytes = sb.toString().getBytes();
// now we extracted uri from xml, now we should treat it as
// regular string that allows to translate data to target represantation
// class by base method
format = CF_STRING;
} else if (format == CF_STRING) {
bytes = Normalizer.normalize(new String(bytes, "UTF8"), Form.NFC).getBytes("UTF8");
}
return super.translateBytes(bytes, flavor, format, transferable); return super.translateBytes(bytes, flavor, format, transferable);
} }
@Override @Override
...@@ -219,6 +240,7 @@ public class CDataTransferer extends DataTransferer { ...@@ -219,6 +240,7 @@ public class CDataTransferer extends DataTransferer {
return nativeDragQueryFile(bytes); return nativeDragQueryFile(bytes);
} }
@Override @Override
protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException { protected Image platformImageBytesToImage(byte[] bytes, long format) throws IOException {
return CImage.getCreator().createImageFromPlatformImageBytes(bytes); return CImage.getCreator().createImageFromPlatformImageBytes(bytes);
...@@ -243,7 +265,7 @@ public class CDataTransferer extends DataTransferer { ...@@ -243,7 +265,7 @@ public class CDataTransferer extends DataTransferer {
} }
try { try {
DataFlavor df = new DataFlavor(nat); DataFlavor df = new DataFlavor(nat);
if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) { if (isUriListFlavor(df)) {
return true; return true;
} }
} catch (Exception e) { } catch (Exception e) {
...@@ -251,6 +273,13 @@ public class CDataTransferer extends DataTransferer { ...@@ -251,6 +273,13 @@ public class CDataTransferer extends DataTransferer {
} }
return false; return false;
} }
private boolean isUriListFlavor(DataFlavor df) {
if (df.getPrimaryType().equals("text") && df.getSubType().equals("uri-list")) {
return true;
}
return false;
}
} }
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -84,10 +84,24 @@ class KQueueSelectorImpl ...@@ -84,10 +84,24 @@ class KQueueSelectorImpl
long fds = IOUtil.makePipe(false); long fds = IOUtil.makePipe(false);
fd0 = (int)(fds >>> 32); fd0 = (int)(fds >>> 32);
fd1 = (int)fds; fd1 = (int)fds;
kqueueWrapper = new KQueueArrayWrapper(); try {
kqueueWrapper.initInterrupt(fd0, fd1); kqueueWrapper = new KQueueArrayWrapper();
fdMap = new HashMap<>(); kqueueWrapper.initInterrupt(fd0, fd1);
totalChannels = 1; fdMap = new HashMap<>();
totalChannels = 1;
} catch (Throwable t) {
try {
FileDispatcherImpl.closeIntFD(fd0);
} catch (IOException ioe0) {
t.addSuppressed(ioe0);
}
try {
FileDispatcherImpl.closeIntFD(fd1);
} catch (IOException ioe1) {
t.addSuppressed(ioe1);
}
throw t;
}
} }
......
...@@ -80,4 +80,6 @@ TIFF=image/x-java-image;class=java.awt.Image ...@@ -80,4 +80,6 @@ TIFF=image/x-java-image;class=java.awt.Image
RICH_TEXT=text/rtf RICH_TEXT=text/rtf
HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1 HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
URL=application/x-java-url;class=java.net.URL URL=application/x-java-url;class=java.net.URL
FILE_NAME=text/uri-list;eoln="\r\n";terminators=1
URL=text/uri-list;eoln="\r\n";terminators=1 URL=text/uri-list;eoln="\r\n";terminators=1
XPICT=image/x-pict;class=java.io.InputStream
...@@ -58,6 +58,8 @@ NSMutableDictionary *getMappingTable() { ...@@ -58,6 +58,8 @@ NSMutableDictionary *getMappingTable() {
forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_PNG]]; forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_PNG]];
[sStandardMappings setObject:(NSString*)kUTTypeJPEG [sStandardMappings setObject:(NSString*)kUTTypeJPEG
forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_JPEG]]; forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_JPEG]];
[sStandardMappings setObject:NSPICTPboardType
forKey:[NSNumber numberWithLong:sun_lwawt_macosx_CDataTransferer_CF_XPICT]];
} }
return sStandardMappings; return sStandardMappings;
} }
......
...@@ -287,7 +287,7 @@ JNF_COCOA_ENTER(env); ...@@ -287,7 +287,7 @@ JNF_COCOA_ENTER(env);
// Processing all events excluding NSApplicationDefined which need to be processed // Processing all events excluding NSApplicationDefined which need to be processed
// on the main loop only (those events are intended for disposing resources) // on the main loop only (those events are intended for disposing resources)
NSEvent *event; NSEvent *event;
if ((event = [NSApp nextEventMatchingMask:(NSAnyEventMask & ~NSApplicationDefined) if ((event = [NSApp nextEventMatchingMask:(NSAnyEventMask & ~NSApplicationDefinedMask)
untilDate:nil untilDate:nil
inMode:NSDefaultRunLoopMode inMode:NSDefaultRunLoopMode
dequeue:YES]) != nil) { dequeue:YES]) != nil) {
......
...@@ -494,16 +494,14 @@ public final class LdapClient implements PooledConnection { ...@@ -494,16 +494,14 @@ public final class LdapClient implements PooledConnection {
*/ */
void processConnectionClosure() { void processConnectionClosure() {
// Notify listeners // Notify listeners
synchronized (unsolicited) { if (unsolicited.size() > 0) {
if (unsolicited.size() > 0) { String msg;
String msg; if (conn != null) {
if (conn != null) { msg = conn.host + ":" + conn.port + " connection closed";
msg = conn.host + ":" + conn.port + " connection closed"; } else {
} else { msg = "Connection closed";
msg = "Connection closed";
}
notifyUnsolicited(new CommunicationException(msg));
} }
notifyUnsolicited(new CommunicationException(msg));
} }
// Remove from pool // Remove from pool
...@@ -1499,13 +1497,8 @@ public final class LdapClient implements PooledConnection { ...@@ -1499,13 +1497,8 @@ public final class LdapClient implements PooledConnection {
if (debug > 0) { if (debug > 0) {
System.err.println("LdapClient.removeUnsolicited" + ctx); System.err.println("LdapClient.removeUnsolicited" + ctx);
} }
synchronized (unsolicited) {
if (unsolicited.size() == 0) {
return;
}
unsolicited.removeElement(ctx); unsolicited.removeElement(ctx);
} }
}
// NOTE: Cannot be synchronized because this is called asynchronously // NOTE: Cannot be synchronized because this is called asynchronously
// by the reader thread in Connection. Instead, sync on 'unsolicited' Vector. // by the reader thread in Connection. Instead, sync on 'unsolicited' Vector.
...@@ -1513,30 +1506,35 @@ public final class LdapClient implements PooledConnection { ...@@ -1513,30 +1506,35 @@ public final class LdapClient implements PooledConnection {
if (debug > 0) { if (debug > 0) {
System.err.println("LdapClient.processUnsolicited"); System.err.println("LdapClient.processUnsolicited");
} }
synchronized (unsolicited) { try {
try { // Parse the response
// Parse the response LdapResult res = new LdapResult();
LdapResult res = new LdapResult();
ber.parseSeq(null); // init seq
ber.parseSeq(null); // init seq ber.parseInt(); // msg id; should be 0; ignored
ber.parseInt(); // msg id; should be 0; ignored if (ber.parseByte() != LDAP_REP_EXTENSION) {
if (ber.parseByte() != LDAP_REP_EXTENSION) { throw new IOException(
throw new IOException( "Unsolicited Notification must be an Extended Response");
"Unsolicited Notification must be an Extended Response"); }
} ber.parseLength();
ber.parseLength(); parseExtResponse(ber, res);
parseExtResponse(ber, res);
if (DISCONNECT_OID.equals(res.extensionId)) { if (DISCONNECT_OID.equals(res.extensionId)) {
// force closing of connection // force closing of connection
forceClose(pooled); forceClose(pooled);
} }
LdapCtx first = null;
UnsolicitedNotification notice = null;
synchronized (unsolicited) {
if (unsolicited.size() > 0) { if (unsolicited.size() > 0) {
first = unsolicited.elementAt(0);
// Create an UnsolicitedNotification using the parsed data // Create an UnsolicitedNotification using the parsed data
// Need a 'ctx' object because we want to use the context's // Need a 'ctx' object because we want to use the context's
// list of provider control factories. // list of provider control factories.
UnsolicitedNotification notice = new UnsolicitedResponseImpl( notice = new UnsolicitedResponseImpl(
res.extensionId, res.extensionId,
res.extensionValue, res.extensionValue,
res.referrals, res.referrals,
...@@ -1544,42 +1542,45 @@ public final class LdapClient implements PooledConnection { ...@@ -1544,42 +1542,45 @@ public final class LdapClient implements PooledConnection {
res.errorMessage, res.errorMessage,
res.matchedDN, res.matchedDN,
(res.resControls != null) ? (res.resControls != null) ?
unsolicited.elementAt(0).convertControls(res.resControls) : first.convertControls(res.resControls) :
null); null);
}
}
// Fire UnsolicitedNotification events to listeners if (notice != null) {
notifyUnsolicited(notice); // Fire UnsolicitedNotification events to listeners
notifyUnsolicited(notice);
// If "disconnect" notification, // If "disconnect" notification,
// notify unsolicited listeners via NamingException // notify unsolicited listeners via NamingException
if (DISCONNECT_OID.equals(res.extensionId)) { if (DISCONNECT_OID.equals(res.extensionId)) {
notifyUnsolicited( notifyUnsolicited(
new CommunicationException("Connection closed")); new CommunicationException("Connection closed"));
}
} }
} catch (IOException e) { }
if (unsolicited.size() == 0) } catch (IOException e) {
return; // no one registered; ignore NamingException ne = new CommunicationException(
"Problem parsing unsolicited notification");
NamingException ne = new CommunicationException( ne.setRootCause(e);
"Problem parsing unsolicited notification");
ne.setRootCause(e);
notifyUnsolicited(ne); notifyUnsolicited(ne);
} catch (NamingException e) { } catch (NamingException e) {
notifyUnsolicited(e); notifyUnsolicited(e);
}
} }
} }
private void notifyUnsolicited(Object e) { private void notifyUnsolicited(Object e) {
for (int i = 0; i < unsolicited.size(); i++) { Vector<LdapCtx> unsolicitedCopy;
unsolicited.elementAt(i).fireUnsolicited(e); synchronized (unsolicited) {
unsolicitedCopy = new Vector<>(unsolicited);
if (e instanceof NamingException) {
unsolicited.setSize(0); // no more listeners after exception
}
} }
if (e instanceof NamingException) { for (int i = 0; i < unsolicitedCopy.size(); i++) {
unsolicited.setSize(0); // no more listeners after exception unsolicitedCopy.elementAt(i).fireUnsolicited(e);
} }
} }
......
...@@ -896,11 +896,13 @@ public class EventQueue { ...@@ -896,11 +896,13 @@ public class EventQueue {
} }
} }
// Wake up EDT waiting in getNextEvent(), so it can if (topQueue.dispatchThread != null) {
// pick up a new EventQueue. Post the waking event before // Wake up EDT waiting in getNextEvent(), so it can
// topQueue.nextQueue is assigned, otherwise the event would // pick up a new EventQueue. Post the waking event before
// go newEventQueue // topQueue.nextQueue is assigned, otherwise the event would
topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable)); // go newEventQueue
topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
}
newEventQueue.previousQueue = topQueue; newEventQueue.previousQueue = topQueue;
topQueue.nextQueue = newEventQueue; topQueue.nextQueue = newEventQueue;
......
...@@ -6647,7 +6647,7 @@ class Character implements java.io.Serializable, Comparable<Character> { ...@@ -6647,7 +6647,7 @@ class Character implements java.io.Serializable, Comparable<Character> {
* <td>{@code FORM FEED}</td></tr> * <td>{@code FORM FEED}</td></tr>
* <tr><td>{@code '\r'}</td> <td>{@code U+000D}</td> * <tr><td>{@code '\r'}</td> <td>{@code U+000D}</td>
* <td>{@code CARRIAGE RETURN}</td></tr> * <td>{@code CARRIAGE RETURN}</td></tr>
* <tr><td>{@code '&nbsp;'}</td> <td>{@code U+0020}</td> * <tr><td>{@code ' '}</td> <td>{@code U+0020}</td>
* <td>{@code SPACE}</td></tr> * <td>{@code SPACE}</td></tr>
* </table> * </table>
* *
......
...@@ -436,7 +436,7 @@ class LambdaFormEditor { ...@@ -436,7 +436,7 @@ class LambdaFormEditor {
} }
private MethodType bindArgumentType(BoundMethodHandle mh, int pos, BasicType bt) { private MethodType bindArgumentType(BoundMethodHandle mh, int pos, BasicType bt) {
assert(mh.form == lambdaForm); assert(mh.form.uncustomize() == lambdaForm);
assert(mh.form.names[1+pos].type == bt); assert(mh.form.names[1+pos].type == bt);
assert(BasicType.basicType(mh.type().parameterType(pos)) == bt); assert(BasicType.basicType(mh.type().parameterType(pos)) == bt);
return mh.type().dropParameterTypes(pos, pos+1); return mh.type().dropParameterTypes(pos, pos+1);
......
...@@ -93,7 +93,7 @@ import java.util.Objects; ...@@ -93,7 +93,7 @@ import java.util.Objects;
/** Return the simple name of this member. /** Return the simple name of this member.
* For a type, it is the same as {@link Class#getSimpleName}. * For a type, it is the same as {@link Class#getSimpleName}.
* For a method or field, it is the simple name of the member. * For a method or field, it is the simple name of the member.
* For a constructor, it is always {@code "&lt;init&gt;"}. * For a constructor, it is always {@code "<init>"}.
*/ */
public String getName() { public String getName() {
if (name == null) { if (name == null) {
...@@ -727,7 +727,7 @@ import java.util.Objects; ...@@ -727,7 +727,7 @@ import java.util.Objects;
} }
/** Create a method or constructor name from the given components: /** Create a method or constructor name from the given components:
* Declaring class, name, type, reference kind. * Declaring class, name, type, reference kind.
* It will be a constructor if and only if the name is {@code "&lt;init&gt;"}. * It will be a constructor if and only if the name is {@code "<init>"}.
* The declaring class may be supplied as null if this is to be a bare name and type. * The declaring class may be supplied as null if this is to be a bare name and type.
* The last argument is optional, a boolean which requests REF_invokeSpecial. * The last argument is optional, a boolean which requests REF_invokeSpecial.
* The resulting name will in an unresolved state. * The resulting name will in an unresolved state.
......
...@@ -155,7 +155,7 @@ interface MethodHandleInfo { ...@@ -155,7 +155,7 @@ interface MethodHandleInfo {
/** /**
* Returns the name of the cracked method handle's underlying member. * Returns the name of the cracked method handle's underlying member.
* This is {@code "&lt;init&gt;"} if the underlying member was a constructor, * This is {@code "<init>"} if the underlying member was a constructor,
* else it is a simple method name or field name. * else it is a simple method name or field name.
* @return the simple name of the underlying member * @return the simple name of the underlying member
*/ */
......
...@@ -51,7 +51,7 @@ import java.lang.annotation.*; ...@@ -51,7 +51,7 @@ import java.lang.annotation.*;
* If the field is an array type, then both the field value and * If the field is an array type, then both the field value and
* all the components of the field value (if the field value is non-null) * all the components of the field value (if the field value is non-null)
* are indicated to be stable. * are indicated to be stable.
* If the field type is an array type with rank {@code N &gt; 1}, * If the field type is an array type with rank {@code N > 1},
* then each component of the field value (if the field value is non-null), * then each component of the field value (if the field value is non-null),
* is regarded as a stable array of rank {@code N-1}. * is regarded as a stable array of rank {@code N-1}.
* <p> * <p>
......
...@@ -55,20 +55,20 @@ package java.lang.invoke; ...@@ -55,20 +55,20 @@ package java.lang.invoke;
* At that point {@code guardWithTest} may ignore {@code T} and return {@code F}. * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}.
* <p> * <p>
* Here is an example of a switch point in action: * Here is an example of a switch point in action:
* <blockquote><pre>{@code * <pre>{@code
MethodHandle MH_strcat = MethodHandles.lookup() * MethodHandle MH_strcat = MethodHandles.lookup()
.findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class)); * .findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class));
SwitchPoint spt = new SwitchPoint(); * SwitchPoint spt = new SwitchPoint();
assert(!spt.hasBeenInvalidated()); * assert(!spt.hasBeenInvalidated());
// the following steps may be repeated to re-use the same switch point: * // the following steps may be repeated to re-use the same switch point:
MethodHandle worker1 = MH_strcat; * MethodHandle worker1 = MH_strcat;
MethodHandle worker2 = MethodHandles.permuteArguments(MH_strcat, MH_strcat.type(), 1, 0); * MethodHandle worker2 = MethodHandles.permuteArguments(MH_strcat, MH_strcat.type(), 1, 0);
MethodHandle worker = spt.guardWithTest(worker1, worker2); * MethodHandle worker = spt.guardWithTest(worker1, worker2);
assertEquals("method", (String) worker.invokeExact("met", "hod")); * assertEquals("method", (String) worker.invokeExact("met", "hod"));
SwitchPoint.invalidateAll(new SwitchPoint[]{ spt }); * SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
assert(spt.hasBeenInvalidated()); * assert(spt.hasBeenInvalidated());
assertEquals("hodmet", (String) worker.invokeExact("met", "hod")); * assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
* }</pre></blockquote> * }</pre>
* <p style="font-size:smaller;"> * <p style="font-size:smaller;">
* <em>Discussion:</em> * <em>Discussion:</em>
* Switch points are useful without subclassing. They may also be subclassed. * Switch points are useful without subclassing. They may also be subclassed.
...@@ -82,31 +82,31 @@ assertEquals("hodmet", (String) worker.invokeExact("met", "hod")); ...@@ -82,31 +82,31 @@ assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
* <em>Implementation Note:</em> * <em>Implementation Note:</em>
* A switch point behaves as if implemented on top of {@link MutableCallSite}, * A switch point behaves as if implemented on top of {@link MutableCallSite},
* approximately as follows: * approximately as follows:
* <blockquote><pre>{@code * <pre>{@code
public class SwitchPoint { * public class SwitchPoint {
private static final MethodHandle * private static final MethodHandle
K_true = MethodHandles.constant(boolean.class, true), * K_true = MethodHandles.constant(boolean.class, true),
K_false = MethodHandles.constant(boolean.class, false); * K_false = MethodHandles.constant(boolean.class, false);
private final MutableCallSite mcs; * private final MutableCallSite mcs;
private final MethodHandle mcsInvoker; * private final MethodHandle mcsInvoker;
public SwitchPoint() { * public SwitchPoint() {
this.mcs = new MutableCallSite(K_true); * this.mcs = new MutableCallSite(K_true);
this.mcsInvoker = mcs.dynamicInvoker(); * this.mcsInvoker = mcs.dynamicInvoker();
} * }
public MethodHandle guardWithTest( * public MethodHandle guardWithTest(
MethodHandle target, MethodHandle fallback) { * MethodHandle target, MethodHandle fallback) {
// Note: mcsInvoker is of type ()boolean. * // Note: mcsInvoker is of type ()boolean.
// Target and fallback may take any arguments, but must have the same type. * // Target and fallback may take any arguments, but must have the same type.
return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback); * return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
} * }
public static void invalidateAll(SwitchPoint[] spts) { * public static void invalidateAll(SwitchPoint[] spts) {
List&lt;MutableCallSite&gt; mcss = new ArrayList&lt;&gt;(); * List<MutableCallSite> mcss = new ArrayList<>();
for (SwitchPoint spt : spts) mcss.add(spt.mcs); * for (SwitchPoint spt : spts) mcss.add(spt.mcs);
for (MutableCallSite mcs : mcss) mcs.setTarget(K_false); * for (MutableCallSite mcs : mcss) mcs.setTarget(K_false);
MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0])); * MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
} * }
} * }
* }</pre></blockquote> * }</pre>
* @author Remi Forax, JSR 292 EG * @author Remi Forax, JSR 292 EG
*/ */
public class SwitchPoint { public class SwitchPoint {
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
package java.lang.ref; package java.lang.ref;
import sun.misc.Cleaner; import sun.misc.Cleaner;
import sun.misc.JavaLangRefAccess;
import sun.misc.SharedSecrets;
/** /**
* Abstract base class for reference objects. This class defines the * Abstract base class for reference objects. This class defines the
...@@ -111,7 +113,7 @@ public abstract class Reference<T> { ...@@ -111,7 +113,7 @@ public abstract class Reference<T> {
* therefore critical that any code holding this lock complete as quickly * therefore critical that any code holding this lock complete as quickly
* as possible, allocate no new objects, and avoid calling user code. * as possible, allocate no new objects, and avoid calling user code.
*/ */
static private class Lock { }; static private class Lock { }
private static Lock lock = new Lock(); private static Lock lock = new Lock();
...@@ -126,51 +128,94 @@ public abstract class Reference<T> { ...@@ -126,51 +128,94 @@ public abstract class Reference<T> {
*/ */
private static class ReferenceHandler extends Thread { private static class ReferenceHandler extends Thread {
private static void ensureClassInitialized(Class<?> clazz) {
try {
Class.forName(clazz.getName(), true, clazz.getClassLoader());
} catch (ClassNotFoundException e) {
throw (Error) new NoClassDefFoundError(e.getMessage()).initCause(e);
}
}
static {
// pre-load and initialize InterruptedException and Cleaner classes
// so that we don't get into trouble later in the run loop if there's
// memory shortage while loading/initializing them lazily.
ensureClassInitialized(InterruptedException.class);
ensureClassInitialized(Cleaner.class);
}
ReferenceHandler(ThreadGroup g, String name) { ReferenceHandler(ThreadGroup g, String name) {
super(g, name); super(g, name);
} }
public void run() { public void run() {
for (;;) { while (true) {
Reference<Object> r; tryHandlePending(true);
synchronized (lock) { }
if (pending != null) { }
r = pending; }
pending = r.discovered;
r.discovered = null;
} else {
// The waiting on the lock may cause an OOME because it may try to allocate
// exception objects, so also catch OOME here to avoid silent exit of the
// reference handler thread.
//
// Explicitly define the order of the two exceptions we catch here
// when waiting for the lock.
//
// We do not want to try to potentially load the InterruptedException class
// (which would be done if this was its first use, and InterruptedException
// were checked first) in this situation.
//
// This may lead to the VM not ever trying to load the InterruptedException
// class again.
try {
try {
lock.wait();
} catch (OutOfMemoryError x) { }
} catch (InterruptedException x) { }
continue;
}
}
// Fast path for cleaners /**
if (r instanceof Cleaner) { * Try handle pending {@link Reference} if there is one.<p>
((Cleaner)r).clean(); * Return {@code true} as a hint that there might be another
continue; * {@link Reference} pending or {@code false} when there are no more pending
* {@link Reference}s at the moment and the program can do some other
* useful work instead of looping.
*
* @param waitForNotify if {@code true} and there was no pending
* {@link Reference}, wait until notified from VM
* or interrupted; if {@code false}, return immediately
* when there is no pending {@link Reference}.
* @return {@code true} if there was a {@link Reference} pending and it
* was processed, or we waited for notification and either got it
* or thread was interrupted before being notified;
* {@code false} otherwise.
*/
static boolean tryHandlePending(boolean waitForNotify) {
Reference<Object> r;
Cleaner c;
try {
synchronized (lock) {
if (pending != null) {
r = pending;
// 'instanceof' might throw OutOfMemoryError sometimes
// so do this before un-linking 'r' from the 'pending' chain...
c = r instanceof Cleaner ? (Cleaner) r : null;
// unlink 'r' from 'pending' chain
pending = r.discovered;
r.discovered = null;
} else {
// The waiting on the lock may cause an OutOfMemoryError
// because it may try to allocate exception objects.
if (waitForNotify) {
lock.wait();
}
// retry if waited
return waitForNotify;
} }
ReferenceQueue<Object> q = r.queue;
if (q != ReferenceQueue.NULL) q.enqueue(r);
} }
} catch (OutOfMemoryError x) {
// Give other threads CPU time so they hopefully drop some live references
// and GC reclaims some space.
// Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above
// persistently throws OOME for some time...
Thread.yield();
// retry
return true;
} catch (InterruptedException x) {
// retry
return true;
}
// Fast path for cleaners
if (c != null) {
c.clean();
return true;
} }
ReferenceQueue<? super Object> q = r.queue;
if (q != ReferenceQueue.NULL) q.enqueue(r);
return true;
} }
static { static {
...@@ -185,8 +230,15 @@ public abstract class Reference<T> { ...@@ -185,8 +230,15 @@ public abstract class Reference<T> {
handler.setPriority(Thread.MAX_PRIORITY); handler.setPriority(Thread.MAX_PRIORITY);
handler.setDaemon(true); handler.setDaemon(true);
handler.start(); handler.start();
}
// provide access in SharedSecrets
SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
@Override
public boolean tryHandlePendingReference() {
return tryHandlePending(false);
}
});
}
/* -- Referent accessor and setters -- */ /* -- Referent accessor and setters -- */
......
...@@ -218,6 +218,7 @@ public final class Constructor<T> extends Executable { ...@@ -218,6 +218,7 @@ public final class Constructor<T> extends Executable {
/** /**
* {@inheritDoc} * {@inheritDoc}
* @since 1.8
*/ */
public int getParameterCount() { return parameterTypes.length; } public int getParameterCount() { return parameterTypes.length; }
......
...@@ -245,7 +245,6 @@ public abstract class Executable extends AccessibleObject ...@@ -245,7 +245,6 @@ public abstract class Executable extends AccessibleObject
* declared or implicitly declared or neither) for the executable * declared or implicitly declared or neither) for the executable
* represented by this object. * represented by this object.
* *
* @since 1.8
* @return The number of formal parameters for the executable this * @return The number of formal parameters for the executable this
* object represents * object represents
*/ */
...@@ -343,7 +342,6 @@ public abstract class Executable extends AccessibleObject ...@@ -343,7 +342,6 @@ public abstract class Executable extends AccessibleObject
* have unique names, or names that are legal identifiers in the * have unique names, or names that are legal identifiers in the
* Java programming language (JLS 3.8). * Java programming language (JLS 3.8).
* *
* @since 1.8
* @throws MalformedParametersException if the class file contains * @throws MalformedParametersException if the class file contains
* a MethodParameters attribute that is improperly formatted. * a MethodParameters attribute that is improperly formatted.
* @return an array of {@code Parameter} objects representing all * @return an array of {@code Parameter} objects representing all
...@@ -575,7 +573,6 @@ public abstract class Executable extends AccessibleObject ...@@ -575,7 +573,6 @@ public abstract class Executable extends AccessibleObject
/** /**
* {@inheritDoc} * {@inheritDoc}
* @throws NullPointerException {@inheritDoc} * @throws NullPointerException {@inheritDoc}
* @since 1.8
*/ */
@Override @Override
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) { public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
...@@ -623,8 +620,6 @@ public abstract class Executable extends AccessibleObject ...@@ -623,8 +620,6 @@ public abstract class Executable extends AccessibleObject
* *
* @return an object representing the return type of the method * @return an object representing the return type of the method
* or constructor represented by this {@code Executable} * or constructor represented by this {@code Executable}
*
* @since 1.8
*/ */
public abstract AnnotatedType getAnnotatedReturnType(); public abstract AnnotatedType getAnnotatedReturnType();
...@@ -633,8 +628,6 @@ public abstract class Executable extends AccessibleObject ...@@ -633,8 +628,6 @@ public abstract class Executable extends AccessibleObject
* Returns an AnnotatedType object that represents the use of a type to * Returns an AnnotatedType object that represents the use of a type to
* specify the return type of the method/constructor represented by this * specify the return type of the method/constructor represented by this
* Executable. * Executable.
*
* @since 1.8
*/ */
AnnotatedType getAnnotatedReturnType0(Type returnType) { AnnotatedType getAnnotatedReturnType0(Type returnType) {
return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
...@@ -664,8 +657,6 @@ public abstract class Executable extends AccessibleObject ...@@ -664,8 +657,6 @@ public abstract class Executable extends AccessibleObject
* *
* @return an object representing the receiver type of the method or * @return an object representing the receiver type of the method or
* constructor represented by this {@code Executable} * constructor represented by this {@code Executable}
*
* @since 1.8
*/ */
public AnnotatedType getAnnotatedReceiverType() { public AnnotatedType getAnnotatedReceiverType() {
if (Modifier.isStatic(this.getModifiers())) if (Modifier.isStatic(this.getModifiers()))
...@@ -692,8 +683,6 @@ public abstract class Executable extends AccessibleObject ...@@ -692,8 +683,6 @@ public abstract class Executable extends AccessibleObject
* @return an array of objects representing the types of the * @return an array of objects representing the types of the
* formal parameters of the method or constructor represented by this * formal parameters of the method or constructor represented by this
* {@code Executable} * {@code Executable}
*
* @since 1.8
*/ */
public AnnotatedType[] getAnnotatedParameterTypes() { public AnnotatedType[] getAnnotatedParameterTypes() {
return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(), return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
...@@ -718,8 +707,6 @@ public abstract class Executable extends AccessibleObject ...@@ -718,8 +707,6 @@ public abstract class Executable extends AccessibleObject
* @return an array of objects representing the declared * @return an array of objects representing the declared
* exceptions of the method or constructor represented by this {@code * exceptions of the method or constructor represented by this {@code
* Executable} * Executable}
*
* @since 1.8
*/ */
public AnnotatedType[] getAnnotatedExceptionTypes() { public AnnotatedType[] getAnnotatedExceptionTypes() {
return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(), return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
......
...@@ -266,6 +266,7 @@ public final class Method extends Executable { ...@@ -266,6 +266,7 @@ public final class Method extends Executable {
/** /**
* {@inheritDoc} * {@inheritDoc}
* @since 1.8
*/ */
public int getParameterCount() { return parameterTypes.length; } public int getParameterCount() { return parameterTypes.length; }
......
/* /*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -68,7 +68,6 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl ...@@ -68,7 +68,6 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
return null; return null;
} }
}); });
init();
} }
/** /**
...@@ -364,6 +363,5 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl ...@@ -364,6 +363,5 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
return connectDisabled; return connectDisabled;
} }
native int dataAvailable(); abstract int dataAvailable();
private static native void init();
} }
...@@ -26,6 +26,11 @@ ...@@ -26,6 +26,11 @@
package java.nio; package java.nio;
import java.security.AccessController; import java.security.AccessController;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import sun.misc.JavaLangRefAccess;
import sun.misc.SharedSecrets;
import sun.misc.Unsafe; import sun.misc.Unsafe;
import sun.misc.VM; import sun.misc.VM;
...@@ -621,55 +626,103 @@ class Bits { // package-private ...@@ -621,55 +626,103 @@ class Bits { // package-private
// direct buffer memory. This value may be changed during VM // direct buffer memory. This value may be changed during VM
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
private static volatile long maxMemory = VM.maxDirectMemory(); private static volatile long maxMemory = VM.maxDirectMemory();
private static volatile long reservedMemory; private static final AtomicLong reservedMemory = new AtomicLong();
private static volatile long totalCapacity; private static final AtomicLong totalCapacity = new AtomicLong();
private static volatile long count; private static final AtomicLong count = new AtomicLong();
private static boolean memoryLimitSet = false; private static volatile boolean memoryLimitSet = false;
// max. number of sleeps during try-reserving with exponentially
// increasing delay before throwing OutOfMemoryError:
// 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
// which means that OOME will be thrown after 0.5 s of trying
private static final int MAX_SLEEPS = 9;
// These methods should be called whenever direct memory is allocated or // These methods should be called whenever direct memory is allocated or
// freed. They allow the user to control the amount of direct memory // freed. They allow the user to control the amount of direct memory
// which a process may access. All sizes are specified in bytes. // which a process may access. All sizes are specified in bytes.
static void reserveMemory(long size, int cap) { static void reserveMemory(long size, int cap) {
synchronized (Bits.class) {
if (!memoryLimitSet && VM.isBooted()) { if (!memoryLimitSet && VM.isBooted()) {
maxMemory = VM.maxDirectMemory(); maxMemory = VM.maxDirectMemory();
memoryLimitSet = true; memoryLimitSet = true;
} }
// -XX:MaxDirectMemorySize limits the total capacity rather than the
// actual memory usage, which will differ when buffers are page // optimist!
// aligned. if (tryReserveMemory(size, cap)) {
if (cap <= maxMemory - totalCapacity) { return;
reservedMemory += size; }
totalCapacity += cap;
count++; final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
// retry while helping enqueue pending Reference objects
// which includes executing pending Cleaner(s) which includes
// Cleaner(s) that free direct buffer memory
while (jlra.tryHandlePendingReference()) {
if (tryReserveMemory(size, cap)) {
return; return;
} }
} }
// trigger VM's Reference processing
System.gc(); System.gc();
// a retry loop with exponential back-off delays
// (this gives VM some time to do it's job)
boolean interrupted = false;
try { try {
Thread.sleep(100); long sleepTime = 1;
} catch (InterruptedException x) { int sleeps = 0;
// Restore interrupt status while (true) {
Thread.currentThread().interrupt(); if (tryReserveMemory(size, cap)) {
return;
}
if (sleeps >= MAX_SLEEPS) {
break;
}
if (!jlra.tryHandlePendingReference()) {
try {
Thread.sleep(sleepTime);
sleepTime <<= 1;
sleeps++;
} catch (InterruptedException e) {
interrupted = true;
}
}
}
// no luck
throw new OutOfMemoryError("Direct buffer memory");
} finally {
if (interrupted) {
// don't swallow interrupts
Thread.currentThread().interrupt();
}
} }
synchronized (Bits.class) { }
if (totalCapacity + cap > maxMemory)
throw new OutOfMemoryError("Direct buffer memory"); private static boolean tryReserveMemory(long size, int cap) {
reservedMemory += size;
totalCapacity += cap; // -XX:MaxDirectMemorySize limits the total capacity rather than the
count++; // actual memory usage, which will differ when buffers are page
// aligned.
long totalCap;
while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
reservedMemory.addAndGet(size);
count.incrementAndGet();
return true;
}
} }
return false;
} }
static synchronized void unreserveMemory(long size, int cap) {
if (reservedMemory > 0) { static void unreserveMemory(long size, int cap) {
reservedMemory -= size; long cnt = count.decrementAndGet();
totalCapacity -= cap; long reservedMem = reservedMemory.addAndGet(-size);
count--; long totalCap = totalCapacity.addAndGet(-cap);
assert (reservedMemory > -1); assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
}
} }
// -- Monitoring of direct buffer usage -- // -- Monitoring of direct buffer usage --
...@@ -687,15 +740,15 @@ class Bits { // package-private ...@@ -687,15 +740,15 @@ class Bits { // package-private
} }
@Override @Override
public long getCount() { public long getCount() {
return Bits.count; return Bits.count.get();
} }
@Override @Override
public long getTotalCapacity() { public long getTotalCapacity() {
return Bits.totalCapacity; return Bits.totalCapacity.get();
} }
@Override @Override
public long getMemoryUsed() { public long getMemoryUsed() {
return Bits.reservedMemory; return Bits.reservedMemory.get();
} }
}; };
} }
......
...@@ -1722,7 +1722,7 @@ public class SimpleDateFormat extends DateFormat { ...@@ -1722,7 +1722,7 @@ public class SimpleDateFormat extends DateFormat {
} }
return (start + zoneNames[nameIndex].length()); return (start + zoneNames[nameIndex].length());
} }
return 0; return -start;
} }
/** /**
......
...@@ -1229,8 +1229,14 @@ public final class Instant ...@@ -1229,8 +1229,14 @@ public final class Instant
* @throws ArithmeticException if numeric overflow occurs * @throws ArithmeticException if numeric overflow occurs
*/ */
public long toEpochMilli() { public long toEpochMilli() {
long millis = Math.multiplyExact(seconds, 1000); if (seconds < 0 && nanos > 0) {
return millis + nanos / 1000_000; long millis = Math.multiplyExact(seconds+1, 1000);
long adjustment = nanos / 1000_000 - 1000;
return Math.addExact(millis, adjustment);
} else {
long millis = Math.multiplyExact(seconds, 1000);
return Math.addExact(millis, nanos / 1000_000);
}
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
......
...@@ -715,7 +715,7 @@ public interface ChronoLocalDate ...@@ -715,7 +715,7 @@ public interface ChronoLocalDate
* only compares the underlying date and not the chronology. * only compares the underlying date and not the chronology.
* This allows dates in different calendar systems to be compared based * This allows dates in different calendar systems to be compared based
* on the time-line position. * on the time-line position.
* This is equivalent to using {@code date1.toEpochDay() &gt; date2.toEpochDay()}. * This is equivalent to using {@code date1.toEpochDay() > date2.toEpochDay()}.
* <p> * <p>
* This default implementation performs the comparison based on the epoch-day. * This default implementation performs the comparison based on the epoch-day.
* *
...@@ -733,7 +733,7 @@ public interface ChronoLocalDate ...@@ -733,7 +733,7 @@ public interface ChronoLocalDate
* only compares the underlying date and not the chronology. * only compares the underlying date and not the chronology.
* This allows dates in different calendar systems to be compared based * This allows dates in different calendar systems to be compared based
* on the time-line position. * on the time-line position.
* This is equivalent to using {@code date1.toEpochDay() &lt; date2.toEpochDay()}. * This is equivalent to using {@code date1.toEpochDay() < date2.toEpochDay()}.
* <p> * <p>
* This default implementation performs the comparison based on the epoch-day. * This default implementation performs the comparison based on the epoch-day.
* *
......
...@@ -318,7 +318,9 @@ class Deflater { ...@@ -318,7 +318,9 @@ class Deflater {
* should be called in order to provide more input * should be called in order to provide more input
*/ */
public boolean needsInput() { public boolean needsInput() {
return len <= 0; synchronized (zsRef) {
return len <= 0;
}
} }
/** /**
......
...@@ -31,7 +31,7 @@ package java.util.zip; ...@@ -31,7 +31,7 @@ package java.util.zip;
class ZStreamRef { class ZStreamRef {
private long address; private volatile long address;
ZStreamRef (long address) { ZStreamRef (long address) {
this.address = address; this.address = address;
} }
......
...@@ -58,7 +58,7 @@ import static java.util.zip.ZipConstants64.*; ...@@ -58,7 +58,7 @@ import static java.util.zip.ZipConstants64.*;
*/ */
public public
class ZipFile implements ZipConstants, Closeable { class ZipFile implements ZipConstants, Closeable {
private long jzfile; // address of jzfile data private long jzfile; // address of jzfile data
private final String name; // zip file name private final String name; // zip file name
private final int total; // total number of entries private final int total; // total number of entries
private final boolean locsig; // if zip file starts with LOCSIG (usually true) private final boolean locsig; // if zip file starts with LOCSIG (usually true)
...@@ -685,7 +685,7 @@ class ZipFile implements ZipConstants, Closeable { ...@@ -685,7 +685,7 @@ class ZipFile implements ZipConstants, Closeable {
* (possibly compressed) zip file entry. * (possibly compressed) zip file entry.
*/ */
private class ZipFileInputStream extends InputStream { private class ZipFileInputStream extends InputStream {
private volatile boolean closeRequested = false; private volatile boolean zfisCloseRequested = false;
protected long jzentry; // address of jzentry data protected long jzentry; // address of jzentry data
private long pos; // current position within entry data private long pos; // current position within entry data
protected long rem; // number of remaining bytes within entry protected long rem; // number of remaining bytes within entry
...@@ -712,6 +712,7 @@ class ZipFile implements ZipConstants, Closeable { ...@@ -712,6 +712,7 @@ class ZipFile implements ZipConstants, Closeable {
len = (int) rem; len = (int) rem;
} }
// Check if ZipFile open
ensureOpenOrZipException(); ensureOpenOrZipException();
len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b, len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
off, len); off, len);
...@@ -755,9 +756,9 @@ class ZipFile implements ZipConstants, Closeable { ...@@ -755,9 +756,9 @@ class ZipFile implements ZipConstants, Closeable {
} }
public void close() { public void close() {
if (closeRequested) if (zfisCloseRequested)
return; return;
closeRequested = true; zfisCloseRequested = true;
rem = 0; rem = 0;
synchronized (ZipFile.this) { synchronized (ZipFile.this) {
......
...@@ -78,7 +78,7 @@ public class ListSelectionEvent extends EventObject ...@@ -78,7 +78,7 @@ public class ListSelectionEvent extends EventObject
/** /**
* Returns the index of the first row whose selection may have changed. * Returns the index of the first row whose selection may have changed.
* {@code getFirstIndex() &lt;= getLastIndex()} * {@code getFirstIndex() <= getLastIndex()}
* *
* @return the first row whose selection value may have changed, * @return the first row whose selection value may have changed,
* where zero is the first row * where zero is the first row
...@@ -87,7 +87,7 @@ public class ListSelectionEvent extends EventObject ...@@ -87,7 +87,7 @@ public class ListSelectionEvent extends EventObject
/** /**
* Returns the index of the last row whose selection may have changed. * Returns the index of the last row whose selection may have changed.
* {@code getLastIndex() &gt;= getFirstIndex()} * {@code getLastIndex() >= getFirstIndex()}
* *
* @return the last row whose selection value may have changed, * @return the last row whose selection value may have changed,
* where zero is the first row * where zero is the first row
......
...@@ -682,12 +682,7 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -682,12 +682,7 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
if (toFocus != null) { if (toFocus != null) {
if (parent instanceof EmbeddedFrame) { if (parent instanceof EmbeddedFrame) {
// JDK-8056915: Try to request focus to the embedder first and ((EmbeddedFrame) parent).synthesizeWindowActivation(true);
// activate the embedded frame through it
if (!((EmbeddedFrame) parent).requestFocusToEmbedder()) {
// Otherwise activate the embedded frame directly
((EmbeddedFrame) parent).synthesizeWindowActivation(true);
}
} }
// EmbeddedFrame might have focus before the applet was added. // EmbeddedFrame might have focus before the applet was added.
// Thus after its activation the most recent focus owner will be // Thus after its activation the most recent focus owner will be
......
...@@ -360,15 +360,6 @@ public abstract class EmbeddedFrame extends Frame ...@@ -360,15 +360,6 @@ public abstract class EmbeddedFrame extends Frame
*/ */
public void synthesizeWindowActivation(boolean doActivate) {} public void synthesizeWindowActivation(boolean doActivate) {}
/**
* Requests the focus to the embedder.
*
* @return {@code true} if focus request was successful, and {@code false} otherwise.
*/
public boolean requestFocusToEmbedder() {
return false;
}
/** /**
* Moves this embedded frame to a new location. The top-left corner of * Moves this embedded frame to a new location. The top-left corner of
* the new location is specified by the <code>x</code> and <code>y</code> * the new location is specified by the <code>x</code> and <code>y</code>
......
...@@ -71,6 +71,13 @@ public final class CompositeFont extends Font2D { ...@@ -71,6 +71,13 @@ public final class CompositeFont extends Font2D {
} else { } else {
numSlots = componentNames.length; numSlots = componentNames.length;
} }
/* We will limit the number of slots to 254.
* We store the slot for a glyph id in a byte and we may use one slot
* for an EUDC font, and we may also create a composite
* using this composite as a backup for a physical font.
* So we want to leave space for the two additional slots.
*/
numSlots = (numSlots <= 254) ? numSlots : 254;
/* Only the first "numMetricsSlots" slots are used for font metrics. /* Only the first "numMetricsSlots" slots are used for font metrics.
* the rest are considered "fallback" slots". * the rest are considered "fallback" slots".
......
...@@ -420,14 +420,13 @@ public class FileFontStrike extends PhysicalStrike { ...@@ -420,14 +420,13 @@ public class FileFontStrike extends PhysicalStrike {
/* The following method is called from CompositeStrike as a special case. /* The following method is called from CompositeStrike as a special case.
*/ */
private static final int SLOTZEROMAX = 0xffffff;
int getSlot0GlyphImagePtrs(int[] glyphCodes, long[] images, int len) { int getSlot0GlyphImagePtrs(int[] glyphCodes, long[] images, int len) {
int convertedCnt = 0; int convertedCnt = 0;
for (int i=0; i<len; i++) { for (int i=0; i<len; i++) {
int glyphCode = glyphCodes[i]; int glyphCode = glyphCodes[i];
if (glyphCode >= SLOTZEROMAX) { if (glyphCode >>> 24 != 0) {
return convertedCnt; return convertedCnt;
} else { } else {
convertedCnt++; convertedCnt++;
......
...@@ -295,7 +295,7 @@ public class BytecodeName { ...@@ -295,7 +295,7 @@ public class BytecodeName {
* (The safe name might possibly be mangled to hide further dangerous characters.) * (The safe name might possibly be mangled to hide further dangerous characters.)
* For example, the qualified class name {@code java/lang/String} * For example, the qualified class name {@code java/lang/String}
* will be parsed into the array {@code {"java", '/', "lang", '/', "String"}}. * will be parsed into the array {@code {"java", '/', "lang", '/', "String"}}.
* The name {@code &lt;init&gt;} will be parsed into { '&lt;', "init", '&gt;'}} * The name {@code <init>} will be parsed into {@code {'<', "init", '>'}}.
* The name {@code foo/bar$:baz} will be parsed into * The name {@code foo/bar$:baz} will be parsed into
* {@code {"foo", '/', "bar", '$', ':', "baz"}}. * {@code {"foo", '/', "bar", '$', ':', "baz"}}.
* The name {@code ::\=:foo:\=bar\!baz} will be parsed into * The name {@code ::\=:foo:\=bar\!baz} will be parsed into
......
/* /*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -165,6 +165,10 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { ...@@ -165,6 +165,10 @@ class ThreadImpl implements com.sun.management.ThreadMXBean {
"Invalid maxDepth parameter: " + maxDepth); "Invalid maxDepth parameter: " + maxDepth);
} }
// ids has been verified to be non-null
// an empty array of ids should return an empty array of ThreadInfos
if (ids.length == 0) return new ThreadInfo[0];
Util.checkMonitorAccess(); Util.checkMonitorAccess();
ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls
...@@ -436,6 +440,10 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { ...@@ -436,6 +440,10 @@ class ThreadImpl implements com.sun.management.ThreadMXBean {
boolean lockedMonitors, boolean lockedMonitors,
boolean lockedSynchronizers) { boolean lockedSynchronizers) {
verifyThreadIds(ids); verifyThreadIds(ids);
// ids has been verified to be non-null
// an empty array of ids should return an empty array of ThreadInfos
if (ids.length == 0) return new ThreadInfo[0];
verifyDumpThreads(lockedMonitors, lockedSynchronizers); verifyDumpThreads(lockedMonitors, lockedSynchronizers);
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers); return dumpThreads0(ids, lockedMonitors, lockedSynchronizers);
} }
......
...@@ -23,67 +23,17 @@ ...@@ -23,67 +23,17 @@
* questions. * questions.
*/ */
#include <sys/types.h> package sun.misc;
#include <sys/socket.h>
public interface JavaLangRefAccess {
#ifdef __solaris__
#include <unistd.h> /**
#include <stropts.h> * Help ReferenceHandler thread process next pending
* {@link java.lang.ref.Reference}
#ifndef BSD_COMP *
#define BSD_COMP * @return {@code true} if there was a pending reference and it
#endif * was enqueue-ed or {@code false} if there was no
* pending reference
#endif */
boolean tryHandlePendingReference();
#include <sys/ioctl.h>
#include "jvm.h"
#include "jni_util.h"
#include "net_util.h"
#include "java_net_AbstractPlainDatagramSocketImpl.h"
static jfieldID IO_fd_fdID;
static jfieldID apdsi_fdID;
/*
* Class: java_net_AbstractPlainDatagramSocketImpl
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
apdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
"Ljava/io/FileDescriptor;");
CHECK_NULL(apdsi_fdID);
IO_fd_fdID = NET_GetFileDescriptorID(env);
}
/*
* Class: java_net_AbstractPlainDatagramSocketImpl
* Method: dataAvailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable
(JNIEnv *env, jobject this) {
int fd, retval;
jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID);
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
}
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
if (ioctl(fd, FIONREAD, &retval) < 0) {
return -1;
}
return retval;
} }
...@@ -45,6 +45,7 @@ public class SharedSecrets { ...@@ -45,6 +45,7 @@ public class SharedSecrets {
private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final Unsafe unsafe = Unsafe.getUnsafe();
private static JavaUtilJarAccess javaUtilJarAccess; private static JavaUtilJarAccess javaUtilJarAccess;
private static JavaLangAccess javaLangAccess; private static JavaLangAccess javaLangAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess; private static JavaIOAccess javaIOAccess;
private static JavaNetAccess javaNetAccess; private static JavaNetAccess javaNetAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess; private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
...@@ -76,6 +77,14 @@ public class SharedSecrets { ...@@ -76,6 +77,14 @@ public class SharedSecrets {
return javaLangAccess; return javaLangAccess;
} }
public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
javaLangRefAccess = jlra;
}
public static JavaLangRefAccess getJavaLangRefAccess() {
return javaLangRefAccess;
}
public static void setJavaNetAccess(JavaNetAccess jna) { public static void setJavaNetAccess(JavaNetAccess jna) {
javaNetAccess = jna; javaNetAccess = jna;
} }
......
/* /*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -44,6 +44,7 @@ public class IPAddressUtil { ...@@ -44,6 +44,7 @@ public class IPAddressUtil {
long tmpValue = 0; long tmpValue = 0;
int currByte = 0; int currByte = 0;
boolean newOctet = true;
int len = src.length(); int len = src.length();
if (len == 0 || len > 15) { if (len == 0 || len > 15) {
...@@ -77,11 +78,12 @@ public class IPAddressUtil { ...@@ -77,11 +78,12 @@ public class IPAddressUtil {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
char c = src.charAt(i); char c = src.charAt(i);
if (c == '.') { if (c == '.') {
if (tmpValue < 0 || tmpValue > 0xff || currByte == 3) { if (newOctet || tmpValue < 0 || tmpValue > 0xff || currByte == 3) {
return null; return null;
} }
res[currByte++] = (byte) (tmpValue & 0xff); res[currByte++] = (byte) (tmpValue & 0xff);
tmpValue = 0; tmpValue = 0;
newOctet = true;
} else { } else {
int digit = Character.digit(c, 10); int digit = Character.digit(c, 10);
if (digit < 0) { if (digit < 0) {
...@@ -89,9 +91,10 @@ public class IPAddressUtil { ...@@ -89,9 +91,10 @@ public class IPAddressUtil {
} }
tmpValue *= 10; tmpValue *= 10;
tmpValue += digit; tmpValue += digit;
newOctet = false;
} }
} }
if (tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) { if (newOctet || tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) {
return null; return null;
} }
switch (currByte) { switch (currByte) {
......
...@@ -328,6 +328,7 @@ public class FileChannelImpl ...@@ -328,6 +328,7 @@ public class FileChannelImpl
int rv = -1; int rv = -1;
long p = -1; long p = -1;
int ti = -1; int ti = -1;
long rp = -1;
try { try {
begin(); begin();
ti = threads.add(); ti = threads.add();
...@@ -363,8 +364,8 @@ public class FileChannelImpl ...@@ -363,8 +364,8 @@ public class FileChannelImpl
if (p > newSize) if (p > newSize)
p = newSize; p = newSize;
do { do {
rv = (int)position0(fd, p); rp = position0(fd, p);
} while ((rv == IOStatus.INTERRUPTED) && isOpen()); } while ((rp == IOStatus.INTERRUPTED) && isOpen());
return this; return this;
} finally { } finally {
threads.remove(ti); threads.remove(ti);
......
...@@ -216,57 +216,55 @@ class KeyStoreDelegator extends KeyStoreSpi { ...@@ -216,57 +216,55 @@ class KeyStoreDelegator extends KeyStoreSpi {
} else { } else {
// First try the primary keystore then try the secondary keystore // First try the primary keystore then try the secondary keystore
try (InputStream bufferedStream = new BufferedInputStream(stream)) { InputStream bufferedStream = new BufferedInputStream(stream);
bufferedStream.mark(Integer.MAX_VALUE); bufferedStream.mark(Integer.MAX_VALUE);
try {
keystore = primaryKeyStore.newInstance();
type = primaryType;
keystore.engineLoad(bufferedStream, password);
} catch (Exception e) {
// incorrect password
if (e instanceof IOException &&
e.getCause() instanceof UnrecoverableKeyException) {
throw (IOException)e;
}
try { try {
keystore = primaryKeyStore.newInstance(); keystore = secondaryKeyStore.newInstance();
type = primaryType; type = secondaryType;
bufferedStream.reset();
keystore.engineLoad(bufferedStream, password); keystore.engineLoad(bufferedStream, password);
} catch (Exception e) { if (debug != null) {
debug.println("WARNING: switching from " +
primaryType + " to " + secondaryType +
" keystore file format has altered the " +
"keystore security level");
}
} catch (InstantiationException |
IllegalAccessException e2) {
// can safely ignore
} catch (IOException |
NoSuchAlgorithmException |
CertificateException e3) {
// incorrect password // incorrect password
if (e instanceof IOException && if (e3 instanceof IOException &&
e.getCause() instanceof UnrecoverableKeyException) { e3.getCause() instanceof
throw (IOException)e; UnrecoverableKeyException) {
throw (IOException)e3;
} }
// rethrow the outer exception
try { if (e instanceof IOException) {
keystore = secondaryKeyStore.newInstance(); throw (IOException)e;
type = secondaryType; } else if (e instanceof CertificateException) {
bufferedStream.reset(); throw (CertificateException)e;
keystore.engineLoad(bufferedStream, password); } else if (e instanceof NoSuchAlgorithmException) {
throw (NoSuchAlgorithmException)e;
if (debug != null) {
debug.println("WARNING: switching from " +
primaryType + " to " + secondaryType +
" keystore file format has altered the " +
"keystore security level");
}
} catch (InstantiationException |
IllegalAccessException e2) {
// can safely ignore
} catch (IOException |
NoSuchAlgorithmException |
CertificateException e3) {
// incorrect password
if (e3 instanceof IOException &&
e3.getCause() instanceof
UnrecoverableKeyException) {
throw (IOException)e3;
}
// rethrow the outer exception
if (e instanceof IOException) {
throw (IOException)e;
} else if (e instanceof CertificateException) {
throw (CertificateException)e;
} else if (e instanceof NoSuchAlgorithmException) {
throw (NoSuchAlgorithmException)e;
}
} }
} }
} }
......
...@@ -102,8 +102,8 @@ public abstract class Builder { ...@@ -102,8 +102,8 @@ public abstract class Builder {
/** /**
* Verifies whether the input certificate completes the path. * Verifies whether the input certificate completes the path.
* When building forward, a trust anchor will complete the path. * When building in the forward direction, a trust anchor will
* When building reverse, the target certificate will complete the path. * complete the path.
* *
* @param cert the certificate to test * @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path. * @return a boolean value indicating whether the cert completes the path.
......
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
package sun.security.provider.certpath; package sun.security.provider.certpath;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.cert.*; import java.security.cert.*;
import java.security.interfaces.DSAPublicKey; import java.security.interfaces.DSAPublicKey;
...@@ -194,7 +193,6 @@ class PKIX { ...@@ -194,7 +193,6 @@ class PKIX {
static class BuilderParams extends ValidatorParams { static class BuilderParams extends ValidatorParams {
private PKIXBuilderParameters params; private PKIXBuilderParameters params;
private boolean buildForward = true;
private List<CertStore> stores; private List<CertStore> stores;
private X500Principal targetSubject; private X500Principal targetSubject;
...@@ -213,10 +211,6 @@ class PKIX { ...@@ -213,10 +211,6 @@ class PKIX {
+ "targetCertConstraints parameter must be an " + "targetCertConstraints parameter must be an "
+ "X509CertSelector"); + "X509CertSelector");
} }
if (params instanceof SunCertPathBuilderParameters) {
buildForward =
((SunCertPathBuilderParameters)params).getBuildForward();
}
this.params = params; this.params = params;
this.targetSubject = getTargetSubject( this.targetSubject = getTargetSubject(
certStores(), (X509CertSelector)targetCertConstraints()); certStores(), (X509CertSelector)targetCertConstraints());
...@@ -230,7 +224,6 @@ class PKIX { ...@@ -230,7 +224,6 @@ class PKIX {
return stores; return stores;
} }
int maxPathLength() { return params.getMaxPathLength(); } int maxPathLength() { return params.getMaxPathLength(); }
boolean buildForward() { return buildForward; }
PKIXBuilderParameters params() { return params; } PKIXBuilderParameters params() { return params; }
X500Principal targetSubject() { return targetSubject; } X500Principal targetSubject() { return targetSubject; }
......
/*
* Copyright (c) 2000, 2013, 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.security.provider.certpath;
import java.io.IOException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.PKIXRevocationChecker;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
import sun.security.provider.certpath.PKIX.BuilderParams;
import sun.security.util.Debug;
import sun.security.x509.NameConstraintsExtension;
import sun.security.x509.SubjectKeyIdentifierExtension;
import sun.security.x509.X509CertImpl;
/**
* A specification of a reverse PKIX validation state
* which is initialized by each build and updated each time a
* certificate is added to the current path.
* @since 1.4
* @author Sean Mullan
* @author Yassir Elley
*/
class ReverseState implements State {
private static final Debug debug = Debug.getInstance("certpath");
/* The subject DN of the last cert in the path */
X500Principal subjectDN;
/* The subject public key of the last cert */
PublicKey pubKey;
/* The subject key identifier extension (if any) of the last cert */
SubjectKeyIdentifierExtension subjKeyId;
/* The PKIX constrained/excluded subtrees state variable */
NameConstraintsExtension nc;
/* The PKIX explicit policy, policy mapping, and inhibit_any-policy
state variables */
int explicitPolicy;
int policyMapping;
int inhibitAnyPolicy;
int certIndex;
PolicyNodeImpl rootNode;
/* The number of remaining CA certs which may follow in the path.
* -1: previous cert was an EE cert
* 0: only EE certs may follow.
* >0 and <Integer.MAX_VALUE:no more than this number of CA certs may follow
* Integer.MAX_VALUE: unlimited
*/
int remainingCACerts;
/* The list of user-defined checkers retrieved from the PKIXParameters
* instance */
ArrayList<PKIXCertPathChecker> userCheckers;
/* Flag indicating if state is initial (path is just starting) */
private boolean init = true;
/* the checker used for revocation status */
RevocationChecker revChecker;
/* the algorithm checker */
AlgorithmChecker algorithmChecker;
/* the untrusted certificates checker */
UntrustedChecker untrustedChecker;
/* the trust anchor used to validate the path */
TrustAnchor trustAnchor;
/* Flag indicating if current cert can vouch for the CRL for
* the next cert
*/
boolean crlSign = true;
/**
* Returns a boolean flag indicating if the state is initial
* (just starting)
*
* @return boolean flag indicating if the state is initial (just starting)
*/
@Override
public boolean isInitial() {
return init;
}
/**
* Display state for debugging purposes
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("State [");
sb.append("\n subjectDN of last cert: ").append(subjectDN);
sb.append("\n subjectKeyIdentifier: ").append
(String.valueOf(subjKeyId));
sb.append("\n nameConstraints: ").append(String.valueOf(nc));
sb.append("\n certIndex: ").append(certIndex);
sb.append("\n explicitPolicy: ").append(explicitPolicy);
sb.append("\n policyMapping: ").append(policyMapping);
sb.append("\n inhibitAnyPolicy: ").append(inhibitAnyPolicy);
sb.append("\n rootNode: ").append(rootNode);
sb.append("\n remainingCACerts: ").append(remainingCACerts);
sb.append("\n crlSign: ").append(crlSign);
sb.append("\n init: ").append(init);
sb.append("\n]\n");
return sb.toString();
}
/**
* Initialize the state.
*
* @param buildParams builder parameters
*/
public void initState(BuilderParams buildParams)
throws CertPathValidatorException
{
/*
* Initialize number of remainingCACerts.
* Note that -1 maxPathLen implies unlimited.
* 0 implies only an EE cert is acceptable.
*/
int maxPathLen = buildParams.maxPathLength();
remainingCACerts = (maxPathLen == -1) ? Integer.MAX_VALUE
: maxPathLen;
/* Initialize explicit policy state variable */
if (buildParams.explicitPolicyRequired()) {
explicitPolicy = 0;
} else {
// unconstrained if maxPathLen is -1,
// otherwise, we want to initialize this to the value of the
// longest possible path + 1 (i.e. maxpathlen + finalcert + 1)
explicitPolicy = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2;
}
/* Initialize policy mapping state variable */
if (buildParams.policyMappingInhibited()) {
policyMapping = 0;
} else {
policyMapping = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2;
}
/* Initialize inhibit any policy state variable */
if (buildParams.anyPolicyInhibited()) {
inhibitAnyPolicy = 0;
} else {
inhibitAnyPolicy = (maxPathLen == -1) ? maxPathLen : maxPathLen + 2;
}
/* Initialize certIndex */
certIndex = 1;
/* Initialize policy tree */
Set<String> initExpPolSet = new HashSet<>(1);
initExpPolSet.add(PolicyChecker.ANY_POLICY);
rootNode = new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null,
false, initExpPolSet, false);
/*
* Initialize each user-defined checker
* Shallow copy the checkers
*/
userCheckers = new ArrayList<>(buildParams.certPathCheckers());
/* initialize each checker (just in case) */
for (PKIXCertPathChecker checker : userCheckers) {
checker.init(false);
}
/* Start by trusting the cert to sign CRLs */
crlSign = true;
init = true;
}
/**
* Update the state with the specified trust anchor.
*
* @param anchor the most-trusted CA
* @param buildParams builder parameters
*/
public void updateState(TrustAnchor anchor, BuilderParams buildParams)
throws CertificateException, IOException, CertPathValidatorException
{
trustAnchor = anchor;
X509Certificate trustedCert = anchor.getTrustedCert();
if (trustedCert != null) {
updateState(trustedCert);
} else {
X500Principal caName = anchor.getCA();
updateState(anchor.getCAPublicKey(), caName);
}
// The user specified AlgorithmChecker and RevocationChecker may not be
// able to set the trust anchor until now.
boolean revCheckerAdded = false;
for (PKIXCertPathChecker checker : userCheckers) {
if (checker instanceof AlgorithmChecker) {
((AlgorithmChecker)checker).trySetTrustAnchor(anchor);
} else if (checker instanceof PKIXRevocationChecker) {
if (revCheckerAdded) {
throw new CertPathValidatorException(
"Only one PKIXRevocationChecker can be specified");
}
// if it's our own, initialize it
if (checker instanceof RevocationChecker) {
((RevocationChecker)checker).init(anchor, buildParams);
}
((PKIXRevocationChecker)checker).init(false);
revCheckerAdded = true;
}
}
// only create a RevocationChecker if revocation is enabled and
// a PKIXRevocationChecker has not already been added
if (buildParams.revocationEnabled() && !revCheckerAdded) {
revChecker = new RevocationChecker(anchor, buildParams);
revChecker.init(false);
}
init = false;
}
/**
* Update the state. This method is used when the most-trusted CA is
* a trusted public-key and caName, instead of a trusted cert.
*
* @param pubKey the public key of the trusted CA
* @param subjectDN the subject distinguished name of the trusted CA
*/
private void updateState(PublicKey pubKey, X500Principal subjectDN) {
/* update subject DN */
this.subjectDN = subjectDN;
/* update subject public key */
this.pubKey = pubKey;
}
/**
* Update the state with the next certificate added to the path.
*
* @param cert the certificate which is used to update the state
*/
public void updateState(X509Certificate cert)
throws CertificateException, IOException, CertPathValidatorException {
if (cert == null) {
return;
}
/* update subject DN */
subjectDN = cert.getSubjectX500Principal();
/* check for key needing to inherit alg parameters */
X509CertImpl icert = X509CertImpl.toImpl(cert);
PublicKey newKey = cert.getPublicKey();
if (PKIX.isDSAPublicKeyWithoutParams(newKey)) {
newKey = BasicChecker.makeInheritedParamsKey(newKey, pubKey);
}
/* update subject public key */
pubKey = newKey;
/*
* if this is a trusted cert (init == true), then we
* don't update any of the remaining fields
*/
if (init) {
init = false;
return;
}
/* update subject key identifier */
subjKeyId = icert.getSubjectKeyIdentifierExtension();
/* update crlSign */
crlSign = RevocationChecker.certCanSignCrl(cert);
/* update current name constraints */
if (nc != null) {
nc.merge(icert.getNameConstraintsExtension());
} else {
nc = icert.getNameConstraintsExtension();
if (nc != null) {
// Make sure we do a clone here, because we're probably
// going to modify this object later and we don't want to
// be sharing it with a Certificate object!
nc = (NameConstraintsExtension) nc.clone();
}
}
/* update policy state variables */
explicitPolicy =
PolicyChecker.mergeExplicitPolicy(explicitPolicy, icert, false);
policyMapping =
PolicyChecker.mergePolicyMapping(policyMapping, icert);
inhibitAnyPolicy =
PolicyChecker.mergeInhibitAnyPolicy(inhibitAnyPolicy, icert);
certIndex++;
/*
* Update remaining CA certs
*/
remainingCACerts =
ConstraintsChecker.mergeBasicConstraints(cert, remainingCACerts);
init = false;
}
/**
* Returns a boolean flag indicating if a key lacking necessary key
* algorithm parameters has been encountered.
*
* @return boolean flag indicating if key lacking parameters encountered.
*/
@Override
public boolean keyParamsNeeded() {
/* when building in reverse, we immediately get parameters needed
* or else throw an exception
*/
return false;
}
/*
* Clone current state. The state is cloned as each cert is
* added to the path. This is necessary if backtracking occurs,
* and a prior state needs to be restored.
*
* Note that this is a SMART clone. Not all fields are fully copied,
* because some of them (e.g., subjKeyId) will
* not have their contents modified by subsequent calls to updateState.
*/
@Override
@SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly
public Object clone() {
try {
ReverseState clonedState = (ReverseState) super.clone();
/* clone checkers, if cloneable */
clonedState.userCheckers =
(ArrayList<PKIXCertPathChecker>)userCheckers.clone();
ListIterator<PKIXCertPathChecker> li =
clonedState.userCheckers.listIterator();
while (li.hasNext()) {
PKIXCertPathChecker checker = li.next();
if (checker instanceof Cloneable) {
li.set((PKIXCertPathChecker)checker.clone());
}
}
/* make copy of name constraints */
if (nc != null) {
clonedState.nc = (NameConstraintsExtension) nc.clone();
}
/* make copy of policy tree */
if (rootNode != null) {
clonedState.rootNode = rootNode.copyTree();
}
return clonedState;
} catch (CloneNotSupportedException e) {
throw new InternalError(e.toString(), e);
}
}
}
...@@ -35,8 +35,6 @@ import java.security.cert.PKIXReason; ...@@ -35,8 +35,6 @@ import java.security.cert.PKIXReason;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Set; import java.util.Set;
...@@ -47,8 +45,7 @@ import static sun.security.x509.PKIXExtensions.*; ...@@ -47,8 +45,7 @@ import static sun.security.x509.PKIXExtensions.*;
import sun.security.util.Debug; import sun.security.util.Debug;
/** /**
* This class is able to build certification paths in either the forward * This class builds certification paths in the forward direction.
* or reverse directions.
* *
* <p> If successful, it returns a certification path which has successfully * <p> If successful, it returns a certification path which has successfully
* satisfied all the constraints and requirements specified in the * satisfied all the constraints and requirements specified in the
...@@ -102,10 +99,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { ...@@ -102,10 +99,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
/** /**
* Attempts to build a certification path using the Sun build * Attempts to build a certification path using the Sun build
* algorithm from a trusted anchor(s) to a target subject, which must both * algorithm from a trusted anchor(s) to a target subject, which must both
* be specified in the input parameter set. By default, this method will * be specified in the input parameter set. This method will
* attempt to build in the forward direction. In order to build in the * attempt to build in the forward direction: from the target to the CA.
* reverse direction, the caller needs to pass in an instance of
* SunCertPathBuilderParameters with the buildForward flag set to false.
* *
* <p>The certification path that is constructed is validated * <p>The certification path that is constructed is validated
* according to the PKIX specification. * according to the PKIX specification.
...@@ -162,11 +157,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { ...@@ -162,11 +157,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
policyTreeResult = null; policyTreeResult = null;
LinkedList<X509Certificate> certPathList = new LinkedList<>(); LinkedList<X509Certificate> certPathList = new LinkedList<>();
try { try {
if (buildParams.buildForward()) { buildForward(adjList, certPathList, searchAllCertStores);
buildForward(adjList, certPathList, searchAllCertStores);
} else {
buildReverse(adjList, certPathList);
}
} catch (GeneralSecurityException | IOException e) { } catch (GeneralSecurityException | IOException e) {
if (debug != null) { if (debug != null) {
debug.println("SunCertPathBuilder.engineBuild() exception in " debug.println("SunCertPathBuilder.engineBuild() exception in "
...@@ -209,81 +200,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { ...@@ -209,81 +200,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
return null; return null;
} }
/*
* Private build reverse method.
*/
private void buildReverse(List<List<Vertex>> adjacencyList,
LinkedList<X509Certificate> certPathList)
throws GeneralSecurityException, IOException
{
if (debug != null) {
debug.println("SunCertPathBuilder.buildReverse()...");
debug.println("SunCertPathBuilder.buildReverse() InitialPolicies: "
+ buildParams.initialPolicies());
}
ReverseState currentState = new ReverseState();
/* Initialize adjacency list */
adjacencyList.clear();
adjacencyList.add(new LinkedList<Vertex>());
/*
* Perform a search using each trust anchor, until a valid
* path is found
*/
Iterator<TrustAnchor> iter = buildParams.trustAnchors().iterator();
while (iter.hasNext()) {
TrustAnchor anchor = iter.next();
/* check if anchor satisfies target constraints */
if (anchorIsTarget(anchor, buildParams.targetCertConstraints())) {
this.trustAnchor = anchor;
this.pathCompleted = true;
this.finalPublicKey = anchor.getTrustedCert().getPublicKey();
break;
}
// skip anchor if it contains a DSA key with no DSA params
X509Certificate trustedCert = anchor.getTrustedCert();
PublicKey pubKey = trustedCert != null ? trustedCert.getPublicKey()
: anchor.getCAPublicKey();
if (PKIX.isDSAPublicKeyWithoutParams(pubKey)) {
continue;
}
/* Initialize current state */
currentState.initState(buildParams);
currentState.updateState(anchor, buildParams);
currentState.algorithmChecker = new AlgorithmChecker(anchor);
currentState.untrustedChecker = new UntrustedChecker();
try {
depthFirstSearchReverse(null, currentState,
new ReverseBuilder(buildParams),
adjacencyList, certPathList);
} catch (GeneralSecurityException | IOException e) {
// continue on error if more anchors to try
if (iter.hasNext())
continue;
else
throw e;
}
// break out of loop if search is successful
if (pathCompleted) {
break;
}
}
if (debug != null) {
debug.println("SunCertPathBuilder.buildReverse() returned from "
+ "depthFirstSearchReverse()");
debug.println("SunCertPathBuilder.buildReverse() "
+ "certPathList.size: " + certPathList.size());
}
}
/* /*
* Private build forward method. * Private build forward method.
*/ */
...@@ -631,147 +547,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi { ...@@ -631,147 +547,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
} }
} }
/*
* This method performs a depth first search for a certification
* path while building reverse which meets the requirements set in
* the parameters object.
* It uses an adjacency list to store all certificates which were
* tried (i.e. at one time added to the path - they may not end up in
* the final path if backtracking occurs). This information can
* be used later to debug or demo the build.
*
* See "Data Structure and Algorithms, by Aho, Hopcroft, and Ullman"
* for an explanation of the DFS algorithm.
*
* @param dN the distinguished name being currently searched for certs
* @param currentState the current PKIX validation state
*/
private void depthFirstSearchReverse(X500Principal dN,
ReverseState currentState,
ReverseBuilder builder,
List<List<Vertex>> adjList,
LinkedList<X509Certificate> cpList)
throws GeneralSecurityException, IOException
{
if (debug != null)
debug.println("SunCertPathBuilder.depthFirstSearchReverse(" + dN
+ ", " + currentState.toString() + ")");
/*
* Find all the certificates issued by dN which
* satisfy the PKIX certification path constraints.
*/
Collection<X509Certificate> certs =
builder.getMatchingCerts(currentState, buildParams.certStores());
List<Vertex> vertices = addVertices(certs, adjList);
if (debug != null)
debug.println("SunCertPathBuilder.depthFirstSearchReverse(): "
+ "certs.size=" + vertices.size());
/*
* For each cert in the collection, verify anything
* that hasn't been checked yet (signature, revocation, etc)
* and check for loops. Call depthFirstSearchReverse()
* recursively for each good cert.
*/
for (Vertex vertex : vertices) {
/**
* Restore state to currentState each time through the loop.
* This is important because some of the user-defined
* checkers modify the state, which MUST be restored if
* the cert eventually fails to lead to the target and
* the next matching cert is tried.
*/
ReverseState nextState = (ReverseState) currentState.clone();
X509Certificate cert = vertex.getCertificate();
try {
builder.verifyCert(cert, nextState, cpList);
} catch (GeneralSecurityException gse) {
if (debug != null)
debug.println("SunCertPathBuilder.depthFirstSearchReverse()"
+ ": validation failed: " + gse);
vertex.setThrowable(gse);
continue;
}
/*
* Certificate is good, add it to the path (if it isn't a
* self-signed cert) and update state
*/
if (!currentState.isInitial())
builder.addCertToPath(cert, cpList);
// save trust anchor
this.trustAnchor = currentState.trustAnchor;
/*
* Check if path is completed, return ASAP if so.
*/
if (builder.isPathCompleted(cert)) {
if (debug != null)
debug.println("SunCertPathBuilder.depthFirstSearchReverse()"
+ ": path completed!");
pathCompleted = true;
PolicyNodeImpl rootNode = nextState.rootNode;
if (rootNode == null)
policyTreeResult = null;
else {
policyTreeResult = rootNode.copyTree();
((PolicyNodeImpl)policyTreeResult).setImmutable();
}
/*
* Extract and save the final target public key
*/
finalPublicKey = cert.getPublicKey();
if (PKIX.isDSAPublicKeyWithoutParams(finalPublicKey)) {
finalPublicKey =
BasicChecker.makeInheritedParamsKey
(finalPublicKey, currentState.pubKey);
}
return;
}
/* Update the PKIX state */
nextState.updateState(cert);
/*
* Append an entry for cert in adjacency list and
* set index for current vertex.
*/
adjList.add(new LinkedList<Vertex>());
vertex.setIndex(adjList.size() - 1);
/* recursively search for matching certs at next dN */
depthFirstSearchReverse(cert.getSubjectX500Principal(), nextState,
builder, adjList, cpList);
/*
* If path has been completed, return ASAP!
*/
if (pathCompleted) {
return;
} else {
/*
* If we get here, it means we have searched all possible
* certs issued by the dN w/o finding any matching certs. This
* means we have to backtrack to the previous cert in the path
* and try some other paths.
*/
if (debug != null)
debug.println("SunCertPathBuilder.depthFirstSearchReverse()"
+ ": backtracking");
if (!currentState.isInitial())
builder.removeFinalCertFromPath(cpList);
}
}
if (debug != null)
debug.println("SunCertPathBuilder.depthFirstSearchReverse() all "
+ "certs in this adjacency list checked");
}
/* /*
* Adds a collection of matching certificates to the * Adds a collection of matching certificates to the
* adjacency list. * adjacency list.
......
/*
* Copyright (c) 2000, 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.security.provider.certpath;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.*;
import java.util.Set;
/**
* This class specifies the set of parameters used as input for the Sun
* certification path build algorithm. It is identical to PKIXBuilderParameters
* with the addition of a <code>buildForward</code> parameter which allows
* the caller to specify whether or not the path should be constructed in
* the forward direction.
*
* The default for the <code>buildForward</code> parameter is
* true, which means that the build algorithm should construct paths
* from the target subject back to the trusted anchor.
*
* @since 1.4
* @author Sean Mullan
* @author Yassir Elley
*/
public class SunCertPathBuilderParameters extends PKIXBuilderParameters {
private boolean buildForward = true;
/**
* Creates an instance of <code>SunCertPathBuilderParameters</code> with the
* specified parameter values.
*
* @param trustAnchors a <code>Set</code> of <code>TrustAnchor</code>s
* @param targetConstraints a <code>CertSelector</code> specifying the
* constraints on the target certificate
* @throws InvalidAlgorithmParameterException if the specified
* <code>Set</code> is empty <code>(trustAnchors.isEmpty() == true)</code>
* @throws NullPointerException if the specified <code>Set</code> is
* <code>null</code>
* @throws ClassCastException if any of the elements in the <code>Set</code>
* are not of type <code>java.security.cert.TrustAnchor</code>
*/
public SunCertPathBuilderParameters(Set<TrustAnchor> trustAnchors,
CertSelector targetConstraints) throws InvalidAlgorithmParameterException
{
super(trustAnchors, targetConstraints);
setBuildForward(true);
}
/**
* Creates an instance of <code>SunCertPathBuilderParameters</code> that
* uses the specified <code>KeyStore</code> to populate the set
* of most-trusted CA certificates.
*
* @param keystore A keystore from which the set of most-trusted
* CA certificates will be populated.
* @param targetConstraints a <code>CertSelector</code> specifying the
* constraints on the target certificate
* @throws KeyStoreException if the keystore has not been initialized.
* @throws InvalidAlgorithmParameterException if the keystore does
* not contain at least one trusted certificate entry
* @throws NullPointerException if the keystore is <code>null</code>
*/
public SunCertPathBuilderParameters(KeyStore keystore,
CertSelector targetConstraints)
throws KeyStoreException, InvalidAlgorithmParameterException
{
super(keystore, targetConstraints);
setBuildForward(true);
}
/**
* Returns the value of the buildForward flag.
*
* @return the value of the buildForward flag
*/
public boolean getBuildForward() {
return this.buildForward;
}
/**
* Sets the value of the buildForward flag. If true, paths
* are built from the target subject to the trusted anchor.
* If false, paths are built from the trusted anchor to the
* target subject. The default value if not specified is true.
*
* @param buildForward the value of the buildForward flag
*/
public void setBuildForward(boolean buildForward) {
this.buildForward = buildForward;
}
/**
* Returns a formatted string describing the parameters.
*
* @return a formatted string describing the parameters.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[\n");
sb.append(super.toString());
sb.append(" Build Forward Flag: " + String.valueOf(buildForward) + "\n");
sb.append("]\n");
return sb.toString();
}
}
...@@ -47,7 +47,8 @@ public final class TimeZoneNames_en_GB extends TimeZoneNamesBundle { ...@@ -47,7 +47,8 @@ public final class TimeZoneNames_en_GB extends TimeZoneNamesBundle {
protected final Object[][] getContents() { protected final Object[][] getContents() {
return new Object[][] { return new Object[][] {
{"Europe/London", new String[] {"Greenwich Mean Time", "GMT", {"Europe/London", new String[] {"Greenwich Mean Time", "GMT",
"British Summer Time", "BST"}}, "British Summer Time", "BST",
"British Time", "BT"}},
}; };
} }
} }
...@@ -40,7 +40,8 @@ public final class TimeZoneNames_hi extends TimeZoneNamesBundle { ...@@ -40,7 +40,8 @@ public final class TimeZoneNames_hi extends TimeZoneNamesBundle {
{"Asia/Calcutta", {"Asia/Calcutta",
new String[] { new String[] {
"\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IST", "\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IST",
"\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IST" "\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IST",
"\u092d\u093e\u0930\u0924\u0940\u092f \u0938\u092e\u092f", "IT"
} }
}, },
}; };
......
...@@ -391,6 +391,7 @@ void* getProcessHandle(); ...@@ -391,6 +391,7 @@ void* getProcessHandle();
void buildJniFunctionName(const char *sym, const char *cname, void buildJniFunctionName(const char *sym, const char *cname,
char *jniEntryName); char *jniEntryName);
extern int getErrorString(int err, char *buf, size_t len);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif /* __cplusplus */ #endif /* __cplusplus */
......
/* /*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -49,13 +49,21 @@ JNIEXPORT void JNICALL ...@@ -49,13 +49,21 @@ JNIEXPORT void JNICALL
Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls) Java_java_util_zip_Deflater_initIDs(JNIEnv *env, jclass cls)
{ {
levelID = (*env)->GetFieldID(env, cls, "level", "I"); levelID = (*env)->GetFieldID(env, cls, "level", "I");
CHECK_NULL(levelID);
strategyID = (*env)->GetFieldID(env, cls, "strategy", "I"); strategyID = (*env)->GetFieldID(env, cls, "strategy", "I");
CHECK_NULL(strategyID);
setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z"); setParamsID = (*env)->GetFieldID(env, cls, "setParams", "Z");
CHECK_NULL(setParamsID);
finishID = (*env)->GetFieldID(env, cls, "finish", "Z"); finishID = (*env)->GetFieldID(env, cls, "finish", "Z");
CHECK_NULL(finishID);
finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
CHECK_NULL(finishedID);
bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
CHECK_NULL(bufID);
offID = (*env)->GetFieldID(env, cls, "off", "I"); offID = (*env)->GetFieldID(env, cls, "off", "I");
CHECK_NULL(offID);
lenID = (*env)->GetFieldID(env, cls, "len", "I"); lenID = (*env)->GetFieldID(env, cls, "len", "I");
CHECK_NULL(lenID);
} }
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
...@@ -137,14 +145,14 @@ Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, ...@@ -137,14 +145,14 @@ Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr,
in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
if (in_buf == NULL) { if (in_buf == NULL) {
// Throw OOME only when length is not zero // Throw OOME only when length is not zero
if (this_len != 0) if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL)
JNU_ThrowOutOfMemoryError(env, 0); JNU_ThrowOutOfMemoryError(env, 0);
return 0; return 0;
} }
out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
if (out_buf == NULL) { if (out_buf == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
if (len != 0) if (len != 0 && (*env)->ExceptionOccurred(env) == NULL)
JNU_ThrowOutOfMemoryError(env, 0); JNU_ThrowOutOfMemoryError(env, 0);
return 0; return 0;
} }
...@@ -163,7 +171,7 @@ Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr, ...@@ -163,7 +171,7 @@ Java_java_util_zip_Deflater_deflateBytes(JNIEnv *env, jobject this, jlong addr,
this_off += this_len - strm->avail_in; this_off += this_len - strm->avail_in;
(*env)->SetIntField(env, this, offID, this_off); (*env)->SetIntField(env, this, offID, this_off);
(*env)->SetIntField(env, this, lenID, strm->avail_in); (*env)->SetIntField(env, this, lenID, strm->avail_in);
return len - strm->avail_out; return (jint) (len - strm->avail_out);
case Z_BUF_ERROR: case Z_BUF_ERROR:
(*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE); (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
return 0; return 0;
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -50,10 +50,15 @@ JNIEXPORT void JNICALL ...@@ -50,10 +50,15 @@ JNIEXPORT void JNICALL
Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls) Java_java_util_zip_Inflater_initIDs(JNIEnv *env, jclass cls)
{ {
needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z"); needDictID = (*env)->GetFieldID(env, cls, "needDict", "Z");
CHECK_NULL(needDictID);
finishedID = (*env)->GetFieldID(env, cls, "finished", "Z"); finishedID = (*env)->GetFieldID(env, cls, "finished", "Z");
CHECK_NULL(finishedID);
bufID = (*env)->GetFieldID(env, cls, "buf", "[B"); bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
CHECK_NULL(bufID);
offID = (*env)->GetFieldID(env, cls, "off", "I"); offID = (*env)->GetFieldID(env, cls, "off", "I");
CHECK_NULL(offID);
lenID = (*env)->GetFieldID(env, cls, "len", "I"); lenID = (*env)->GetFieldID(env, cls, "len", "I");
CHECK_NULL(lenID);
} }
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
...@@ -127,14 +132,14 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, ...@@ -127,14 +132,14 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0); in_buf = (*env)->GetPrimitiveArrayCritical(env, this_buf, 0);
if (in_buf == NULL) { if (in_buf == NULL) {
if (this_len != 0) if (this_len != 0 && (*env)->ExceptionOccurred(env) == NULL)
JNU_ThrowOutOfMemoryError(env, 0); JNU_ThrowOutOfMemoryError(env, 0);
return 0; return 0;
} }
out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0); out_buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
if (out_buf == NULL) { if (out_buf == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0); (*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
if (len != 0) if (len != 0 && (*env)->ExceptionOccurred(env) == NULL)
JNU_ThrowOutOfMemoryError(env, 0); JNU_ThrowOutOfMemoryError(env, 0);
return 0; return 0;
} }
...@@ -154,7 +159,7 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr, ...@@ -154,7 +159,7 @@ Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
this_off += this_len - strm->avail_in; this_off += this_len - strm->avail_in;
(*env)->SetIntField(env, this, offID, this_off); (*env)->SetIntField(env, this, offID, this_off);
(*env)->SetIntField(env, this, lenID, strm->avail_in); (*env)->SetIntField(env, this, lenID, strm->avail_in);
return len - strm->avail_out; return (jint) (len - strm->avail_out);
case Z_NEED_DICT: case Z_NEED_DICT:
(*env)->SetBooleanField(env, this, needDictID, JNI_TRUE); (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
/* Might have consumed some input here! */ /* Might have consumed some input here! */
......
/* /*
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -71,11 +71,13 @@ ThrowZipException(JNIEnv *env, const char *msg) ...@@ -71,11 +71,13 @@ ThrowZipException(JNIEnv *env, const char *msg)
if (msg != NULL) { if (msg != NULL) {
s = JNU_NewStringPlatform(env, msg); s = JNU_NewStringPlatform(env, msg);
} }
x = JNU_NewObjectByName(env, if (s != NULL) {
x = JNU_NewObjectByName(env,
"java/util/zip/ZipException", "java/util/zip/ZipException",
"(Ljava/lang/String;)V", s); "(Ljava/lang/String;)V", s);
if (x != NULL) { if (x != NULL) {
(*env)->Throw(env, x); (*env)->Throw(env, x);
}
} }
} }
...@@ -363,8 +365,10 @@ Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj) ...@@ -363,8 +365,10 @@ Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)
/* If some names were found then build array of java strings */ /* If some names were found then build array of java strings */
if (count > 0) { if (count > 0) {
jclass cls = (*env)->FindClass(env, "java/lang/String"); jclass cls = JNU_ClassString(env);
CHECK_NULL_RETURN(cls, NULL);
result = (*env)->NewObjectArray(env, count, cls, 0); result = (*env)->NewObjectArray(env, count, cls, 0);
CHECK_NULL_RETURN(result, NULL);
if (result != 0) { if (result != 0) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
jstring str = (*env)->NewStringUTF(env, zip->metanames[i]); jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);
......
...@@ -1314,12 +1314,23 @@ ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry) ...@@ -1314,12 +1314,23 @@ ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry)
jint jint
ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len) ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len)
{ {
jlong entry_size = (entry->csize != 0) ? entry->csize : entry->size; jlong entry_size;
jlong start; jlong start;
if (zip == 0) {
return -1;
}
/* Clear previous zip error */ /* Clear previous zip error */
zip->msg = NULL; zip->msg = NULL;
if (entry == 0) {
zip->msg = "ZIP_Read: jzentry is NULL";
return -1;
}
entry_size = (entry->csize != 0) ? entry->csize : entry->size;
/* Check specified position */ /* Check specified position */
if (pos < 0 || pos > entry_size - 1) { if (pos < 0 || pos > entry_size - 1) {
zip->msg = "ZIP_Read: specified offset out of range"; zip->msg = "ZIP_Read: specified offset out of range";
...@@ -1449,6 +1460,12 @@ jboolean JNICALL ...@@ -1449,6 +1460,12 @@ jboolean JNICALL
ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
{ {
char *msg; char *msg;
char tmpbuf[1024];
if (entry == 0) {
jio_fprintf(stderr, "jzentry was invalid");
return JNI_FALSE;
}
strcpy(entryname, entry->name); strcpy(entryname, entry->name);
if (entry->csize == 0) { if (entry->csize == 0) {
...@@ -1467,8 +1484,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) ...@@ -1467,8 +1484,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
msg = zip->msg; msg = zip->msg;
ZIP_Unlock(zip); ZIP_Unlock(zip);
if (n == -1) { if (n == -1) {
jio_fprintf(stderr, "%s: %s\n", zip->name, if (msg == 0) {
msg != 0 ? msg : strerror(errno)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
msg = tmpbuf;
}
jio_fprintf(stderr, "%s: %s\n", zip->name, msg);
return JNI_FALSE; return JNI_FALSE;
} }
buf += n; buf += n;
...@@ -1481,8 +1501,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname) ...@@ -1481,8 +1501,11 @@ ZIP_ReadEntry(jzfile *zip, jzentry *entry, unsigned char *buf, char *entryname)
if ((msg == NULL) || (*msg == 0)) { if ((msg == NULL) || (*msg == 0)) {
msg = zip->msg; msg = zip->msg;
} }
jio_fprintf(stderr, "%s: %s\n", zip->name, if (msg == 0) {
msg != 0 ? msg : strerror(errno)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
msg = tmpbuf;
}
jio_fprintf(stderr, "%s: %s\n", zip->name, msg);
return JNI_FALSE; return JNI_FALSE;
} }
} }
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
*/ */
/* Copyright (c) 2002 Graz University of Technology. All rights reserved. /* Copyright (c) 2002 Graz University of Technology. All rights reserved.
...@@ -474,6 +474,7 @@ CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriv ...@@ -474,6 +474,7 @@ CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriv
jfieldID fieldID; jfieldID fieldID;
jclass jSsl3RandomDataClass; jclass jSsl3RandomDataClass;
jobject jRandomInfo, jRIClientRandom, jRIServerRandom, jVersion; jobject jRandomInfo, jRIClientRandom, jRIServerRandom, jVersion;
memset(&ckParam, 0, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
/* get RandomInfo */ /* get RandomInfo */
jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS); jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
...@@ -527,6 +528,7 @@ CK_TLS_PRF_PARAMS jTlsPrfParamsToCKTlsPrfParam(JNIEnv *env, jobject jParam) ...@@ -527,6 +528,7 @@ CK_TLS_PRF_PARAMS jTlsPrfParamsToCKTlsPrfParam(JNIEnv *env, jobject jParam)
CK_TLS_PRF_PARAMS ckParam; CK_TLS_PRF_PARAMS ckParam;
jfieldID fieldID; jfieldID fieldID;
jobject jSeed, jLabel, jOutput; jobject jSeed, jLabel, jOutput;
memset(&ckParam, 0, sizeof(CK_TLS_PRF_PARAMS));
// TBD: what if jParam == NULL?! // TBD: what if jParam == NULL?!
...@@ -592,6 +594,7 @@ CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject ...@@ -592,6 +594,7 @@ CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject
jobject jRandomInfo, jRIClientRandom, jRIServerRandom; jobject jRandomInfo, jRIClientRandom, jRIServerRandom;
jobject jReturnedKeyMaterial, jRMIvClient, jRMIvServer; jobject jReturnedKeyMaterial, jRMIvClient, jRMIvServer;
CK_ULONG ckTemp; CK_ULONG ckTemp;
memset(&ckParam, 0, sizeof(CK_SSL3_KEY_MAT_PARAMS));
/* get ulMacSizeInBits */ /* get ulMacSizeInBits */
jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS); jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
...@@ -1355,6 +1358,7 @@ CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobje ...@@ -1355,6 +1358,7 @@ CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobje
jlong jHashAlg, jMgf, jSource; jlong jHashAlg, jMgf, jSource;
jobject jSourceData; jobject jSourceData;
CK_BYTE_PTR ckpByte; CK_BYTE_PTR ckpByte;
memset(&ckParam, 0, sizeof(CK_RSA_PKCS_OAEP_PARAMS));
/* get hashAlg */ /* get hashAlg */
jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS); jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
...@@ -1404,6 +1408,7 @@ CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam) ...@@ -1404,6 +1408,7 @@ CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam)
jlong jIteration; jlong jIteration;
jobject jInitVector, jPassword, jSalt; jobject jInitVector, jPassword, jSalt;
CK_ULONG ckTemp; CK_ULONG ckTemp;
memset(&ckParam, 0, sizeof(CK_PBE_PARAMS));
/* get pInitVector */ /* get pInitVector */
jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS); jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
...@@ -1522,6 +1527,7 @@ CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject j ...@@ -1522,6 +1527,7 @@ CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject j
jfieldID fieldID; jfieldID fieldID;
jlong jSaltSource, jIteration, jPrf; jlong jSaltSource, jIteration, jPrf;
jobject jSaltSourceData, jPrfData; jobject jSaltSourceData, jPrfData;
memset(&ckParam, 0, sizeof(CK_PKCS5_PBKD2_PARAMS));
/* get saltSource */ /* get saltSource */
jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS); jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
...@@ -1734,6 +1740,7 @@ CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env ...@@ -1734,6 +1740,7 @@ CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env
jfieldID fieldID; jfieldID fieldID;
jlong jKdf; jlong jKdf;
jobject jOtherInfo, jPublicData; jobject jOtherInfo, jPublicData;
memset(&ckParam, 0, sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
/* get kdf */ /* get kdf */
jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS); jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
...@@ -1779,6 +1786,7 @@ CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env ...@@ -1779,6 +1786,7 @@ CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env
jfieldID fieldID; jfieldID fieldID;
jlong jKdf, jPrivateDataLen, jPrivateData; jlong jKdf, jPrivateDataLen, jPrivateData;
jobject jOtherInfo, jPublicData, jPublicData2; jobject jOtherInfo, jPublicData, jPublicData2;
memset(&ckParam, 0, sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
/* get kdf */ /* get kdf */
jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS); jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
......
/* /*
* Copyright (c) 2007,2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -119,6 +119,8 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl ...@@ -119,6 +119,8 @@ class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
protected native void disconnect0(int family); protected native void disconnect0(int family);
native int dataAvailable();
/** /**
* Perform class load-time initializations. * Perform class load-time initializations.
*/ */
......
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,91 +23,86 @@ ...@@ -23,91 +23,86 @@
* questions. * questions.
*/ */
#include <windows.h> package sun.awt;
#include <winsock2.h>
#include "jvm.h" import sun.font.FcFontConfiguration;
#include "jni_util.h" import sun.font.FontConfigManager;
#include "net_util.h" import sun.font.SunFontManager;
#include "java_net_AbstractPlainDatagramSocketImpl.h" /**
* A {@link sun.font.FontManager} that uses fontconfig to find system fonts.
static jfieldID IO_fd_fdID = NULL;
static jfieldID apdsi_fdID = NULL;
static jfieldID apdsi_fd1ID = NULL;
static jclass two_stacks_clazz = NULL;
/*
* Class: java_net_AbstractPlainDatagramSocketImpl
* Method: init
* Signature: ()V
*/ */
JNIEXPORT void JNICALL public class FcFontManager extends SunFontManager {
Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
apdsi_fdID = (*env)->GetFieldID(env, cls, "fd", private FontConfigManager fcManager = null;
"Ljava/io/FileDescriptor;");
CHECK_NULL(apdsi_fdID);
IO_fd_fdID = NET_GetFileDescriptorID(env);
CHECK_NULL(IO_fd_fdID);
two_stacks_clazz = (*env)->FindClass(env, "java/net/TwoStacksPlainDatagramSocketImpl"); public synchronized FontConfigManager getFontConfigManager() {
CHECK_NULL(two_stacks_clazz);
/* Handle both TwoStacks and DualStack here */ if (fcManager == null) {
fcManager = new FontConfigManager();
}
if (JNU_Equals(env, cls, two_stacks_clazz)) { return fcManager;
/* fd1 present only in TwoStack.. */
apdsi_fd1ID = (*env)->GetFieldID(env, cls, "fd1",
"Ljava/io/FileDescriptor;");
CHECK_NULL(apdsi_fd1ID);
} }
JNU_CHECK_EXCEPTION(env); @Override
} protected FontConfiguration createFontConfiguration() {
FcFontConfiguration fcFontConfig = new FcFontConfiguration(this);
/* if (fcFontConfig.init()) {
* Class: java_net_AbstractPlainDatagramSocketImpl return fcFontConfig;
* Method: dataAvailable } else {
* Signature: ()I throw new InternalError("failed to initialize fontconfig");
*/ }
JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable }
(JNIEnv *env, jobject this) {
SOCKET fd;
SOCKET fd1;
int rv = -1, rv1 = -1;
jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID);
if (!IS_NULL(fdObj)) { @Override
int retval = 0; public FontConfiguration createFontConfiguration(boolean preferLocaleFonts,
fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID); boolean preferPropFonts) {
rv = ioctlsocket(fd, FIONREAD, &retval); FcFontConfiguration fcFontConfig =
if (retval > 0) { new FcFontConfiguration(this, preferLocaleFonts, preferPropFonts);
return retval; if (fcFontConfig.init()) {
return fcFontConfig;
} else {
throw new InternalError("failed to initialize fontconfig");
} }
} }
if (!IS_NULL(apdsi_fd1ID)) { @Override
/* TwoStacks */ protected String[] getDefaultPlatformFont() {
jobject fd1Obj = (*env)->GetObjectField(env, this, apdsi_fd1ID); final String[] info = new String[2];
if (!IS_NULL(fd1Obj)) { getFontConfigManager().initFontConfigFonts(false);
int retval = 0; FontConfigManager.FcCompFont[] fontConfigFonts =
fd1 = (SOCKET)(*env)->GetIntField(env, fd1Obj, IO_fd_fdID); getFontConfigManager().getFontConfigFonts();
rv1 = ioctlsocket(fd1, FIONREAD, &retval); for (int i=0; i<fontConfigFonts.length; i++) {
if (retval > 0) { if ("sans".equals(fontConfigFonts[i].fcFamily) &&
return retval; 0 == fontConfigFonts[i].style) {
info[0] = fontConfigFonts[i].firstFont.familyName;
info[1] = fontConfigFonts[i].firstFont.fontFile;
break;
} }
} }
/* Absolute last ditch attempt in the face of fontconfig problems.
* If we didn't match, pick the first, or just make something
* up so we don't NPE.
*/
if (info[0] == null) {
if (fontConfigFonts.length > 0 &&
fontConfigFonts[0].firstFont.fontFile != null) {
info[0] = fontConfigFonts[0].firstFont.familyName;
info[1] = fontConfigFonts[0].firstFont.fontFile;
} else {
info[0] = "Dialog";
info[1] = "/dialog.ttf";
}
}
return info;
} }
if (rv < 0 && rv1 < 0) { protected native String getFontPathNative(boolean noType1Fonts,
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", boolean isX11GE);
"Socket closed");
return -1; protected synchronized String getFontPath(boolean noType1Fonts) {
return getFontPathNative(noType1Fonts, false);
} }
return 0;
} }
...@@ -54,7 +54,7 @@ import sun.util.logging.PlatformLogger; ...@@ -54,7 +54,7 @@ import sun.util.logging.PlatformLogger;
/** /**
* The X11 implementation of {@link FontManager}. * The X11 implementation of {@link FontManager}.
*/ */
public final class X11FontManager extends SunFontManager { public final class X11FontManager extends FcFontManager {
// constants identifying XLFD and font ID fields // constants identifying XLFD and font ID fields
private static final int FOUNDRY_FIELD = 1; private static final int FOUNDRY_FIELD = 1;
...@@ -154,8 +154,6 @@ public final class X11FontManager extends SunFontManager { ...@@ -154,8 +154,6 @@ public final class X11FontManager extends SunFontManager {
*/ */
private static String[] fontdirs = null; private static String[] fontdirs = null;
private FontConfigManager fcManager = null;
public static X11FontManager getInstance() { public static X11FontManager getInstance() {
return (X11FontManager) SunFontManager.getInstance(); return (X11FontManager) SunFontManager.getInstance();
} }
...@@ -784,51 +782,9 @@ public final class X11FontManager extends SunFontManager { ...@@ -784,51 +782,9 @@ public final class X11FontManager extends SunFontManager {
preferLocaleFonts, preferPropFonts); preferLocaleFonts, preferPropFonts);
} }
public synchronized native String getFontPathNative(boolean noType1Fonts);
protected synchronized String getFontPath(boolean noType1Fonts) { protected synchronized String getFontPath(boolean noType1Fonts) {
isHeadless(); // make sure GE is inited, as its the X11 lock. isHeadless(); // make sure GE is inited, as its the X11 lock.
return getFontPathNative(noType1Fonts); return getFontPathNative(noType1Fonts, true);
}
@Override
protected String[] getDefaultPlatformFont() {
final String[] info = new String[2];
getFontConfigManager().initFontConfigFonts(false);
FontConfigManager.FcCompFont[] fontConfigFonts =
getFontConfigManager().getFontConfigFonts();
for (int i=0; i<fontConfigFonts.length; i++) {
if ("sans".equals(fontConfigFonts[i].fcFamily) &&
0 == fontConfigFonts[i].style) {
info[0] = fontConfigFonts[i].firstFont.familyName;
info[1] = fontConfigFonts[i].firstFont.fontFile;
break;
}
}
/* Absolute last ditch attempt in the face of fontconfig problems.
* If we didn't match, pick the first, or just make something
* up so we don't NPE.
*/
if (info[0] == null) {
if (fontConfigFonts.length > 0 &&
fontConfigFonts[0].firstFont.fontFile != null) {
info[0] = fontConfigFonts[0].firstFont.familyName;
info[1] = fontConfigFonts[0].firstFont.fontFile;
} else {
info[0] = "Dialog";
info[1] = "/dialog.ttf";
}
}
return info;
}
public synchronized FontConfigManager getFontConfigManager() {
if (fcManager == null) {
fcManager = new FontConfigManager();
}
return fcManager;
} }
@Override @Override
......
...@@ -39,10 +39,10 @@ import java.util.HashMap; ...@@ -39,10 +39,10 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import java.util.Scanner; import java.util.Scanner;
import sun.awt.FcFontManager;
import sun.awt.FontConfiguration; import sun.awt.FontConfiguration;
import sun.awt.FontDescriptor; import sun.awt.FontDescriptor;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.awt.X11FontManager;
import sun.font.CompositeFontDescriptor; import sun.font.CompositeFontDescriptor;
import sun.font.FontManager; import sun.font.FontManager;
import sun.font.FontConfigManager.FontConfigInfo; import sun.font.FontConfigManager.FontConfigInfo;
...@@ -92,7 +92,7 @@ public class FcFontConfiguration extends FontConfiguration { ...@@ -92,7 +92,7 @@ public class FcFontConfiguration extends FontConfiguration {
setFontConfiguration(); setFontConfiguration();
readFcInfo(); readFcInfo();
X11FontManager fm = (X11FontManager) fontManager; FcFontManager fm = (FcFontManager) fontManager;
FontConfigManager fcm = fm.getFontConfigManager(); FontConfigManager fcm = fm.getFontConfigManager();
if (fcCompFonts == null) { if (fcCompFonts == null) {
fcCompFonts = fcm.loadFontConfig(); fcCompFonts = fcm.loadFontConfig();
...@@ -194,7 +194,7 @@ public class FcFontConfiguration extends FontConfiguration { ...@@ -194,7 +194,7 @@ public class FcFontConfiguration extends FontConfiguration {
@Override @Override
public String[] getPlatformFontNames() { public String[] getPlatformFontNames() {
HashSet<String> nameSet = new HashSet<String>(); HashSet<String> nameSet = new HashSet<String>();
X11FontManager fm = (X11FontManager) fontManager; FcFontManager fm = (FcFontManager) fontManager;
FontConfigManager fcm = fm.getFontConfigManager(); FontConfigManager fcm = fm.getFontConfigManager();
FcCompFont[] fcCompFonts = fcm.loadFontConfig(); FcCompFont[] fcCompFonts = fcm.loadFontConfig();
for (int i=0; i<fcCompFonts.length; i++) { for (int i=0; i<fcCompFonts.length; i++) {
...@@ -235,7 +235,7 @@ public class FcFontConfiguration extends FontConfiguration { ...@@ -235,7 +235,7 @@ public class FcFontConfiguration extends FontConfiguration {
@Override @Override
public CompositeFontDescriptor[] get2DCompositeFontInfo() { public CompositeFontDescriptor[] get2DCompositeFontInfo() {
X11FontManager fm = (X11FontManager) fontManager; FcFontManager fm = (FcFontManager) fontManager;
FontConfigManager fcm = fm.getFontConfigManager(); FontConfigManager fcm = fm.getFontConfigManager();
FcCompFont[] fcCompFonts = fcm.loadFontConfig(); FcCompFont[] fcCompFonts = fcm.loadFontConfig();
...@@ -368,7 +368,7 @@ public class FcFontConfiguration extends FontConfiguration { ...@@ -368,7 +368,7 @@ public class FcFontConfiguration extends FontConfiguration {
private void writeFcInfo() { private void writeFcInfo() {
Properties props = new Properties(); Properties props = new Properties();
props.setProperty("version", fileVersion); props.setProperty("version", fileVersion);
X11FontManager fm = (X11FontManager) fontManager; FcFontManager fm = (FcFontManager) fontManager;
FontConfigManager fcm = fm.getFontConfigManager(); FontConfigManager fcm = fm.getFontConfigManager();
FontConfigInfo fcInfo = fcm.getFontConfigInfo(); FontConfigInfo fcInfo = fcm.getFontConfigInfo();
props.setProperty("fcversion", Integer.toString(fcInfo.fcVersion)); props.setProperty("fcversion", Integer.toString(fcInfo.fcVersion));
...@@ -427,7 +427,7 @@ public class FcFontConfiguration extends FontConfiguration { ...@@ -427,7 +427,7 @@ public class FcFontConfiguration extends FontConfiguration {
return; return;
} }
Properties props = new Properties(); Properties props = new Properties();
X11FontManager fm = (X11FontManager) fontManager; FcFontManager fm = (FcFontManager) fontManager;
FontConfigManager fcm = fm.getFontConfigManager(); FontConfigManager fcm = fm.getFontConfigManager();
try { try {
FileInputStream fis = new FileInputStream(fcFile); FileInputStream fis = new FileInputStream(fcFile);
......
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -68,9 +68,23 @@ class DevPollSelectorImpl ...@@ -68,9 +68,23 @@ class DevPollSelectorImpl
long pipeFds = IOUtil.makePipe(false); long pipeFds = IOUtil.makePipe(false);
fd0 = (int) (pipeFds >>> 32); fd0 = (int) (pipeFds >>> 32);
fd1 = (int) pipeFds; fd1 = (int) pipeFds;
pollWrapper = new DevPollArrayWrapper(); try {
pollWrapper.initInterrupt(fd0, fd1); pollWrapper = new DevPollArrayWrapper();
fdToKey = new HashMap<Integer,SelectionKeyImpl>(); pollWrapper.initInterrupt(fd0, fd1);
fdToKey = new HashMap<>();
} catch (Throwable t) {
try {
FileDispatcherImpl.closeIntFD(fd0);
} catch (IOException ioe0) {
t.addSuppressed(ioe0);
}
try {
FileDispatcherImpl.closeIntFD(fd1);
} catch (IOException ioe1) {
t.addSuppressed(ioe1);
}
throw t;
}
} }
protected int doSelect(long timeout) protected int doSelect(long timeout)
......
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -65,9 +65,23 @@ class EPollSelectorImpl ...@@ -65,9 +65,23 @@ class EPollSelectorImpl
long pipeFds = IOUtil.makePipe(false); long pipeFds = IOUtil.makePipe(false);
fd0 = (int) (pipeFds >>> 32); fd0 = (int) (pipeFds >>> 32);
fd1 = (int) pipeFds; fd1 = (int) pipeFds;
pollWrapper = new EPollArrayWrapper(); try {
pollWrapper.initInterrupt(fd0, fd1); pollWrapper = new EPollArrayWrapper();
fdToKey = new HashMap<>(); pollWrapper.initInterrupt(fd0, fd1);
fdToKey = new HashMap<>();
} catch (Throwable t) {
try {
FileDispatcherImpl.closeIntFD(fd0);
} catch (IOException ioe0) {
t.addSuppressed(ioe0);
}
try {
FileDispatcherImpl.closeIntFD(fd1);
} catch (IOException ioe1) {
t.addSuppressed(ioe1);
}
throw t;
}
} }
protected int doSelect(long timeout) throws IOException { protected int doSelect(long timeout) throws IOException {
......
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -57,9 +57,23 @@ class PollSelectorImpl ...@@ -57,9 +57,23 @@ class PollSelectorImpl
long pipeFds = IOUtil.makePipe(false); long pipeFds = IOUtil.makePipe(false);
fd0 = (int) (pipeFds >>> 32); fd0 = (int) (pipeFds >>> 32);
fd1 = (int) pipeFds; fd1 = (int) pipeFds;
pollWrapper = new PollArrayWrapper(INIT_CAP); try {
pollWrapper.initInterrupt(fd0, fd1); pollWrapper = new PollArrayWrapper(INIT_CAP);
channelArray = new SelectionKeyImpl[INIT_CAP]; pollWrapper.initInterrupt(fd0, fd1);
channelArray = new SelectionKeyImpl[INIT_CAP];
} catch (Throwable t) {
try {
FileDispatcherImpl.closeIntFD(fd0);
} catch (IOException ioe0) {
t.addSuppressed(ioe0);
}
try {
FileDispatcherImpl.closeIntFD(fd1);
} catch (IOException ioe1) {
t.addSuppressed(ioe1);
}
throw t;
}
} }
protected int doSelect(long timeout) protected int doSelect(long timeout)
......
...@@ -86,7 +86,7 @@ public class GnomeFileTypeDetector ...@@ -86,7 +86,7 @@ public class GnomeFileTypeDetector
// GIO // GIO
private static native boolean initializeGio(); private static native boolean initializeGio();
private static native byte[] probeUsingGio(long pathAddress); private static synchronized native byte[] probeUsingGio(long pathAddress);
// GNOME VFS // GNOME VFS
private static native boolean initializeGnomeVfs(); private static native boolean initializeGnomeVfs();
......
...@@ -171,7 +171,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector { ...@@ -171,7 +171,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
final String EXTEQUAL = "exts="; final String EXTEQUAL = "exts=";
String extRegex = "\\b" + EXTEQUAL + String extRegex = "\\b" + EXTEQUAL +
"(\"[\\p{Graph}|\\p{Blank}]+?\"|\\p{Graph}+\\b)"; "(\"[\\p{Graph}\\p{Blank}]+?\"|\\p{Graph}+\\b)";
Pattern extPattern = Pattern.compile(extRegex); Pattern extPattern = Pattern.compile(extRegex);
Matcher extMatcher = extPattern.matcher(entry); Matcher extMatcher = extPattern.matcher(entry);
...@@ -181,7 +181,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector { ...@@ -181,7 +181,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
if (exts.charAt(0) == '"') { if (exts.charAt(0) == '"') {
exts = exts.substring(1, exts.length() - 1); exts = exts.substring(1, exts.length() - 1);
} }
String[] extList = exts.split("[\\p{Blank}|\\p{Punct}]+"); String[] extList = exts.split("[\\p{Blank}\\p{Punct}]+");
for (String ext : extList) { for (String ext : extList) {
putIfAbsent(ext, type); putIfAbsent(ext, type);
} }
......
/* /*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -186,7 +186,8 @@ abstract class UnixFileStore ...@@ -186,7 +186,8 @@ abstract class UnixFileStore
return false; return false;
UnixFileStore other = (UnixFileStore)ob; UnixFileStore other = (UnixFileStore)ob;
return (this.dev == other.dev) && return (this.dev == other.dev) &&
Arrays.equals(this.entry.dir(), other.entry.dir()); Arrays.equals(this.entry.dir(), other.entry.dir()) &&
this.entry.name().equals(other.entry.name());
} }
@Override @Override
......
...@@ -37,6 +37,13 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy) ...@@ -37,6 +37,13 @@ char* nativeGetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
return NULL; return NULL;
} }
#if defined(LINUX) && (defined(_GNU_SOURCE) || \
(defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE < 200112L \
&& defined(_XOPEN_SOURCE) && _XOPEN_SOURCE < 600))
extern int __xpg_strerror_r(int, char *, size_t);
#define strerror_r(a, b, c) __xpg_strerror_r((a), (b), (c))
#endif
void* getProcessHandle() { void* getProcessHandle() {
static void *procHandle = NULL; static void *procHandle = NULL;
if (procHandle != NULL) { if (procHandle != NULL) {
...@@ -59,3 +66,9 @@ void buildJniFunctionName(const char *sym, const char *cname, ...@@ -59,3 +66,9 @@ void buildJniFunctionName(const char *sym, const char *cname,
} }
} }
int
getErrorString(int err, char *buf, size_t len)
{
if (err == 0 || len < 1) return 0;
return strerror_r(err, buf, len);
}
...@@ -216,13 +216,6 @@ size_t ...@@ -216,13 +216,6 @@ size_t
getLastErrorString(char *buf, size_t len) getLastErrorString(char *buf, size_t len)
{ {
if (errno == 0 || len < 1) return 0; if (errno == 0 || len < 1) return 0;
getErrorString(errno, buf, len);
const char *err = strerror(errno); return strlen(buf);
size_t n = strlen(err);
if (n >= len)
n = len - 1;
strncpy(buf, err, n);
buf[n] = '\0';
return n;
} }
...@@ -292,12 +292,13 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail) ...@@ -292,12 +292,13 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
static const char * const format = "error=%d, %s"; static const char * const format = "error=%d, %s";
const char *detail = defaultDetail; const char *detail = defaultDetail;
char *errmsg; char *errmsg;
char tmpbuf[1024];
jstring s; jstring s;
if (errnum != 0) { if (errnum != 0) {
const char *s = strerror(errnum); int ret = getErrorString(errnum, tmpbuf, sizeof(tmpbuf));
if (strcmp(s, "Unknown error") != 0) if (ret != EINVAL)
detail = s; detail = tmpbuf;
} }
/* ASCII Decimal representation uses 2.4 times as many bits as binary. */ /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum)); errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
......
/* /*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,6 +32,12 @@ ...@@ -32,6 +32,12 @@
#ifdef __solaris__ #ifdef __solaris__
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#ifndef BSD_COMP
#define BSD_COMP
#endif
#endif #endif
#ifdef __linux__ #ifdef __linux__
#include <unistd.h> #include <unistd.h>
...@@ -52,6 +58,8 @@ ...@@ -52,6 +58,8 @@
#endif #endif
#endif // __linux__ #endif // __linux__
#include <sys/ioctl.h>
#ifndef IPTOS_TOS_MASK #ifndef IPTOS_TOS_MASK
#define IPTOS_TOS_MASK 0x1e #define IPTOS_TOS_MASK 0x1e
#endif #endif
...@@ -946,6 +954,7 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -946,6 +954,7 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
jobject this) { jobject this) {
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID); jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
int arg, fd, t = 1; int arg, fd, t = 1;
char tmpbuf[1024];
#ifdef AF_INET6 #ifdef AF_INET6
int domain = ipv6_available() ? AF_INET6 : AF_INET; int domain = ipv6_available() ? AF_INET6 : AF_INET;
#else #else
...@@ -981,14 +990,14 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -981,14 +990,14 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
arg = 65507; arg = 65507;
if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF, if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF,
(char *)&arg, sizeof(arg)) < 0) { (char *)&arg, sizeof(arg)) < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", getErrorString(errno, tmpbuf, sizeof(tmpbuf));
strerror(errno)); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
return; return;
} }
if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF, if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF,
(char *)&arg, sizeof(arg)) < 0) { (char *)&arg, sizeof(arg)) < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", getErrorString(errno, tmpbuf, sizeof(tmpbuf));
strerror(errno)); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
return; return;
} }
#endif /* __APPLE__ */ #endif /* __APPLE__ */
...@@ -996,15 +1005,16 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env, ...@@ -996,15 +1005,16 @@ Java_java_net_PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int)); setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
#if defined(__linux__) #if defined(__linux__)
arg = 0; arg = 0;
int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP; int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP;
if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) && if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) &&
(errno != ENOPROTOOPT)) { (errno != ENOPROTOOPT))
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", {
strerror(errno)); getErrorString(errno, tmpbuf, sizeof(tmpbuf));
close(fd); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
return; close(fd);
} return;
}
#endif #endif
#if defined (__linux__) && defined (AF_INET6) #if defined (__linux__) && defined (AF_INET6)
...@@ -2265,3 +2275,28 @@ Java_java_net_PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this, ...@@ -2265,3 +2275,28 @@ Java_java_net_PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this,
{ {
mcast_join_leave(env, this, iaObj, niObj, JNI_FALSE); mcast_join_leave(env, this, iaObj, niObj, JNI_FALSE);
} }
/*
* Class: java_net_PlainDatagramSocketImpl
* Method: dataAvailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_java_net_PlainDatagramSocketImpl_dataAvailable(JNIEnv *env, jobject this)
{
int fd, retval;
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
if (IS_NULL(fdObj)) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
}
fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
if (ioctl(fd, FIONREAD, &retval) < 0) {
return -1;
}
return retval;
}
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,14 +35,20 @@ ...@@ -35,14 +35,20 @@
#include <string.h> #include <string.h>
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
#ifdef __solaris__ #if defined(__solaris__)
#include <libscf.h> #include <libscf.h>
#endif #endif
#include "jvm.h" #include "jvm.h"
#include "TimeZone_md.h"
#define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++; #define SKIP_SPACE(p) while (*p == ' ' || *p == '\t') p++;
#if defined(_ALLBSD_SOURCE)
#define dirent64 dirent
#define readdir64_r readdir_r
#endif
#if !defined(__solaris__) || defined(__sparcv9) || defined(amd64) #if !defined(__solaris__) || defined(__sparcv9) || defined(amd64)
#define fileopen fopen #define fileopen fopen
#define filegets fgets #define filegets fgets
...@@ -50,19 +56,20 @@ ...@@ -50,19 +56,20 @@
#endif #endif
#if defined(__linux__) || defined(_ALLBSD_SOURCE) #if defined(__linux__) || defined(_ALLBSD_SOURCE)
static const char *ETC_TIMEZONE_FILE = "/etc/timezone"; static const char *ETC_TIMEZONE_FILE = "/etc/timezone";
static const char *ZONEINFO_DIR = "/usr/share/zoneinfo"; static const char *ZONEINFO_DIR = "/usr/share/zoneinfo";
static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime"; static const char *DEFAULT_ZONEINFO_FILE = "/etc/localtime";
#else #else
#ifdef _AIX
static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
#endif
static const char *SYS_INIT_FILE = "/etc/default/init"; static const char *SYS_INIT_FILE = "/etc/default/init";
static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo"; static const char *ZONEINFO_DIR = "/usr/share/lib/zoneinfo";
static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime"; static const char *DEFAULT_ZONEINFO_FILE = "/usr/share/lib/zoneinfo/localtime";
#endif /*__linux__*/ #endif /* defined(__linux__) || defined(_ALLBSD_SOURCE) */
#if defined(_AIX)
static const char *ETC_ENVIRONMENT_FILE = "/etc/environment";
#endif
#if defined(__linux__) || defined(MACOSX) || defined(__solaris__)
/* /*
* Returns a pointer to the zone ID portion of the given zoneinfo file * Returns a pointer to the zone ID portion of the given zoneinfo file
...@@ -108,8 +115,8 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) ...@@ -108,8 +115,8 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
{ {
DIR *dirp = NULL; DIR *dirp = NULL;
struct stat statbuf; struct stat statbuf;
struct dirent *dp = NULL; struct dirent64 *dp = NULL;
struct dirent *entry = NULL; struct dirent64 *entry = NULL;
char *pathname = NULL; char *pathname = NULL;
int fd = -1; int fd = -1;
char *dbuf = NULL; char *dbuf = NULL;
...@@ -120,19 +127,13 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) ...@@ -120,19 +127,13 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
return NULL; return NULL;
} }
entry = (struct dirent *) malloc((size_t) pathconf(dir, _PC_NAME_MAX)); entry = (struct dirent64 *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
if (entry == NULL) { if (entry == NULL) {
(void) closedir(dirp); (void) closedir(dirp);
return NULL; return NULL;
} }
#if defined(_AIX) || defined(__linux__) || defined(MACOSX) || (defined(__solaris__) \ while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
&& (defined(_POSIX_PTHREAD_SEMANTICS) || defined(_LP64)))
while (readdir_r(dirp, entry, &dp) == 0 && dp != NULL) {
#else
while ((dp = readdir_r(dirp, entry)) != NULL) {
#endif
/* /*
* Skip '.' and '..' (and possibly other .* files) * Skip '.' and '..' (and possibly other .* files)
*/ */
...@@ -145,7 +146,7 @@ findZoneinfoFile(char *buf, size_t size, const char *dir) ...@@ -145,7 +146,7 @@ findZoneinfoFile(char *buf, size_t size, const char *dir)
*/ */
if ((strcmp(dp->d_name, "ROC") == 0) if ((strcmp(dp->d_name, "ROC") == 0)
|| (strcmp(dp->d_name, "posixrules") == 0) || (strcmp(dp->d_name, "posixrules") == 0)
#ifdef __solaris__ #if defined(__solaris__)
/* /*
* Skip the "src" and "tab" directories on Solaris. * Skip the "src" and "tab" directories on Solaris.
*/ */
...@@ -230,7 +231,7 @@ getPlatformTimeZoneID() ...@@ -230,7 +231,7 @@ getPlatformTimeZoneID()
char *buf; char *buf;
size_t size; size_t size;
#ifdef __linux__ #if defined(__linux__)
/* /*
* Try reading the /etc/timezone file for Debian distros. There's * Try reading the /etc/timezone file for Debian distros. There's
* no spec of the file format available. This parsing assumes that * no spec of the file format available. This parsing assumes that
...@@ -254,7 +255,7 @@ getPlatformTimeZoneID() ...@@ -254,7 +255,7 @@ getPlatformTimeZoneID()
return tz; return tz;
} }
} }
#endif /* __linux__ */ #endif /* defined(__linux__) */
/* /*
* Next, try /etc/localtime to find the zone ID. * Next, try /etc/localtime to find the zone ID.
...@@ -318,8 +319,9 @@ getPlatformTimeZoneID() ...@@ -318,8 +319,9 @@ getPlatformTimeZoneID()
free((void *) buf); free((void *) buf);
return tz; return tz;
} }
#else
#ifdef __solaris__ #elif defined(__solaris__)
#if !defined(__sparcv9) && !defined(amd64) #if !defined(__sparcv9) && !defined(amd64)
/* /*
...@@ -444,8 +446,7 @@ filegets(char *s, int n, FILE *stream) ...@@ -444,8 +446,7 @@ filegets(char *s, int n, FILE *stream)
} }
/*NOTREACHED*/ /*NOTREACHED*/
} }
#endif /* not __sparcv9 */ #endif /* !defined(__sparcv9) && !defined(amd64) */
/* /*
* Performs Solaris dependent mapping. Returns a zone ID if * Performs Solaris dependent mapping. Returns a zone ID if
...@@ -546,7 +547,7 @@ cleanupScf(scf_handle_t *h, ...@@ -546,7 +547,7 @@ cleanupScf(scf_handle_t *h,
} }
/* /*
* Retruns a zone ID of Solaris when the TZ value is "localtime". * Returns a zone ID of Solaris when the TZ value is "localtime".
* First, it tries scf. If scf fails, it looks for the same file as * First, it tries scf. If scf fails, it looks for the same file as
* /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/. * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/.
*/ */
...@@ -615,10 +616,11 @@ getSolarisDefaultZoneID() { ...@@ -615,10 +616,11 @@ getSolarisDefaultZoneID() {
free((void *) buf); free((void *) buf);
return tz; return tz;
} }
#endif /*__solaris__*/
#endif /*__linux__*/
#ifdef _AIX #endif /* defined(__solaris__) */
#elif defined(_AIX)
static char * static char *
getPlatformTimeZoneID() getPlatformTimeZoneID()
{ {
...@@ -644,8 +646,103 @@ getPlatformTimeZoneID() ...@@ -644,8 +646,103 @@ getPlatformTimeZoneID()
return tz; return tz;
} }
static char *mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz);
#endif static char *
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
FILE *tzmapf;
char mapfilename[PATH_MAX + 1];
char line[256];
int linecount = 0;
char *tz_buf = NULL;
char *temp_tz = NULL;
char *javatz = NULL;
size_t tz_len = 0;
/* On AIX, the TZ environment variable may end with a comma
* followed by modifier fields. These are ignored here. */
temp_tz = strchr(tz, ',');
tz_len = (temp_tz == NULL) ? strlen(tz) : temp_tz - tz;
tz_buf = (char *)malloc(tz_len + 1);
memcpy(tz_buf, tz, tz_len);
tz_buf[tz_len] = 0;
/* Open tzmappings file, with buffer overrun check */
if ((strlen(java_home_dir) + 15) > PATH_MAX) {
jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir);
goto tzerr;
}
strcpy(mapfilename, java_home_dir);
strcat(mapfilename, "/lib/tzmappings");
if ((tzmapf = fopen(mapfilename, "r")) == NULL) {
jio_fprintf(stderr, "can't open %s\n", mapfilename);
goto tzerr;
}
while (fgets(line, sizeof(line), tzmapf) != NULL) {
char *p = line;
char *sol = line;
char *java;
int result;
linecount++;
/*
* Skip comments and blank lines
*/
if (*p == '#' || *p == '\n') {
continue;
}
/*
* Get the first field, platform zone ID
*/
while (*p != '\0' && *p != '\t') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at near line %d.\n", linecount);
break;
}
*p++ = '\0';
if ((result = strncmp(tz_buf, sol, tz_len)) == 0) {
/*
* If this is the current platform zone ID,
* take the Java time zone ID (2nd field).
*/
java = p;
while (*p != '\0' && *p != '\n') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at line %d.\n", linecount);
break;
}
*p = '\0';
javatz = strdup(java);
break;
} else if (result < 0) {
break;
}
}
(void) fclose(tzmapf);
tzerr:
if (tz_buf != NULL ) {
free((void *) tz_buf);
}
if (javatz == NULL) {
return getGMTOffsetID();
}
return javatz;
}
#endif /* defined(_AIX) */
/* /*
* findJavaTZ_md() maps platform time zone ID to Java time zone ID * findJavaTZ_md() maps platform time zone ID to Java time zone ID
...@@ -664,51 +761,50 @@ findJavaTZ_md(const char *java_home_dir) ...@@ -664,51 +761,50 @@ findJavaTZ_md(const char *java_home_dir)
tz = getenv("TZ"); tz = getenv("TZ");
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
if (tz == NULL) {
#else
#if defined (__solaris__) || defined(_AIX)
if (tz == NULL || *tz == '\0') { if (tz == NULL || *tz == '\0') {
#endif
#endif
tz = getPlatformTimeZoneID(); tz = getPlatformTimeZoneID();
freetz = tz; freetz = tz;
} }
/*
* Remove any preceding ':'
*/
if (tz != NULL && *tz == ':') {
tz++;
}
#ifdef __solaris__
if (tz != NULL && strcmp(tz, "localtime") == 0) {
tz = getSolarisDefaultZoneID();
freetz = tz;
}
#endif
if (tz != NULL) { if (tz != NULL) {
#ifdef __linux__ /* Ignore preceding ':' */
/* if (*tz == ':') {
* Ignore "posix/" prefix. tz++;
*/ }
#if defined(__linux__)
/* Ignore "posix/" prefix on Linux. */
if (strncmp(tz, "posix/", 6) == 0) { if (strncmp(tz, "posix/", 6) == 0) {
tz += 6; tz += 6;
} }
#endif #endif
javatz = strdup(tz);
#if defined(_AIX)
/* On AIX do the platform to Java mapping. */
javatz = mapPlatformToJavaTimezone(java_home_dir, tz);
if (freetz != NULL) { if (freetz != NULL) {
free((void *) freetz); free((void *) freetz);
} }
#else
#ifdef _AIX #if defined(__solaris__)
freetz = mapPlatformToJavaTimezone(java_home_dir, javatz); /* Solaris might use localtime, so handle it here. */
if (javatz != NULL) { if (strcmp(tz, "localtime") == 0) {
free((void *) javatz); javatz = getSolarisDefaultZoneID();
if (freetz != NULL) {
free((void *) freetz);
}
} else
#endif
if (freetz == NULL) {
/* strdup if we are still working on getenv result. */
javatz = strdup(tz);
} else if (freetz != tz) {
/* strdup and free the old buffer, if we moved the pointer. */
javatz = strdup(tz);
free((void *) freetz);
} else {
/* we are good if we already work on a freshly allocated buffer. */
javatz = tz;
} }
javatz = freetz;
#endif #endif
} }
...@@ -719,7 +815,7 @@ findJavaTZ_md(const char *java_home_dir) ...@@ -719,7 +815,7 @@ findJavaTZ_md(const char *java_home_dir)
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00") * Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
*/ */
#ifdef MACOSX #if defined(MACOSX)
char * char *
getGMTOffsetID() getGMTOffsetID()
...@@ -735,15 +831,16 @@ getGMTOffsetID() ...@@ -735,15 +831,16 @@ getGMTOffsetID()
local_tm = localtime(&clock); local_tm = localtime(&clock);
if (local_tm->tm_gmtoff >= 0) { if (local_tm->tm_gmtoff >= 0) {
offset = (time_t) local_tm->tm_gmtoff; offset = (time_t) local_tm->tm_gmtoff;
sign = "+"; sign = '+';
} else { } else {
offset = (time_t) -local_tm->tm_gmtoff; offset = (time_t) -local_tm->tm_gmtoff;
sign = "-"; sign = '-';
} }
sprintf(buf, (const char *)"GMT%c%02d:%02d", sprintf(buf, (const char *)"GMT%c%02d:%02d",
sign, (int)(offset/3600), (int)((offset%3600)/60)); sign, (int)(offset/3600), (int)((offset%3600)/60));
return strdup(buf); return strdup(buf);
} }
#else #else
char * char *
...@@ -751,7 +848,7 @@ getGMTOffsetID() ...@@ -751,7 +848,7 @@ getGMTOffsetID()
{ {
time_t offset; time_t offset;
char sign, buf[32]; char sign, buf[32];
#ifdef __solaris__ #if defined(__solaris__)
struct tm localtm; struct tm localtm;
time_t currenttime; time_t currenttime;
...@@ -763,7 +860,7 @@ getGMTOffsetID() ...@@ -763,7 +860,7 @@ getGMTOffsetID()
offset = localtm.tm_isdst ? altzone : timezone; offset = localtm.tm_isdst ? altzone : timezone;
#else #else
offset = timezone; offset = timezone;
#endif /*__linux__*/ #endif
if (offset == 0) { if (offset == 0) {
return strdup("GMT"); return strdup("GMT");
...@@ -781,101 +878,3 @@ getGMTOffsetID() ...@@ -781,101 +878,3 @@ getGMTOffsetID()
return strdup(buf); return strdup(buf);
} }
#endif /* MACOSX */ #endif /* MACOSX */
#ifdef _AIX
static char *
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
FILE *tzmapf;
char mapfilename[PATH_MAX+1];
char line[256];
int linecount = 0;
char temp[100], *temp_tz;
char *javatz = NULL;
char *str_tmp = NULL;
size_t temp_tz_len = 0;
/* On AIX, the TZ environment variable may end with a comma
* followed by modifier fields. These are ignored here.
*/
strncpy(temp, tz, 100);
temp_tz = strtok_r(temp, ",", &str_tmp);
if(temp_tz == NULL)
goto tzerr;
temp_tz_len = strlen(temp_tz);
if (strlen(java_home_dir) >= (PATH_MAX - 15)) {
jio_fprintf(stderr, "java.home longer than maximum path length \n");
goto tzerr;
}
strncpy(mapfilename, java_home_dir, PATH_MAX);
strcat(mapfilename, "/lib/tzmappings");
if ((tzmapf = fopen(mapfilename, "r")) == NULL) {
jio_fprintf(stderr, "can't open %s\n", mapfilename);
goto tzerr;
}
while (fgets(line, sizeof(line), tzmapf) != NULL) {
char *p = line;
char *sol = line;
char *java;
int result;
linecount++;
/*
* Skip comments and blank lines
*/
if (*p == '#' || *p == '\n') {
continue;
}
/*
* Get the first field, platform zone ID
*/
while (*p != '\0' && *p != '\t') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at near line %d.\n", linecount);
break;
}
*p++ = '\0';
if ((result = strncmp(temp_tz, sol, temp_tz_len)) == 0) {
/*
* If this is the current platform zone ID,
* take the Java time zone ID (2nd field).
*/
java = p;
while (*p != '\0' && *p != '\n') {
p++;
}
if (*p == '\0') {
/* mapping table is broken! */
jio_fprintf(stderr, "tzmappings: Illegal format at line %d.\n", linecount);
break;
}
*p = '\0';
javatz = strdup(java);
break;
} else if (result < 0) {
break;
}
}
(void) fclose(tzmapf);
tzerr:
if (javatz == NULL) {
return getGMTOffsetID();
}
return javatz;
}
#endif
...@@ -497,7 +497,7 @@ static char* mergePaths(char **p1, char **p2, char **p3, jboolean noType1) { ...@@ -497,7 +497,7 @@ static char* mergePaths(char **p1, char **p2, char **p3, jboolean noType1) {
* This also frees us from X11 APIs as JRE is required to function in * This also frees us from X11 APIs as JRE is required to function in
* a "headless" mode where there is no Xserver. * a "headless" mode where there is no Xserver.
*/ */
static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) { static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1, jboolean isX11) {
char **fcdirs = NULL, **x11dirs = NULL, **knowndirs = NULL, *path = NULL; char **fcdirs = NULL, **x11dirs = NULL, **knowndirs = NULL, *path = NULL;
...@@ -519,6 +519,7 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) { ...@@ -519,6 +519,7 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) {
* be initialised. * be initialised.
*/ */
#ifndef HEADLESS #ifndef HEADLESS
if (isX11) { // The following only works in an x11 environment.
#if defined(__linux__) #if defined(__linux__)
/* There's no headless build on linux ... */ /* There's no headless build on linux ... */
if (!AWTIsHeadless()) { /* .. so need to call a function to check */ if (!AWTIsHeadless()) { /* .. so need to call a function to check */
...@@ -538,6 +539,7 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) { ...@@ -538,6 +539,7 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) {
#if defined(__linux__) #if defined(__linux__)
} }
#endif #endif
}
#endif /* !HEADLESS */ #endif /* !HEADLESS */
path = mergePaths(fcdirs, x11dirs, knowndirs, noType1); path = mergePaths(fcdirs, x11dirs, knowndirs, noType1);
if (fcdirs != NULL) { if (fcdirs != NULL) {
...@@ -555,13 +557,13 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) { ...@@ -555,13 +557,13 @@ static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1) {
return path; return path;
} }
JNIEXPORT jstring JNICALL Java_sun_awt_X11FontManager_getFontPathNative JNIEXPORT jstring JNICALL Java_sun_awt_FcFontManager_getFontPathNative
(JNIEnv *env, jobject thiz, jboolean noType1) { (JNIEnv *env, jobject thiz, jboolean noType1, jboolean isX11) {
jstring ret; jstring ret;
static char *ptr = NULL; /* retain result across calls */ static char *ptr = NULL; /* retain result across calls */
if (ptr == NULL) { if (ptr == NULL) {
ptr = getPlatformFontPathChars(env, noType1); ptr = getPlatformFontPathChars(env, noType1, isX11);
} }
ret = (*env)->NewStringUTF(env, ptr); ret = (*env)->NewStringUTF(env, ptr);
return ret; return ret;
...@@ -1217,10 +1219,11 @@ Java_sun_font_FontConfigManager_getFontConfig ...@@ -1217,10 +1219,11 @@ Java_sun_font_FontConfigManager_getFontConfig
minGlyphs = val; minGlyphs = val;
} }
} }
FcCharSet *unionCharset = NULL;
for (j=0; j<nfonts; j++) { for (j=0; j<nfonts; j++) {
FcPattern *fontPattern = fontset->fonts[j]; FcPattern *fontPattern = fontset->fonts[j];
FcChar8 *fontformat; FcChar8 *fontformat;
FcCharSet *unionCharset = NULL, *charset; FcCharSet *charset = NULL;
fontformat = NULL; fontformat = NULL;
(*FcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat); (*FcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat);
...@@ -1278,6 +1281,9 @@ Java_sun_font_FontConfigManager_getFontConfig ...@@ -1278,6 +1281,9 @@ Java_sun_font_FontConfigManager_getFontConfig
if (!includeFallbacks) { if (!includeFallbacks) {
break; break;
} }
if (fontCount == 254) {
break; // CompositeFont will only use up to 254 slots from here.
}
} }
/* Once we get here 'fontCount' is the number of returned fonts /* Once we get here 'fontCount' is the number of returned fonts
......
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -76,14 +76,17 @@ static void next_line(FILE *f) { ...@@ -76,14 +76,17 @@ static void next_line(FILE *f) {
static int get_totalticks(int which, ticks *pticks) { static int get_totalticks(int which, ticks *pticks) {
FILE *fh; FILE *fh;
uint64_t userTicks, niceTicks, systemTicks, idleTicks; uint64_t userTicks, niceTicks, systemTicks, idleTicks;
uint64_t iowTicks = 0, irqTicks = 0, sirqTicks= 0;
int n; int n;
if((fh = fopen("/proc/stat", "r")) == NULL) { if((fh = fopen("/proc/stat", "r")) == NULL) {
return -1; return -1;
} }
n = fscanf(fh, "cpu " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64, n = fscanf(fh, "cpu " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 " "
&userTicks, &niceTicks, &systemTicks, &idleTicks); DEC_64 " " DEC_64,
&userTicks, &niceTicks, &systemTicks, &idleTicks,
&iowTicks, &irqTicks, &sirqTicks);
// Move to next line // Move to next line
next_line(fh); next_line(fh);
...@@ -92,24 +95,30 @@ static int get_totalticks(int which, ticks *pticks) { ...@@ -92,24 +95,30 @@ static int get_totalticks(int which, ticks *pticks) {
if (which != -1) { if (which != -1) {
int i; int i;
for (i = 0; i < which; i++) { for (i = 0; i < which; i++) {
if (fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64, &userTicks, &niceTicks, &systemTicks, &idleTicks) != 4) { if (fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 " "
DEC_64 " " DEC_64 " " DEC_64,
&userTicks, &niceTicks, &systemTicks, &idleTicks,
&iowTicks, &irqTicks, &sirqTicks) < 4) {
fclose(fh); fclose(fh);
return -2; return -2;
} }
next_line(fh); next_line(fh);
} }
n = fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 "\n", n = fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 " "
&userTicks, &niceTicks, &systemTicks, &idleTicks); DEC_64 " " DEC_64 " " DEC_64 "\n",
&userTicks, &niceTicks, &systemTicks, &idleTicks,
&iowTicks, &irqTicks, &sirqTicks);
} }
fclose(fh); fclose(fh);
if (n != 4) { if (n < 4) {
return -2; return -2;
} }
pticks->used = userTicks + niceTicks; pticks->used = userTicks + niceTicks;
pticks->usedKernel = systemTicks; pticks->usedKernel = systemTicks + irqTicks + sirqTicks;
pticks->total = userTicks + niceTicks + systemTicks + idleTicks; pticks->total = userTicks + niceTicks + systemTicks + idleTicks +
iowTicks + irqTicks + sirqTicks;
return 0; return 0;
} }
......
...@@ -308,21 +308,15 @@ Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) { ...@@ -308,21 +308,15 @@ Java_sun_nio_fs_UnixNativeDispatcher_getcwd(JNIEnv* env, jclass this) {
JNIEXPORT jbyteArray JNIEXPORT jbyteArray
Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error) Java_sun_nio_fs_UnixNativeDispatcher_strerror(JNIEnv* env, jclass this, jint error)
{ {
char* msg; char tmpbuf[1024];
jsize len; jsize len;
jbyteArray bytes; jbyteArray bytes;
#ifdef _AIX getErrorString((int)errno, tmpbuf, sizeof(tmpbuf));
/* strerror() is not thread-safe on AIX so we have to use strerror_r() */ len = strlen(tmpbuf);
char buffer[256];
msg = (strerror_r((int)error, buffer, 256) == 0) ? buffer : "Error while calling strerror_r";
#else
msg = strerror((int)error);
#endif
len = strlen(msg);
bytes = (*env)->NewByteArray(env, len); bytes = (*env)->NewByteArray(env, len);
if (bytes != NULL) { if (bytes != NULL) {
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)msg); (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)tmpbuf);
} }
return bytes; return bytes;
} }
......
/* /*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -45,7 +45,7 @@ import java.security.PrivilegedAction; ...@@ -45,7 +45,7 @@ import java.security.PrivilegedAction;
class DefaultDatagramSocketImplFactory class DefaultDatagramSocketImplFactory
{ {
static Class<?> prefixImplClass = null; private final static Class<?> prefixImplClass;
/* the windows version. */ /* the windows version. */
private static float version; private static float version;
...@@ -54,16 +54,19 @@ class DefaultDatagramSocketImplFactory ...@@ -54,16 +54,19 @@ class DefaultDatagramSocketImplFactory
private static boolean preferIPv4Stack = false; private static boolean preferIPv4Stack = false;
/* If the version supports a dual stack TCP implementation */ /* If the version supports a dual stack TCP implementation */
private static boolean useDualStackImpl = false; private final static boolean useDualStackImpl;
/* sun.net.useExclusiveBind */ /* sun.net.useExclusiveBind */
private static String exclBindProp; private static String exclBindProp;
/* True if exclusive binding is on for Windows */ /* True if exclusive binding is on for Windows */
private static boolean exclusiveBind = true; private final static boolean exclusiveBind;
static { static {
Class<?> prefixImplClassLocal = null;
boolean useDualStackImplLocal = false;
boolean exclusiveBindLocal = true;
// Determine Windows Version. // Determine Windows Version.
java.security.AccessController.doPrivileged( java.security.AccessController.doPrivileged(
new PrivilegedAction<Object>() { new PrivilegedAction<Object>() {
...@@ -78,7 +81,7 @@ class DefaultDatagramSocketImplFactory ...@@ -78,7 +81,7 @@ class DefaultDatagramSocketImplFactory
"java.net.preferIPv4Stack")); "java.net.preferIPv4Stack"));
exclBindProp = System.getProperty( exclBindProp = System.getProperty(
"sun.net.useExclusiveBind"); "sun.net.useExclusiveBind");
} catch (NumberFormatException e ) { } catch (NumberFormatException e) {
assert false : e; assert false : e;
} }
return null; // nothing to return return null; // nothing to return
...@@ -87,14 +90,14 @@ class DefaultDatagramSocketImplFactory ...@@ -87,14 +90,14 @@ class DefaultDatagramSocketImplFactory
// (version >= 6.0) implies Vista or greater. // (version >= 6.0) implies Vista or greater.
if (version >= 6.0 && !preferIPv4Stack) { if (version >= 6.0 && !preferIPv4Stack) {
useDualStackImpl = true; useDualStackImplLocal = true;
} }
if (exclBindProp != null) { if (exclBindProp != null) {
// sun.net.useExclusiveBind is true // sun.net.useExclusiveBind is true
exclusiveBind = exclBindProp.length() == 0 ? true exclusiveBindLocal = exclBindProp.length() == 0 ? true
: Boolean.parseBoolean(exclBindProp); : Boolean.parseBoolean(exclBindProp);
} else if (version < 6.0) { } else if (version < 6.0) {
exclusiveBind = false; exclusiveBindLocal = false;
} }
// impl.prefix // impl.prefix
...@@ -103,12 +106,16 @@ class DefaultDatagramSocketImplFactory ...@@ -103,12 +106,16 @@ class DefaultDatagramSocketImplFactory
prefix = AccessController.doPrivileged( prefix = AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("impl.prefix", null)); new sun.security.action.GetPropertyAction("impl.prefix", null));
if (prefix != null) if (prefix != null)
prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl"); prefixImplClassLocal = Class.forName("java.net."+prefix+"DatagramSocketImpl");
} catch (Exception e) { } catch (Exception e) {
System.err.println("Can't find class: java.net." + System.err.println("Can't find class: java.net." +
prefix + prefix +
"DatagramSocketImpl: check impl.prefix property"); "DatagramSocketImpl: check impl.prefix property");
} }
prefixImplClass = prefixImplClassLocal;
useDualStackImpl = useDualStackImplLocal;
exclusiveBind = exclusiveBindLocal;
} }
/** /**
...@@ -126,12 +133,10 @@ class DefaultDatagramSocketImplFactory ...@@ -126,12 +133,10 @@ class DefaultDatagramSocketImplFactory
throw new SocketException("can't instantiate DatagramSocketImpl"); throw new SocketException("can't instantiate DatagramSocketImpl");
} }
} else { } else {
if (isMulticast)
exclusiveBind = false;
if (useDualStackImpl && !isMulticast) if (useDualStackImpl && !isMulticast)
return new DualStackPlainDatagramSocketImpl(exclusiveBind); return new DualStackPlainDatagramSocketImpl(exclusiveBind);
else else
return new TwoStacksPlainDatagramSocketImpl(exclusiveBind); return new TwoStacksPlainDatagramSocketImpl(exclusiveBind && !isMulticast);
} }
} }
} }
/* /*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -45,6 +45,10 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl ...@@ -45,6 +45,10 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
{ {
static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess(); static JavaIOFileDescriptorAccess fdAccess = SharedSecrets.getJavaIOFileDescriptorAccess();
static {
initIDs();
}
// true if this socket is exclusively bound // true if this socket is exclusively bound
private final boolean exclusiveBind; private final boolean exclusiveBind;
...@@ -288,4 +292,6 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl ...@@ -288,4 +292,6 @@ class DualStackPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
int optionValue) throws SocketException; int optionValue) throws SocketException;
private static native int socketGetIntOption(int fd, int cmd) throws SocketException; private static native int socketGetIntOption(int fd, int cmd) throws SocketException;
native int dataAvailable();
} }
/* /*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -207,6 +207,8 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl ...@@ -207,6 +207,8 @@ class TwoStacksPlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
protected native void disconnect0(int family); protected native void disconnect0(int family);
native int dataAvailable();
/** /**
* Perform class load-time initializations. * Perform class load-time initializations.
*/ */
......
...@@ -248,14 +248,6 @@ public class WEmbeddedFrame extends EmbeddedFrame { ...@@ -248,14 +248,6 @@ public class WEmbeddedFrame extends EmbeddedFrame {
} }
} }
@SuppressWarnings("deprecation")
public boolean requestFocusToEmbedder() {
if (isEmbeddedInIE) {
return ((WEmbeddedFramePeer) getPeer()).requestFocusToEmbedder();
}
return false;
}
public void registerAccelerator(AWTKeyStroke stroke) {} public void registerAccelerator(AWTKeyStroke stroke) {}
public void unregisterAccelerator(AWTKeyStroke stroke) {} public void unregisterAccelerator(AWTKeyStroke stroke) {}
......
...@@ -79,10 +79,4 @@ public class WEmbeddedFramePeer extends WFramePeer { ...@@ -79,10 +79,4 @@ public class WEmbeddedFramePeer extends WFramePeer {
return !Win32GraphicsEnvironment.isDWMCompositionEnabled(); return !Win32GraphicsEnvironment.isDWMCompositionEnabled();
} }
/**
* Sets the focus to plugin control window, the parent of embedded frame.
* Eventually, it will synthesizeWindowActivation to activate the embedded frame,
* if plugin control window gets the focus.
*/
public native boolean requestFocusToEmbedder();
} }
...@@ -98,6 +98,7 @@ class WindowsConstants { ...@@ -98,6 +98,7 @@ class WindowsConstants {
public static final int ERROR_DISK_FULL = 112; public static final int ERROR_DISK_FULL = 112;
public static final int ERROR_INSUFFICIENT_BUFFER = 122; public static final int ERROR_INSUFFICIENT_BUFFER = 122;
public static final int ERROR_INVALID_LEVEL = 124; public static final int ERROR_INVALID_LEVEL = 124;
public static final int ERROR_DIR_NOT_ROOT = 144;
public static final int ERROR_DIR_NOT_EMPTY = 145; public static final int ERROR_DIR_NOT_EMPTY = 145;
public static final int ERROR_ALREADY_EXISTS = 183; public static final int ERROR_ALREADY_EXISTS = 183;
public static final int ERROR_MORE_DATA = 234; public static final int ERROR_MORE_DATA = 234;
......
...@@ -86,14 +86,28 @@ class WindowsFileStore ...@@ -86,14 +86,28 @@ class WindowsFileStore
WindowsFileAttributes.get(file, true); WindowsFileAttributes.get(file, true);
target = file.getPathForWin32Calls(); target = file.getPathForWin32Calls();
} }
String root = GetVolumePathName(target); try {
return new WindowsFileStore(root); return createFromPath(target);
} catch (WindowsException e) {
if (e.lastError() != ERROR_DIR_NOT_ROOT)
throw e;
target = WindowsLinkSupport.getFinalPath(file);
if (target == null)
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Couldn't resolve path");
return createFromPath(target);
}
} catch (WindowsException x) { } catch (WindowsException x) {
x.rethrowAsIOException(file); x.rethrowAsIOException(file);
return null; // keep compiler happy return null; // keep compiler happy
} }
} }
private static WindowsFileStore createFromPath(String target) throws WindowsException {
String root = GetVolumePathName(target);
return new WindowsFileStore(root);
}
VolumeInformation volumeInformation() { VolumeInformation volumeInformation() {
return volInfo; return volInfo;
} }
......
...@@ -66,7 +66,7 @@ class WindowsLinkSupport { ...@@ -66,7 +66,7 @@ class WindowsLinkSupport {
* Returns the final path (all symbolic links resolved) or null if this * Returns the final path (all symbolic links resolved) or null if this
* operation is not supported. * operation is not supported.
*/ */
private static String getFinalPath(WindowsPath input) throws IOException { static String getFinalPath(WindowsPath input) throws IOException {
long h = 0; long h = 0;
try { try {
h = input.openForReadAttributeAccess(true); h = input.openForReadAttributeAccess(true);
......
...@@ -36,6 +36,17 @@ import sun.misc.Unsafe; ...@@ -36,6 +36,17 @@ import sun.misc.Unsafe;
class WindowsNativeDispatcher { class WindowsNativeDispatcher {
private WindowsNativeDispatcher() { } private WindowsNativeDispatcher() { }
/**
* HANDLE CreateEvent(
* LPSECURITY_ATTRIBUTES lpEventAttributes,
* BOOL bManualReset,
* BOOL bInitialState,
* PCTSTR lpName
* );
*/
static native long CreateEvent(boolean bManualReset, boolean bInitialState)
throws WindowsException;
/** /**
* HANDLE CreateFile( * HANDLE CreateFile(
* LPCTSTR lpFileName, * LPCTSTR lpFileName,
...@@ -1041,6 +1052,25 @@ class WindowsNativeDispatcher { ...@@ -1041,6 +1052,25 @@ class WindowsNativeDispatcher {
long pOverlapped) long pOverlapped)
throws WindowsException; throws WindowsException;
/**
* CancelIo(
* HANDLE hFile
* )
*/
static native void CancelIo(long hFile) throws WindowsException;
/**
* GetOverlappedResult(
* HANDLE hFile,
* LPOVERLAPPED lpOverlapped,
* LPDWORD lpNumberOfBytesTransferred,
* BOOL bWait
* );
*/
static native int GetOverlappedResult(long hFile, long lpOverlapped)
throws WindowsException;
/** /**
* BackupRead( * BackupRead(
* HANDLE hFile, * HANDLE hFile,
......
...@@ -25,9 +25,16 @@ ...@@ -25,9 +25,16 @@
package sun.nio.fs; package sun.nio.fs;
import java.nio.file.*;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.nio.file.NotDirectoryException;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sun.nio.file.ExtendedWatchEventModifier; import com.sun.nio.file.ExtendedWatchEventModifier;
import sun.misc.Unsafe; import sun.misc.Unsafe;
...@@ -42,7 +49,6 @@ class WindowsWatchService ...@@ -42,7 +49,6 @@ class WindowsWatchService
extends AbstractWatchService extends AbstractWatchService
{ {
private final static int WAKEUP_COMPLETION_KEY = 0; private final static int WAKEUP_COMPLETION_KEY = 0;
private final Unsafe unsafe = Unsafe.getUnsafe();
// background thread to service I/O completion port // background thread to service I/O completion port
private final Poller poller; private final Poller poller;
...@@ -82,7 +88,7 @@ class WindowsWatchService ...@@ -82,7 +88,7 @@ class WindowsWatchService
/** /**
* Windows implementation of WatchKey. * Windows implementation of WatchKey.
*/ */
private class WindowsWatchKey extends AbstractWatchKey { private static class WindowsWatchKey extends AbstractWatchKey {
// file key (used to detect existing registrations) // file key (used to detect existing registrations)
private final FileKey fileKey; private final FileKey fileKey;
...@@ -169,15 +175,9 @@ class WindowsWatchService ...@@ -169,15 +175,9 @@ class WindowsWatchService
return completionKey; return completionKey;
} }
// close directory and release buffer // Invalidate the key, assumes that resources have been released
void releaseResources() {
CloseHandle(handle);
buffer.cleaner().clean();
}
// Invalidate key by closing directory and releasing buffer
void invalidate() { void invalidate() {
releaseResources(); ((WindowsWatchService)watcher()).poller.releaseResources(this);
handle = INVALID_HANDLE_VALUE; handle = INVALID_HANDLE_VALUE;
buffer = null; buffer = null;
countAddress = 0; countAddress = 0;
...@@ -193,7 +193,7 @@ class WindowsWatchService ...@@ -193,7 +193,7 @@ class WindowsWatchService
public void cancel() { public void cancel() {
if (isValid()) { if (isValid()) {
// delegate to poller // delegate to poller
poller.cancel(this); ((WindowsWatchService)watcher()).poller.cancel(this);
} }
} }
} }
...@@ -241,18 +241,25 @@ class WindowsWatchService ...@@ -241,18 +241,25 @@ class WindowsWatchService
/** /**
* Background thread to service I/O completion port. * Background thread to service I/O completion port.
*/ */
private class Poller extends AbstractPoller { private static class Poller extends AbstractPoller {
private final static Unsafe UNSAFE = Unsafe.getUnsafe();
/* /*
* typedef struct _OVERLAPPED { * typedef struct _OVERLAPPED {
* DWORD Internal; * ULONG_PTR Internal;
* DWORD InternalHigh; * ULONG_PTR InternalHigh;
* DWORD Offset; * union {
* DWORD OffsetHigh; * struct { DWORD Offset; DWORD OffsetHigh; };
* HANDLE hEvent; * PVOID Pointer;
* };
* HANDLE hEvent;
* } OVERLAPPED; * } OVERLAPPED;
*/ */
private static final short SIZEOF_DWORD = 4; private static final short SIZEOF_DWORD = 4;
private static final short SIZEOF_OVERLAPPED = 32; // 20 on 32-bit private static final short SIZEOF_OVERLAPPED = 32; // 20 on 32-bit
private static final short OFFSETOF_HEVENT =
(UNSAFE.addressSize() == 4) ? (short) 16 : 24;
/* /*
* typedef struct _FILE_NOTIFY_INFORMATION { * typedef struct _FILE_NOTIFY_INFORMATION {
...@@ -276,10 +283,10 @@ class WindowsWatchService ...@@ -276,10 +283,10 @@ class WindowsWatchService
private final long port; private final long port;
// maps completion key to WatchKey // maps completion key to WatchKey
private final Map<Integer,WindowsWatchKey> ck2key; private final Map<Integer, WindowsWatchKey> ck2key;
// maps file key to WatchKey // maps file key to WatchKey
private final Map<FileKey,WindowsWatchKey> fk2key; private final Map<FileKey, WindowsWatchKey> fk2key;
// unique completion key for each directory // unique completion key for each directory
// native completion key capacity is 64 bits on Win64. // native completion key capacity is 64 bits on Win64.
...@@ -393,8 +400,13 @@ class WindowsWatchService ...@@ -393,8 +400,13 @@ class WindowsWatchService
long overlappedAddress = bufferAddress + size - SIZEOF_OVERLAPPED; long overlappedAddress = bufferAddress + size - SIZEOF_OVERLAPPED;
long countAddress = overlappedAddress - SIZEOF_DWORD; long countAddress = overlappedAddress - SIZEOF_DWORD;
// zero the overlapped structure
UNSAFE.setMemory(overlappedAddress, SIZEOF_OVERLAPPED, (byte)0);
// start async read of changes to directory // start async read of changes to directory
try { try {
createAndAttachEvent(overlappedAddress);
ReadDirectoryChangesW(handle, ReadDirectoryChangesW(handle,
bufferAddress, bufferAddress,
CHANGES_BUFFER_SIZE, CHANGES_BUFFER_SIZE,
...@@ -403,6 +415,7 @@ class WindowsWatchService ...@@ -403,6 +415,7 @@ class WindowsWatchService
countAddress, countAddress,
overlappedAddress); overlappedAddress);
} catch (WindowsException x) { } catch (WindowsException x) {
closeAttachedEvent(overlappedAddress);
buffer.release(); buffer.release();
return new IOException(x.getMessage()); return new IOException(x.getMessage());
} }
...@@ -421,7 +434,7 @@ class WindowsWatchService ...@@ -421,7 +434,7 @@ class WindowsWatchService
// 2. release existing key's resources (handle/buffer) // 2. release existing key's resources (handle/buffer)
// 3. re-initialize key with new handle/buffer // 3. re-initialize key with new handle/buffer
ck2key.remove(existing.completionKey()); ck2key.remove(existing.completionKey());
existing.releaseResources(); releaseResources(existing);
watchKey = existing.init(handle, events, watchSubtree, buffer, watchKey = existing.init(handle, events, watchSubtree, buffer,
countAddress, overlappedAddress, completionKey); countAddress, overlappedAddress, completionKey);
} }
...@@ -436,6 +449,42 @@ class WindowsWatchService ...@@ -436,6 +449,42 @@ class WindowsWatchService
} }
} }
/**
* Cancels the outstanding I/O operation on the directory
* associated with the given key and releases the associated
* resources.
*/
private void releaseResources(WindowsWatchKey key) {
try {
CancelIo(key.handle());
GetOverlappedResult(key.handle(), key.overlappedAddress());
} catch (WindowsException expected) {
// expected as I/O operation has been cancelled
}
CloseHandle(key.handle());
closeAttachedEvent(key.overlappedAddress());
key.buffer().cleaner().clean();
}
/**
* Creates an unnamed event and set it as the hEvent field
* in the given OVERLAPPED structure
*/
private void createAndAttachEvent(long ov) throws WindowsException {
long hEvent = CreateEvent(false, false);
UNSAFE.putAddress(ov + OFFSETOF_HEVENT, hEvent);
}
/**
* Closes the event attached to the given OVERLAPPED structure. A
* no-op if there isn't an event attached.
*/
private void closeAttachedEvent(long ov) {
long hEvent = UNSAFE.getAddress(ov + OFFSETOF_HEVENT);
if (hEvent != 0 && hEvent != INVALID_HANDLE_VALUE)
CloseHandle(hEvent);
}
// cancel single key // cancel single key
@Override @Override
void implCancelKey(WatchKey obj) { void implCancelKey(WatchKey obj) {
...@@ -451,9 +500,8 @@ class WindowsWatchService ...@@ -451,9 +500,8 @@ class WindowsWatchService
@Override @Override
void implCloseAll() { void implCloseAll() {
// cancel all keys // cancel all keys
for (Map.Entry<Integer, WindowsWatchKey> entry: ck2key.entrySet()) { ck2key.values().forEach(WindowsWatchKey::invalidate);
entry.getValue().invalidate();
}
fk2key.clear(); fk2key.clear();
ck2key.clear(); ck2key.clear();
...@@ -462,8 +510,7 @@ class WindowsWatchService ...@@ -462,8 +510,7 @@ class WindowsWatchService
} }
// Translate file change action into watch event // Translate file change action into watch event
private WatchEvent.Kind<?> translateActionToEvent(int action) private WatchEvent.Kind<?> translateActionToEvent(int action) {
{
switch (action) { switch (action) {
case FILE_ACTION_MODIFIED : case FILE_ACTION_MODIFIED :
return StandardWatchEventKinds.ENTRY_MODIFY; return StandardWatchEventKinds.ENTRY_MODIFY;
...@@ -487,18 +534,18 @@ class WindowsWatchService ...@@ -487,18 +534,18 @@ class WindowsWatchService
int nextOffset; int nextOffset;
do { do {
int action = unsafe.getInt(address + OFFSETOF_ACTION); int action = UNSAFE.getInt(address + OFFSETOF_ACTION);
// map action to event // map action to event
WatchEvent.Kind<?> kind = translateActionToEvent(action); WatchEvent.Kind<?> kind = translateActionToEvent(action);
if (key.events().contains(kind)) { if (key.events().contains(kind)) {
// copy the name // copy the name
int nameLengthInBytes = unsafe.getInt(address + OFFSETOF_FILENAMELENGTH); int nameLengthInBytes = UNSAFE.getInt(address + OFFSETOF_FILENAMELENGTH);
if ((nameLengthInBytes % 2) != 0) { if ((nameLengthInBytes % 2) != 0) {
throw new AssertionError("FileNameLength.FileNameLength is not a multiple of 2"); throw new AssertionError("FileNameLength is not a multiple of 2");
} }
char[] nameAsArray = new char[nameLengthInBytes/2]; char[] nameAsArray = new char[nameLengthInBytes/2];
unsafe.copyMemory(null, address + OFFSETOF_FILENAME, nameAsArray, UNSAFE.copyMemory(null, address + OFFSETOF_FILENAME, nameAsArray,
Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes); Unsafe.ARRAY_CHAR_BASE_OFFSET, nameLengthInBytes);
// create FileName and queue event // create FileName and queue event
...@@ -508,7 +555,7 @@ class WindowsWatchService ...@@ -508,7 +555,7 @@ class WindowsWatchService
} }
// next event // next event
nextOffset = unsafe.getInt(address + OFFSETOF_NEXTENTRYOFFSET); nextOffset = UNSAFE.getInt(address + OFFSETOF_NEXTENTRYOFFSET);
address += (long)nextOffset; address += (long)nextOffset;
} while (nextOffset != 0); } while (nextOffset != 0);
} }
......
...@@ -142,6 +142,15 @@ void* getProcessHandle() { ...@@ -142,6 +142,15 @@ void* getProcessHandle() {
return (void*)GetModuleHandle(NULL); return (void*)GetModuleHandle(NULL);
} }
int
getErrorString(int err, char *buf, size_t len)
{
int ret = 0;
if (err == 0 || len < 1) return 0;
ret = strerror_s(buf, len, err);
return ret;
}
/* /*
* Windows symbols can be simple like JNI_OnLoad or __stdcall format * Windows symbols can be simple like JNI_OnLoad or __stdcall format
* like _JNI_OnLoad@8. We need to handle both. * like _JNI_OnLoad@8. We need to handle both.
......
/* /*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -70,6 +70,25 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd) ...@@ -70,6 +70,25 @@ static jboolean purgeOutstandingICMP(JNIEnv *env, jint fd)
return got_icmp; return got_icmp;
} }
static jfieldID IO_fd_fdID = NULL;
static jfieldID pdsi_fdID = NULL;
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: initIDs
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_initIDs
(JNIEnv *env, jclass clazz)
{
pdsi_fdID = (*env)->GetFieldID(env, clazz, "fd",
"Ljava/io/FileDescriptor;");
CHECK_NULL(pdsi_fdID);
IO_fd_fdID = NET_GetFileDescriptorID(env);
CHECK_NULL(IO_fd_fdID);
JNU_CHECK_EXCEPTION(env);
}
/* /*
* Class: java_net_DualStackPlainDatagramSocketImpl * Class: java_net_DualStackPlainDatagramSocketImpl
* Method: socketCreate * Method: socketCreate
...@@ -498,3 +517,32 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketGetI ...@@ -498,3 +517,32 @@ JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_socketGetI
return result; return result;
} }
/*
* Class: java_net_DualStackPlainDatagramSocketImpl
* Method: dataAvailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_java_net_DualStackPlainDatagramSocketImpl_dataAvailable
(JNIEnv *env, jobject this) {
SOCKET fd;
int rv = -1;
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
if (!IS_NULL(fdObj)) {
int retval = 0;
fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID);
rv = ioctlsocket(fd, FIONREAD, &retval);
if (retval > 0) {
return retval;
}
}
if (rv < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
}
return 0;
}
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -2239,8 +2239,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj ...@@ -2239,8 +2239,11 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobj
optlen = sizeof(optval.i); optlen = sizeof(optval.i);
if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) { if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
char errmsg[255]; char tmpbuf[255];
sprintf(errmsg, "error getting socket option: %s\n", strerror(errno)); int size = 0;
char errmsg[255 + 31];
getErrorString(errno, tmpbuf, sizeof(tmpbuf));
sprintf(errmsg, "error getting socket option: %s", tmpbuf);
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", errmsg);
return NULL; return NULL;
} }
...@@ -2591,3 +2594,44 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_leave(JNIEnv *env, jobject this, ...@@ -2591,3 +2594,44 @@ Java_java_net_TwoStacksPlainDatagramSocketImpl_leave(JNIEnv *env, jobject this,
{ {
mcast_join_leave (env, this, iaObj, niObj, JNI_FALSE); mcast_join_leave (env, this, iaObj, niObj, JNI_FALSE);
} }
/*
* Class: java_net_TwoStacksPlainDatagramSocketImpl
* Method: dataAvailable
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_java_net_TwoStacksPlainDatagramSocketImpl_dataAvailable
(JNIEnv *env, jobject this) {
SOCKET fd;
SOCKET fd1;
int rv = -1, rv1 = -1;
jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
jobject fd1Obj;
if (!IS_NULL(fdObj)) {
int retval = 0;
fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID);
rv = ioctlsocket(fd, FIONREAD, &retval);
if (retval > 0) {
return retval;
}
}
fd1Obj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
if (!IS_NULL(fd1Obj)) {
int retval = 0;
fd1 = (SOCKET)(*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
rv1 = ioctlsocket(fd1, FIONREAD, &retval);
if (retval > 0) {
return retval;
}
}
if (rv < 0 && rv1 < 0) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket closed");
return -1;
}
return 0;
}
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -114,8 +114,9 @@ void SetupThreadGraphicsInfo(JNIEnv *env, GDIWinSDOps *wsdo) { ...@@ -114,8 +114,9 @@ void SetupThreadGraphicsInfo(JNIEnv *env, GDIWinSDOps *wsdo) {
// which may've been disposed by this time, and we have // which may've been disposed by this time, and we have
// no means of checking against it. // no means of checking against it.
if (oldhDC != NULL) { if (oldhDC != NULL) {
MoveDCToPassiveList(oldhDC); MoveDCToPassiveList(oldhDC, info->hWnd);
info->hDC = NULL; info->hDC = NULL;
info->hWnd = NULL;
} }
if (wsdo->window != NULL){ if (wsdo->window != NULL){
...@@ -150,6 +151,7 @@ void SetupThreadGraphicsInfo(JNIEnv *env, GDIWinSDOps *wsdo) { ...@@ -150,6 +151,7 @@ void SetupThreadGraphicsInfo(JNIEnv *env, GDIWinSDOps *wsdo) {
// Finally, set these new values in the info for this thread // Finally, set these new values in the info for this thread
info->hDC = hDC; info->hDC = hDC;
info->hWnd = wsdo->window;
} }
// cached brush and pen are not associated with any DC, and can be // cached brush and pen are not associated with any DC, and can be
...@@ -187,7 +189,7 @@ void DisposeThreadGraphicsInfo(JNIEnv *env, jlong tgi) { ...@@ -187,7 +189,7 @@ void DisposeThreadGraphicsInfo(JNIEnv *env, jlong tgi) {
if (info->hDC != NULL) { if (info->hDC != NULL) {
// move the DC from the active dcs list to // move the DC from the active dcs list to
// the passive dc list to be released later // the passive dc list to be released later
MoveDCToPassiveList(info->hDC); MoveDCToPassiveList(info->hDC, info->hWnd);
} }
if (info->clip != NULL) { if (info->clip != NULL) {
......
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -196,6 +196,7 @@ extern "C" { ...@@ -196,6 +196,7 @@ extern "C" {
*/ */
typedef struct { typedef struct {
HDC hDC; HDC hDC;
HWND hWnd;
GDIWinSDOps *wsdo; GDIWinSDOps *wsdo;
LONG wsdoTimeStamp; // wsdo creation time stamp. LONG wsdoTimeStamp; // wsdo creation time stamp.
// Other threads may deallocate wsdo // Other threads may deallocate wsdo
......
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -157,7 +157,7 @@ Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6, ...@@ -157,7 +157,7 @@ Java_sun_nio_ch_Net_socket0(JNIEnv *env, jclass cl, jboolean preferIPv6,
if (loopback_available) { if (loopback_available) {
int rv = NET_EnableFastTcpLoopback((jint)s); int rv = NET_EnableFastTcpLoopback((jint)s);
if (rv) { if (rv) {
if (rv == WSAEOPNOTSUPP) { if (rv == WSAEOPNOTSUPP || rv == WSAEINVAL) {
loopback_available = 0; loopback_available = 0;
} else { } else {
NET_ThrowNew(env, rv, "fastLoopback"); NET_ThrowNew(env, rv, "fastLoopback");
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册