--- a/jdk/make/java/java/Makefile Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/make/java/java/Makefile Thu Oct 11 11:47:05 2012 +0100
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 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
@@ -64,13 +64,11 @@
include Exportedfiles.gmk
ifeq ($(PLATFORM),windows)
-FILES_java += java/io/Win32FileSystem.java \
- java/io/WinNTFileSystem.java \
+FILES_java += java/io/WinNTFileSystem.java \
java/util/prefs/WindowsPreferences.java \
java/util/prefs/WindowsPreferencesFactory.java
FILES_c += ProcessImpl_md.c \
- Win32FileSystem_md.c \
WinNTFileSystem_md.c \
canonicalize_md.c \
dirent_md.c \
--- a/jdk/makefiles/CompileNativeLibraries.gmk Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/makefiles/CompileNativeLibraries.gmk Thu Oct 11 11:47:05 2012 +0100
@@ -209,7 +209,6 @@
else
LIBJAVA_EXCLUDE_FILES += \
ProcessImpl_md.c \
- Win32FileSystem_md.c \
WinNTFileSystem_md.c \
dirent_md.c \
WindowsPreferences.c \
--- a/jdk/src/windows/classes/java/io/Win32FileSystem.java Wed Oct 10 17:34:27 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,608 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, 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 java.io;
-
-import java.security.AccessController;
-import java.util.Locale;
-import sun.security.action.GetPropertyAction;
-
-
-class Win32FileSystem extends FileSystem {
-
- private final char slash;
- private final char altSlash;
- private final char semicolon;
-
- public Win32FileSystem() {
- slash = AccessController.doPrivileged(
- new GetPropertyAction("file.separator")).charAt(0);
- semicolon = AccessController.doPrivileged(
- new GetPropertyAction("path.separator")).charAt(0);
- altSlash = (this.slash == '\\') ? '/' : '\\';
- }
-
- private boolean isSlash(char c) {
- return (c == '\\') || (c == '/');
- }
-
- private boolean isLetter(char c) {
- return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
- }
-
- private String slashify(String p) {
- if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p;
- else return p;
- }
-
-
- /* -- Normalization and construction -- */
-
- public char getSeparator() {
- return slash;
- }
-
- public char getPathSeparator() {
- return semicolon;
- }
-
- /* A normal Win32 pathname contains no duplicate slashes, except possibly
- for a UNC prefix, and does not end with a slash. It may be the empty
- string. Normalized Win32 pathnames have the convenient property that
- the length of the prefix almost uniquely identifies the type of the path
- and whether it is absolute or relative:
-
- 0 relative to both drive and directory
- 1 drive-relative (begins with '\\')
- 2 absolute UNC (if first char is '\\'),
- else directory-relative (has form "z:foo")
- 3 absolute local pathname (begins with "z:\\")
- */
-
- private int normalizePrefix(String path, int len, StringBuffer sb) {
- int src = 0;
- while ((src < len) && isSlash(path.charAt(src))) src++;
- char c;
- if ((len - src >= 2)
- && isLetter(c = path.charAt(src))
- && path.charAt(src + 1) == ':') {
- /* Remove leading slashes if followed by drive specifier.
- This hack is necessary to support file URLs containing drive
- specifiers (e.g., "file://c:/path"). As a side effect,
- "/c:/path" can be used as an alternative to "c:/path". */
- sb.append(c);
- sb.append(':');
- src += 2;
- } else {
- src = 0;
- if ((len >= 2)
- && isSlash(path.charAt(0))
- && isSlash(path.charAt(1))) {
- /* UNC pathname: Retain first slash; leave src pointed at
- second slash so that further slashes will be collapsed
- into the second slash. The result will be a pathname
- beginning with "\\\\" followed (most likely) by a host
- name. */
- src = 1;
- sb.append(slash);
- }
- }
- return src;
- }
-
- /* Normalize the given pathname, whose length is len, starting at the given
- offset; everything before this offset is already normal. */
- private String normalize(String path, int len, int off) {
- if (len == 0) return path;
- if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */
- int src;
- char slash = this.slash;
- StringBuffer sb = new StringBuffer(len);
-
- if (off == 0) {
- /* Complete normalization, including prefix */
- src = normalizePrefix(path, len, sb);
- } else {
- /* Partial normalization */
- src = off;
- sb.append(path.substring(0, off));
- }
-
- /* Remove redundant slashes from the remainder of the path, forcing all
- slashes into the preferred slash */
- while (src < len) {
- char c = path.charAt(src++);
- if (isSlash(c)) {
- while ((src < len) && isSlash(path.charAt(src))) src++;
- if (src == len) {
- /* Check for trailing separator */
- int sn = sb.length();
- if ((sn == 2) && (sb.charAt(1) == ':')) {
- /* "z:\\" */
- sb.append(slash);
- break;
- }
- if (sn == 0) {
- /* "\\" */
- sb.append(slash);
- break;
- }
- if ((sn == 1) && (isSlash(sb.charAt(0)))) {
- /* "\\\\" is not collapsed to "\\" because "\\\\" marks
- the beginning of a UNC pathname. Even though it is
- not, by itself, a valid UNC pathname, we leave it as
- is in order to be consistent with the win32 APIs,
- which treat this case as an invalid UNC pathname
- rather than as an alias for the root directory of
- the current drive. */
- sb.append(slash);
- break;
- }
- /* Path does not denote a root directory, so do not append
- trailing slash */
- break;
- } else {
- sb.append(slash);
- }
- } else {
- sb.append(c);
- }
- }
-
- String rv = sb.toString();
- return rv;
- }
-
- /* Check that the given pathname is normal. If not, invoke the real
- normalizer on the part of the pathname that requires normalization.
- This way we iterate through the whole pathname string only once. */
- public String normalize(String path) {
- int n = path.length();
- char slash = this.slash;
- char altSlash = this.altSlash;
- char prev = 0;
- for (int i = 0; i < n; i++) {
- char c = path.charAt(i);
- if (c == altSlash)
- return normalize(path, n, (prev == slash) ? i - 1 : i);
- if ((c == slash) && (prev == slash) && (i > 1))
- return normalize(path, n, i - 1);
- if ((c == ':') && (i > 1))
- return normalize(path, n, 0);
- prev = c;
- }
- if (prev == slash) return normalize(path, n, n - 1);
- return path;
- }
-
- public int prefixLength(String path) {
- char slash = this.slash;
- int n = path.length();
- if (n == 0) return 0;
- char c0 = path.charAt(0);
- char c1 = (n > 1) ? path.charAt(1) : 0;
- if (c0 == slash) {
- if (c1 == slash) return 2; /* Absolute UNC pathname "\\\\foo" */
- return 1; /* Drive-relative "\\foo" */
- }
- if (isLetter(c0) && (c1 == ':')) {
- if ((n > 2) && (path.charAt(2) == slash))
- return 3; /* Absolute local pathname "z:\\foo" */
- return 2; /* Directory-relative "z:foo" */
- }
- return 0; /* Completely relative */
- }
-
- public String resolve(String parent, String child) {
- int pn = parent.length();
- if (pn == 0) return child;
- int cn = child.length();
- if (cn == 0) return parent;
-
- String c = child;
- int childStart = 0;
- int parentEnd = pn;
-
- if ((cn > 1) && (c.charAt(0) == slash)) {
- if (c.charAt(1) == slash) {
- /* Drop prefix when child is a UNC pathname */
- childStart = 2;
- } else {
- /* Drop prefix when child is drive-relative */
- childStart = 1;
-
- }
- if (cn == childStart) { // Child is double slash
- if (parent.charAt(pn - 1) == slash)
- return parent.substring(0, pn - 1);
- return parent;
- }
- }
-
- if (parent.charAt(pn - 1) == slash)
- parentEnd--;
-
- int strlen = parentEnd + cn - childStart;
- char[] theChars = null;
- if (child.charAt(childStart) == slash) {
- theChars = new char[strlen];
- parent.getChars(0, parentEnd, theChars, 0);
- child.getChars(childStart, cn, theChars, parentEnd);
- } else {
- theChars = new char[strlen + 1];
- parent.getChars(0, parentEnd, theChars, 0);
- theChars[parentEnd] = slash;
- child.getChars(childStart, cn, theChars, parentEnd + 1);
- }
- return new String(theChars);
- }
-
- public String getDefaultParent() {
- return ("" + slash);
- }
-
- public String fromURIPath(String path) {
- String p = path;
- if ((p.length() > 2) && (p.charAt(2) == ':')) {
- // "/c:/foo" --> "c:/foo"
- p = p.substring(1);
- // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/"
- if ((p.length() > 3) && p.endsWith("/"))
- p = p.substring(0, p.length() - 1);
- } else if ((p.length() > 1) && p.endsWith("/")) {
- // "/foo/" --> "/foo"
- p = p.substring(0, p.length() - 1);
- }
- return p;
- }
-
-
-
- /* -- Path operations -- */
-
- public boolean isAbsolute(File f) {
- int pl = f.getPrefixLength();
- return (((pl == 2) && (f.getPath().charAt(0) == slash))
- || (pl == 3));
- }
-
- protected native String getDriveDirectory(int drive);
-
- private static String[] driveDirCache = new String[26];
-
- private static int driveIndex(char d) {
- if ((d >= 'a') && (d <= 'z')) return d - 'a';
- if ((d >= 'A') && (d <= 'Z')) return d - 'A';
- return -1;
- }
-
- private String getDriveDirectory(char drive) {
- int i = driveIndex(drive);
- if (i < 0) return null;
- String s = driveDirCache[i];
- if (s != null) return s;
- s = getDriveDirectory(i + 1);
- driveDirCache[i] = s;
- return s;
- }
-
- private String getUserPath() {
- /* For both compatibility and security,
- we must look this up every time */
- return normalize(System.getProperty("user.dir"));
- }
-
- private String getDrive(String path) {
- int pl = prefixLength(path);
- return (pl == 3) ? path.substring(0, 2) : null;
- }
-
- public String resolve(File f) {
- String path = f.getPath();
- int pl = f.getPrefixLength();
- if ((pl == 2) && (path.charAt(0) == slash))
- return path; /* UNC */
- if (pl == 3)
- return path; /* Absolute local */
- if (pl == 0)
- return getUserPath() + slashify(path); /* Completely relative */
- if (pl == 1) { /* Drive-relative */
- String up = getUserPath();
- String ud = getDrive(up);
- if (ud != null) return ud + path;
- return up + path; /* User dir is a UNC path */
- }
- if (pl == 2) { /* Directory-relative */
- String up = getUserPath();
- String ud = getDrive(up);
- if ((ud != null) && path.startsWith(ud))
- return up + slashify(path.substring(2));
- char drive = path.charAt(0);
- String dir = getDriveDirectory(drive);
- String np;
- if (dir != null) {
- /* When resolving a directory-relative path that refers to a
- drive other than the current drive, insist that the caller
- have read permission on the result */
- String p = drive + (':' + dir + slashify(path.substring(2)));
- SecurityManager security = System.getSecurityManager();
- try {
- if (security != null) security.checkRead(p);
- } catch (SecurityException x) {
- /* Don't disclose the drive's directory in the exception */
- throw new SecurityException("Cannot resolve path " + path);
- }
- return p;
- }
- return drive + ":" + slashify(path.substring(2)); /* fake it */
- }
- throw new InternalError("Unresolvable path: " + path);
- }
-
- // Caches for canonicalization results to improve startup performance.
- // The first cache handles repeated canonicalizations of the same path
- // name. The prefix cache handles repeated canonicalizations within the
- // same directory, and must not create results differing from the true
- // canonicalization algorithm in canonicalize_md.c. For this reason the
- // prefix cache is conservative and is not used for complex path names.
- private ExpiringCache cache = new ExpiringCache();
- private ExpiringCache prefixCache = new ExpiringCache();
-
- public String canonicalize(String path) throws IOException {
- // If path is a drive letter only then skip canonicalization
- int len = path.length();
- if ((len == 2) &&
- (isLetter(path.charAt(0))) &&
- (path.charAt(1) == ':')) {
- char c = path.charAt(0);
- if ((c >= 'A') && (c <= 'Z'))
- return path;
- return "" + ((char) (c-32)) + ':';
- } else if ((len == 3) &&
- (isLetter(path.charAt(0))) &&
- (path.charAt(1) == ':') &&
- (path.charAt(2) == '\\')) {
- char c = path.charAt(0);
- if ((c >= 'A') && (c <= 'Z'))
- return path;
- return "" + ((char) (c-32)) + ':' + '\\';
- }
- if (!useCanonCaches) {
- return canonicalize0(path);
- } else {
- String res = cache.get(path);
- if (res == null) {
- String dir = null;
- String resDir = null;
- if (useCanonPrefixCache) {
- dir = parentOrNull(path);
- if (dir != null) {
- resDir = prefixCache.get(dir);
- if (resDir != null) {
- // Hit only in prefix cache; full path is canonical,
- // but we need to get the canonical name of the file
- // in this directory to get the appropriate capitalization
- String filename = path.substring(1 + dir.length());
- res = canonicalizeWithPrefix(resDir, filename);
- cache.put(dir + File.separatorChar + filename, res);
- }
- }
- }
- if (res == null) {
- res = canonicalize0(path);
- cache.put(path, res);
- if (useCanonPrefixCache && dir != null) {
- resDir = parentOrNull(res);
- if (resDir != null) {
- File f = new File(res);
- if (f.exists() && !f.isDirectory()) {
- prefixCache.put(dir, resDir);
- }
- }
- }
- }
- }
- return res;
- }
- }
-
- protected native String canonicalize0(String path)
- throws IOException;
- protected String canonicalizeWithPrefix(String canonicalPrefix,
- String filename) throws IOException
- {
- return canonicalizeWithPrefix0(canonicalPrefix,
- canonicalPrefix + File.separatorChar + filename);
- }
- // Run the canonicalization operation assuming that the prefix
- // (everything up to the last filename) is canonical; just gets
- // the canonical name of the last element of the path
- protected native String canonicalizeWithPrefix0(String canonicalPrefix,
- String pathWithCanonicalPrefix)
- throws IOException;
- // Best-effort attempt to get parent of this path; used for
- // optimization of filename canonicalization. This must return null for
- // any cases where the code in canonicalize_md.c would throw an
- // exception or otherwise deal with non-simple pathnames like handling
- // of "." and "..". It may conservatively return null in other
- // situations as well. Returning null will cause the underlying
- // (expensive) canonicalization routine to be called.
- static String parentOrNull(String path) {
- if (path == null) return null;
- char sep = File.separatorChar;
- char altSep = '/';
- int last = path.length() - 1;
- int idx = last;
- int adjacentDots = 0;
- int nonDotCount = 0;
- while (idx > 0) {
- char c = path.charAt(idx);
- if (c == '.') {
- if (++adjacentDots >= 2) {
- // Punt on pathnames containing . and ..
- return null;
- }
- if (nonDotCount == 0) {
- // Punt on pathnames ending in a .
- return null;
- }
- } else if (c == sep) {
- if (adjacentDots == 1 && nonDotCount == 0) {
- // Punt on pathnames containing . and ..
- return null;
- }
- if (idx == 0 ||
- idx >= last - 1 ||
- path.charAt(idx - 1) == sep ||
- path.charAt(idx - 1) == altSep) {
- // Punt on pathnames containing adjacent slashes
- // toward the end
- return null;
- }
- return path.substring(0, idx);
- } else if (c == altSep) {
- // Punt on pathnames containing both backward and
- // forward slashes
- return null;
- } else if (c == '*' || c == '?') {
- // Punt on pathnames containing wildcards
- return null;
- } else {
- ++nonDotCount;
- adjacentDots = 0;
- }
- --idx;
- }
- return null;
- }
-
-
- /* -- Attribute accessors -- */
-
- public native int getBooleanAttributes(File f);
- public native boolean checkAccess(File f, int access);
- public native long getLastModifiedTime(File f);
- public native long getLength(File f);
- public native boolean setPermission(File f, int access, boolean enable, boolean owneronly);
-
- /* -- File operations -- */
-
- public native boolean createFileExclusively(String path)
- throws IOException;
- public boolean delete(File f) {
- // Keep canonicalization caches in sync after file deletion
- // and renaming operations. Could be more clever than this
- // (i.e., only remove/update affected entries) but probably
- // not worth it since these entries expire after 30 seconds
- // anyway.
- cache.clear();
- prefixCache.clear();
- return delete0(f);
- }
- protected native boolean delete0(File f);
- public native String[] list(File f);
- public native boolean createDirectory(File f);
- public boolean rename(File f1, File f2) {
- // Keep canonicalization caches in sync after file deletion
- // and renaming operations. Could be more clever than this
- // (i.e., only remove/update affected entries) but probably
- // not worth it since these entries expire after 30 seconds
- // anyway.
- cache.clear();
- prefixCache.clear();
- return rename0(f1, f2);
- }
- protected native boolean rename0(File f1, File f2);
- public native boolean setLastModifiedTime(File f, long time);
- public native boolean setReadOnly(File f);
-
-
- /* -- Filesystem interface -- */
-
- private boolean access(String path) {
- try {
- SecurityManager security = System.getSecurityManager();
- if (security != null) security.checkRead(path);
- return true;
- } catch (SecurityException x) {
- return false;
- }
- }
-
- private static native int listRoots0();
-
- public File[] listRoots() {
- int ds = listRoots0();
- int n = 0;
- for (int i = 0; i < 26; i++) {
- if (((ds >> i) & 1) != 0) {
- if (!access((char)('A' + i) + ":" + slash))
- ds &= ~(1 << i);
- else
- n++;
- }
- }
- File[] fs = new File[n];
- int j = 0;
- char slash = this.slash;
- for (int i = 0; i < 26; i++) {
- if (((ds >> i) & 1) != 0)
- fs[j++] = new File((char)('A' + i) + ":" + slash);
- }
- return fs;
- }
-
-
- /* -- Disk usage -- */
- public long getSpace(File f, int t) {
- if (f.exists()) {
- File file = (f.isDirectory() ? f : f.getParentFile());
- return getSpace0(file, t);
- }
- return 0;
- }
-
- private native long getSpace0(File f, int t);
-
-
- /* -- Basic infrastructure -- */
-
- public int compare(File f1, File f2) {
- return f1.getPath().compareToIgnoreCase(f2.getPath());
- }
-
- public int hashCode(File f) {
- /* Could make this more efficient: String.hashCodeIgnoreCase */
- return f.getPath().toLowerCase(Locale.ENGLISH).hashCode() ^ 1234321;
- }
-
-
- private static native void initIDs();
-
- static {
- initIDs();
- }
-
-}
--- a/jdk/src/windows/classes/java/io/WinNTFileSystem.java Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/src/windows/classes/java/io/WinNTFileSystem.java Thu Oct 11 11:47:05 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -23,10 +23,11 @@
* questions.
*/
-/*
- */
+package java.io;
-package java.io;
+import java.security.AccessController;
+import java.util.Locale;
+import sun.security.action.GetPropertyAction;
/**
* Unicode-aware FileSystem for Windows NT/2000.
@@ -34,23 +35,589 @@
* @author Konstantin Kladko
* @since 1.4
*/
-class WinNTFileSystem extends Win32FileSystem {
+class WinNTFileSystem extends FileSystem {
+
+ private final char slash;
+ private final char altSlash;
+ private final char semicolon;
+
+ public WinNTFileSystem() {
+ slash = AccessController.doPrivileged(
+ new GetPropertyAction("file.separator")).charAt(0);
+ semicolon = AccessController.doPrivileged(
+ new GetPropertyAction("path.separator")).charAt(0);
+ altSlash = (this.slash == '\\') ? '/' : '\\';
+ }
+
+ private boolean isSlash(char c) {
+ return (c == '\\') || (c == '/');
+ }
+
+ private boolean isLetter(char c) {
+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
+ }
+
+ private String slashify(String p) {
+ if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p;
+ else return p;
+ }
+
+ /* -- Normalization and construction -- */
+
+ @Override
+ public char getSeparator() {
+ return slash;
+ }
+
+ @Override
+ public char getPathSeparator() {
+ return semicolon;
+ }
+
+ /* Check that the given pathname is normal. If not, invoke the real
+ normalizer on the part of the pathname that requires normalization.
+ This way we iterate through the whole pathname string only once. */
+ @Override
+ public String normalize(String path) {
+ int n = path.length();
+ char slash = this.slash;
+ char altSlash = this.altSlash;
+ char prev = 0;
+ for (int i = 0; i < n; i++) {
+ char c = path.charAt(i);
+ if (c == altSlash)
+ return normalize(path, n, (prev == slash) ? i - 1 : i);
+ if ((c == slash) && (prev == slash) && (i > 1))
+ return normalize(path, n, i - 1);
+ if ((c == ':') && (i > 1))
+ return normalize(path, n, 0);
+ prev = c;
+ }
+ if (prev == slash) return normalize(path, n, n - 1);
+ return path;
+ }
+
+ /* Normalize the given pathname, whose length is len, starting at the given
+ offset; everything before this offset is already normal. */
+ private String normalize(String path, int len, int off) {
+ if (len == 0) return path;
+ if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */
+ int src;
+ char slash = this.slash;
+ StringBuffer sb = new StringBuffer(len);
+
+ if (off == 0) {
+ /* Complete normalization, including prefix */
+ src = normalizePrefix(path, len, sb);
+ } else {
+ /* Partial normalization */
+ src = off;
+ sb.append(path.substring(0, off));
+ }
+
+ /* Remove redundant slashes from the remainder of the path, forcing all
+ slashes into the preferred slash */
+ while (src < len) {
+ char c = path.charAt(src++);
+ if (isSlash(c)) {
+ while ((src < len) && isSlash(path.charAt(src))) src++;
+ if (src == len) {
+ /* Check for trailing separator */
+ int sn = sb.length();
+ if ((sn == 2) && (sb.charAt(1) == ':')) {
+ /* "z:\\" */
+ sb.append(slash);
+ break;
+ }
+ if (sn == 0) {
+ /* "\\" */
+ sb.append(slash);
+ break;
+ }
+ if ((sn == 1) && (isSlash(sb.charAt(0)))) {
+ /* "\\\\" is not collapsed to "\\" because "\\\\" marks
+ the beginning of a UNC pathname. Even though it is
+ not, by itself, a valid UNC pathname, we leave it as
+ is in order to be consistent with the win32 APIs,
+ which treat this case as an invalid UNC pathname
+ rather than as an alias for the root directory of
+ the current drive. */
+ sb.append(slash);
+ break;
+ }
+ /* Path does not denote a root directory, so do not append
+ trailing slash */
+ break;
+ } else {
+ sb.append(slash);
+ }
+ } else {
+ sb.append(c);
+ }
+ }
+
+ String rv = sb.toString();
+ return rv;
+ }
+
+ /* A normal Win32 pathname contains no duplicate slashes, except possibly
+ for a UNC prefix, and does not end with a slash. It may be the empty
+ string. Normalized Win32 pathnames have the convenient property that
+ the length of the prefix almost uniquely identifies the type of the path
+ and whether it is absolute or relative:
+
+ 0 relative to both drive and directory
+ 1 drive-relative (begins with '\\')
+ 2 absolute UNC (if first char is '\\'),
+ else directory-relative (has form "z:foo")
+ 3 absolute local pathname (begins with "z:\\")
+ */
+ private int normalizePrefix(String path, int len, StringBuffer sb) {
+ int src = 0;
+ while ((src < len) && isSlash(path.charAt(src))) src++;
+ char c;
+ if ((len - src >= 2)
+ && isLetter(c = path.charAt(src))
+ && path.charAt(src + 1) == ':') {
+ /* Remove leading slashes if followed by drive specifier.
+ This hack is necessary to support file URLs containing drive
+ specifiers (e.g., "file://c:/path"). As a side effect,
+ "/c:/path" can be used as an alternative to "c:/path". */
+ sb.append(c);
+ sb.append(':');
+ src += 2;
+ } else {
+ src = 0;
+ if ((len >= 2)
+ && isSlash(path.charAt(0))
+ && isSlash(path.charAt(1))) {
+ /* UNC pathname: Retain first slash; leave src pointed at
+ second slash so that further slashes will be collapsed
+ into the second slash. The result will be a pathname
+ beginning with "\\\\" followed (most likely) by a host
+ name. */
+ src = 1;
+ sb.append(slash);
+ }
+ }
+ return src;
+ }
+
+ @Override
+ public int prefixLength(String path) {
+ char slash = this.slash;
+ int n = path.length();
+ if (n == 0) return 0;
+ char c0 = path.charAt(0);
+ char c1 = (n > 1) ? path.charAt(1) : 0;
+ if (c0 == slash) {
+ if (c1 == slash) return 2; /* Absolute UNC pathname "\\\\foo" */
+ return 1; /* Drive-relative "\\foo" */
+ }
+ if (isLetter(c0) && (c1 == ':')) {
+ if ((n > 2) && (path.charAt(2) == slash))
+ return 3; /* Absolute local pathname "z:\\foo" */
+ return 2; /* Directory-relative "z:foo" */
+ }
+ return 0; /* Completely relative */
+ }
+
+ @Override
+ public String resolve(String parent, String child) {
+ int pn = parent.length();
+ if (pn == 0) return child;
+ int cn = child.length();
+ if (cn == 0) return parent;
+
+ String c = child;
+ int childStart = 0;
+ int parentEnd = pn;
+
+ if ((cn > 1) && (c.charAt(0) == slash)) {
+ if (c.charAt(1) == slash) {
+ /* Drop prefix when child is a UNC pathname */
+ childStart = 2;
+ } else {
+ /* Drop prefix when child is drive-relative */
+ childStart = 1;
+
+ }
+ if (cn == childStart) { // Child is double slash
+ if (parent.charAt(pn - 1) == slash)
+ return parent.substring(0, pn - 1);
+ return parent;
+ }
+ }
+
+ if (parent.charAt(pn - 1) == slash)
+ parentEnd--;
+
+ int strlen = parentEnd + cn - childStart;
+ char[] theChars = null;
+ if (child.charAt(childStart) == slash) {
+ theChars = new char[strlen];
+ parent.getChars(0, parentEnd, theChars, 0);
+ child.getChars(childStart, cn, theChars, parentEnd);
+ } else {
+ theChars = new char[strlen + 1];
+ parent.getChars(0, parentEnd, theChars, 0);
+ theChars[parentEnd] = slash;
+ child.getChars(childStart, cn, theChars, parentEnd + 1);
+ }
+ return new String(theChars);
+ }
+
+ @Override
+ public String getDefaultParent() {
+ return ("" + slash);
+ }
- protected native String canonicalize0(String path)
- throws IOException;
- protected native String canonicalizeWithPrefix0(String canonicalPrefix,
- String pathWithCanonicalPrefix)
- throws IOException;
+ @Override
+ public String fromURIPath(String path) {
+ String p = path;
+ if ((p.length() > 2) && (p.charAt(2) == ':')) {
+ // "/c:/foo" --> "c:/foo"
+ p = p.substring(1);
+ // "c:/foo/" --> "c:/foo", but "c:/" --> "c:/"
+ if ((p.length() > 3) && p.endsWith("/"))
+ p = p.substring(0, p.length() - 1);
+ } else if ((p.length() > 1) && p.endsWith("/")) {
+ // "/foo/" --> "/foo"
+ p = p.substring(0, p.length() - 1);
+ }
+ return p;
+ }
+
+ /* -- Path operations -- */
+
+ @Override
+ public boolean isAbsolute(File f) {
+ int pl = f.getPrefixLength();
+ return (((pl == 2) && (f.getPath().charAt(0) == slash))
+ || (pl == 3));
+ }
+
+ @Override
+ public String resolve(File f) {
+ String path = f.getPath();
+ int pl = f.getPrefixLength();
+ if ((pl == 2) && (path.charAt(0) == slash))
+ return path; /* UNC */
+ if (pl == 3)
+ return path; /* Absolute local */
+ if (pl == 0)
+ return getUserPath() + slashify(path); /* Completely relative */
+ if (pl == 1) { /* Drive-relative */
+ String up = getUserPath();
+ String ud = getDrive(up);
+ if (ud != null) return ud + path;
+ return up + path; /* User dir is a UNC path */
+ }
+ if (pl == 2) { /* Directory-relative */
+ String up = getUserPath();
+ String ud = getDrive(up);
+ if ((ud != null) && path.startsWith(ud))
+ return up + slashify(path.substring(2));
+ char drive = path.charAt(0);
+ String dir = getDriveDirectory(drive);
+ String np;
+ if (dir != null) {
+ /* When resolving a directory-relative path that refers to a
+ drive other than the current drive, insist that the caller
+ have read permission on the result */
+ String p = drive + (':' + dir + slashify(path.substring(2)));
+ SecurityManager security = System.getSecurityManager();
+ try {
+ if (security != null) security.checkRead(p);
+ } catch (SecurityException x) {
+ /* Don't disclose the drive's directory in the exception */
+ throw new SecurityException("Cannot resolve path " + path);
+ }
+ return p;
+ }
+ return drive + ":" + slashify(path.substring(2)); /* fake it */
+ }
+ throw new InternalError("Unresolvable path: " + path);
+ }
+
+ private String getUserPath() {
+ /* For both compatibility and security,
+ we must look this up every time */
+ return normalize(System.getProperty("user.dir"));
+ }
+
+ private String getDrive(String path) {
+ int pl = prefixLength(path);
+ return (pl == 3) ? path.substring(0, 2) : null;
+ }
+
+ private static String[] driveDirCache = new String[26];
+
+ private static int driveIndex(char d) {
+ if ((d >= 'a') && (d <= 'z')) return d - 'a';
+ if ((d >= 'A') && (d <= 'Z')) return d - 'A';
+ return -1;
+ }
+
+ private native String getDriveDirectory(int drive);
+
+ private String getDriveDirectory(char drive) {
+ int i = driveIndex(drive);
+ if (i < 0) return null;
+ String s = driveDirCache[i];
+ if (s != null) return s;
+ s = getDriveDirectory(i + 1);
+ driveDirCache[i] = s;
+ return s;
+ }
+
+ // Caches for canonicalization results to improve startup performance.
+ // The first cache handles repeated canonicalizations of the same path
+ // name. The prefix cache handles repeated canonicalizations within the
+ // same directory, and must not create results differing from the true
+ // canonicalization algorithm in canonicalize_md.c. For this reason the
+ // prefix cache is conservative and is not used for complex path names.
+ private ExpiringCache cache = new ExpiringCache();
+ private ExpiringCache prefixCache = new ExpiringCache();
+
+ @Override
+ public String canonicalize(String path) throws IOException {
+ // If path is a drive letter only then skip canonicalization
+ int len = path.length();
+ if ((len == 2) &&
+ (isLetter(path.charAt(0))) &&
+ (path.charAt(1) == ':')) {
+ char c = path.charAt(0);
+ if ((c >= 'A') && (c <= 'Z'))
+ return path;
+ return "" + ((char) (c-32)) + ':';
+ } else if ((len == 3) &&
+ (isLetter(path.charAt(0))) &&
+ (path.charAt(1) == ':') &&
+ (path.charAt(2) == '\\')) {
+ char c = path.charAt(0);
+ if ((c >= 'A') && (c <= 'Z'))
+ return path;
+ return "" + ((char) (c-32)) + ':' + '\\';
+ }
+ if (!useCanonCaches) {
+ return canonicalize0(path);
+ } else {
+ String res = cache.get(path);
+ if (res == null) {
+ String dir = null;
+ String resDir = null;
+ if (useCanonPrefixCache) {
+ dir = parentOrNull(path);
+ if (dir != null) {
+ resDir = prefixCache.get(dir);
+ if (resDir != null) {
+ /*
+ * Hit only in prefix cache; full path is canonical,
+ * but we need to get the canonical name of the file
+ * in this directory to get the appropriate
+ * capitalization
+ */
+ String filename = path.substring(1 + dir.length());
+ res = canonicalizeWithPrefix(resDir, filename);
+ cache.put(dir + File.separatorChar + filename, res);
+ }
+ }
+ }
+ if (res == null) {
+ res = canonicalize0(path);
+ cache.put(path, res);
+ if (useCanonPrefixCache && dir != null) {
+ resDir = parentOrNull(res);
+ if (resDir != null) {
+ File f = new File(res);
+ if (f.exists() && !f.isDirectory()) {
+ prefixCache.put(dir, resDir);
+ }
+ }
+ }
+ }
+ }
+ return res;
+ }
+ }
+
+ private native String canonicalize0(String path)
+ throws IOException;
+
+ private String canonicalizeWithPrefix(String canonicalPrefix,
+ String filename) throws IOException
+ {
+ return canonicalizeWithPrefix0(canonicalPrefix,
+ canonicalPrefix + File.separatorChar + filename);
+ }
+
+ // Run the canonicalization operation assuming that the prefix
+ // (everything up to the last filename) is canonical; just gets
+ // the canonical name of the last element of the path
+ private native String canonicalizeWithPrefix0(String canonicalPrefix,
+ String pathWithCanonicalPrefix)
+ throws IOException;
+
+ // Best-effort attempt to get parent of this path; used for
+ // optimization of filename canonicalization. This must return null for
+ // any cases where the code in canonicalize_md.c would throw an
+ // exception or otherwise deal with non-simple pathnames like handling
+ // of "." and "..". It may conservatively return null in other
+ // situations as well. Returning null will cause the underlying
+ // (expensive) canonicalization routine to be called.
+ private static String parentOrNull(String path) {
+ if (path == null) return null;
+ char sep = File.separatorChar;
+ char altSep = '/';
+ int last = path.length() - 1;
+ int idx = last;
+ int adjacentDots = 0;
+ int nonDotCount = 0;
+ while (idx > 0) {
+ char c = path.charAt(idx);
+ if (c == '.') {
+ if (++adjacentDots >= 2) {
+ // Punt on pathnames containing . and ..
+ return null;
+ }
+ if (nonDotCount == 0) {
+ // Punt on pathnames ending in a .
+ return null;
+ }
+ } else if (c == sep) {
+ if (adjacentDots == 1 && nonDotCount == 0) {
+ // Punt on pathnames containing . and ..
+ return null;
+ }
+ if (idx == 0 ||
+ idx >= last - 1 ||
+ path.charAt(idx - 1) == sep ||
+ path.charAt(idx - 1) == altSep) {
+ // Punt on pathnames containing adjacent slashes
+ // toward the end
+ return null;
+ }
+ return path.substring(0, idx);
+ } else if (c == altSep) {
+ // Punt on pathnames containing both backward and
+ // forward slashes
+ return null;
+ } else if (c == '*' || c == '?') {
+ // Punt on pathnames containing wildcards
+ return null;
+ } else {
+ ++nonDotCount;
+ adjacentDots = 0;
+ }
+ --idx;
+ }
+ return null;
+ }
/* -- Attribute accessors -- */
+ @Override
public native int getBooleanAttributes(File f);
+
+ @Override
public native boolean checkAccess(File f, int access);
+
+ @Override
public native long getLastModifiedTime(File f);
+
+ @Override
public native long getLength(File f);
- public native boolean setPermission(File f, int access, boolean enable, boolean owneronly);
+
+ @Override
+ public native boolean setPermission(File f, int access, boolean enable,
+ boolean owneronly);
+
+ /* -- File operations -- */
+
+ @Override
+ public native boolean createFileExclusively(String path)
+ throws IOException;
+
+ @Override
+ public native String[] list(File f);
+
+ @Override
+ public native boolean createDirectory(File f);
+
+ @Override
+ public native boolean setLastModifiedTime(File f, long time);
+
+ @Override
+ public native boolean setReadOnly(File f);
+
+ @Override
+ public boolean delete(File f) {
+ // Keep canonicalization caches in sync after file deletion
+ // and renaming operations. Could be more clever than this
+ // (i.e., only remove/update affected entries) but probably
+ // not worth it since these entries expire after 30 seconds
+ // anyway.
+ cache.clear();
+ prefixCache.clear();
+ return delete0(f);
+ }
+
+ private native boolean delete0(File f);
+ @Override
+ public boolean rename(File f1, File f2) {
+ // Keep canonicalization caches in sync after file deletion
+ // and renaming operations. Could be more clever than this
+ // (i.e., only remove/update affected entries) but probably
+ // not worth it since these entries expire after 30 seconds
+ // anyway.
+ cache.clear();
+ prefixCache.clear();
+ return rename0(f1, f2);
+ }
+ private native boolean rename0(File f1, File f2);
+
+ /* -- Filesystem interface -- */
+
+ @Override
+ public File[] listRoots() {
+ int ds = listRoots0();
+ int n = 0;
+ for (int i = 0; i < 26; i++) {
+ if (((ds >> i) & 1) != 0) {
+ if (!access((char)('A' + i) + ":" + slash))
+ ds &= ~(1 << i);
+ else
+ n++;
+ }
+ }
+ File[] fs = new File[n];
+ int j = 0;
+ char slash = this.slash;
+ for (int i = 0; i < 26; i++) {
+ if (((ds >> i) & 1) != 0)
+ fs[j++] = new File((char)('A' + i) + ":" + slash);
+ }
+ return fs;
+ }
+
+ private static native int listRoots0();
+
+ private boolean access(String path) {
+ try {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) security.checkRead(path);
+ return true;
+ } catch (SecurityException x) {
+ return false;
+ }
+ }
+
+ /* -- Disk usage -- */
+
+ @Override
public long getSpace(File f, int t) {
if (f.exists()) {
return getSpace0(f, t);
@@ -60,20 +627,22 @@
private native long getSpace0(File f, int t);
- /* -- File operations -- */
+ /* -- Basic infrastructure -- */
+
+ @Override
+ public int compare(File f1, File f2) {
+ return f1.getPath().compareToIgnoreCase(f2.getPath());
+ }
- public native boolean createFileExclusively(String path)
- throws IOException;
- protected native boolean delete0(File f);
- public native String[] list(File f);
- public native boolean createDirectory(File f);
- protected native boolean rename0(File f1, File f2);
- public native boolean setLastModifiedTime(File f, long time);
- public native boolean setReadOnly(File f);
- protected native String getDriveDirectory(int drive);
+ @Override
+ public int hashCode(File f) {
+ /* Could make this more efficient: String.hashCodeIgnoreCase */
+ return f.getPath().toLowerCase(Locale.ENGLISH).hashCode() ^ 1234321;
+ }
+
private static native void initIDs();
static {
- initIDs();
+ initIDs();
}
}
--- a/jdk/src/windows/native/java/io/FileSystem_md.c Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/src/windows/native/java/io/FileSystem_md.c Thu Oct 11 11:47:05 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -27,16 +27,8 @@
#include "jni.h"
#include "jni_util.h"
-extern jboolean onNT;
-extern void initializeWindowsVersion();
-
JNIEXPORT jobject JNICALL
Java_java_io_FileSystem_getFileSystem(JNIEnv *env, jclass ignored)
{
- initializeWindowsVersion();
- if (onNT) {
- return JNU_NewObjectByName(env, "java/io/WinNTFileSystem", "()V");
- } else {
- return JNU_NewObjectByName(env, "java/io/Win32FileSystem", "()V");
- }
+ return JNU_NewObjectByName(env, "java/io/WinNTFileSystem", "()V");
}
--- a/jdk/src/windows/native/java/io/Win32FileSystem_md.c Wed Oct 10 17:34:27 2012 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,509 +0,0 @@
-/*
- * Copyright (c) 1998, 2006, 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.
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <direct.h>
-#include <windows.h>
-#include <io.h>
-
-#include "jvm.h"
-#include "jni.h"
-#include "jni_util.h"
-#include "jlong.h"
-#include "io_util.h"
-#include "dirent_md.h"
-#include "java_io_FileSystem.h"
-
-/* This macro relies upon the fact that JNU_GetStringPlatformChars always makes
- a copy of the string */
-
-#define WITH_NATIVE_PATH(env, object, id, var) \
- WITH_FIELD_PLATFORM_STRING(env, object, id, var) \
- JVM_NativePath((char *)var);
-
-#define END_NATIVE_PATH(env, var) END_PLATFORM_STRING(env, var)
-
-
-static struct {
- jfieldID path;
-} ids;
-
-JNIEXPORT void JNICALL
-Java_java_io_Win32FileSystem_initIDs(JNIEnv *env, jclass cls)
-{
- jclass fileClass = (*env)->FindClass(env, "java/io/File");
- if (!fileClass) return;
- ids.path = (*env)->GetFieldID(env, fileClass,
- "path", "Ljava/lang/String;");
-}
-
-
-/* -- Path operations -- */
-
-
-extern int canonicalize(char *path, const char *out, int len);
-extern int canonicalizeWithPrefix(const char* canonicalPrefix, const char *pathWithCanonicalPrefix, char *out, int len);
-
-JNIEXPORT jstring JNICALL
-Java_java_io_Win32FileSystem_canonicalize0(JNIEnv *env, jobject this,
- jstring pathname)
-{
- jstring rv = NULL;
-
- WITH_PLATFORM_STRING(env, pathname, path) {
- char canonicalPath[JVM_MAXPATHLEN];
- if (canonicalize(JVM_NativePath((char *)path),
- canonicalPath, JVM_MAXPATHLEN) < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
- } else {
- rv = JNU_NewStringPlatform(env, canonicalPath);
- }
- } END_PLATFORM_STRING(env, path);
- return rv;
-}
-
-
-JNIEXPORT jstring JNICALL
-Java_java_io_Win32FileSystem_canonicalizeWithPrefix0(JNIEnv *env, jobject this,
- jstring canonicalPrefixString,
- jstring pathWithCanonicalPrefixString)
-{
- jstring rv = NULL;
- char canonicalPath[JVM_MAXPATHLEN];
-
- WITH_PLATFORM_STRING(env, canonicalPrefixString, canonicalPrefix) {
- WITH_PLATFORM_STRING(env, pathWithCanonicalPrefixString, pathWithCanonicalPrefix) {
- if (canonicalizeWithPrefix(canonicalPrefix,
- pathWithCanonicalPrefix,
- canonicalPath, JVM_MAXPATHLEN) < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
- } else {
- rv = JNU_NewStringPlatform(env, canonicalPath);
- }
- } END_PLATFORM_STRING(env, pathWithCanonicalPrefix);
- } END_PLATFORM_STRING(env, canonicalPrefix);
- return rv;
-}
-
-
-
-/* -- Attribute accessors -- */
-
-/* Check whether or not the file name in "path" is a Windows reserved
- device name (CON, PRN, AUX, NUL, COM[1-9], LPT[1-9]) based on the
- returned result from GetFullPathName. If the file name in the path
- is indeed a reserved device name GetFuulPathName returns
- "\\.\[ReservedDeviceName]".
- */
-BOOL isReservedDeviceName(const char* path) {
-#define BUFSIZE 9
- char buf[BUFSIZE];
- char *lpf = NULL;
- DWORD retLen = GetFullPathName(path,
- BUFSIZE,
- buf,
- &lpf);
- if ((retLen == BUFSIZE - 1 || retLen == BUFSIZE - 2) &&
- buf[0] == '\\' && buf[1] == '\\' &&
- buf[2] == '.' && buf[3] == '\\') {
- char* dname = _strupr(buf + 4);
- if (strcmp(dname, "CON") == 0 ||
- strcmp(dname, "PRN") == 0 ||
- strcmp(dname, "AUX") == 0 ||
- strcmp(dname, "NUL") == 0)
- return TRUE;
- if ((strncmp(dname, "COM", 3) == 0 ||
- strncmp(dname, "LPT", 3) == 0) &&
- dname[3] - '0' > 0 &&
- dname[3] - '0' <= 9)
- return TRUE;
- }
- return FALSE;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_io_Win32FileSystem_getBooleanAttributes(JNIEnv *env, jobject this,
- jobject file)
-{
- jint rv = 0;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- WIN32_FILE_ATTRIBUTE_DATA wfad;
- if (!isReservedDeviceName(path) &&
- GetFileAttributesEx(path, GetFileExInfoStandard, &wfad)) {
- rv = (java_io_FileSystem_BA_EXISTS
- | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- ? java_io_FileSystem_BA_DIRECTORY
- : java_io_FileSystem_BA_REGULAR)
- | ((wfad.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
- ? java_io_FileSystem_BA_HIDDEN : 0));
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_checkAccess(JNIEnv *env, jobject this,
- jobject file, jint a)
-{
- jboolean rv = JNI_FALSE;
- int mode;
- switch (a) {
- case java_io_FileSystem_ACCESS_READ:
- case java_io_FileSystem_ACCESS_EXECUTE:
- mode = 4;
- break;
- case java_io_FileSystem_ACCESS_WRITE:
- mode = 2;
- break;
- default: assert(0);
- }
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- if (access(path, mode) == 0) {
- rv = JNI_TRUE;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_setPermission(JNIEnv *env, jobject this,
- jobject file,
- jint access,
- jboolean enable,
- jboolean owneronly)
-{
- jboolean rv = JNI_FALSE;
- if (access == java_io_FileSystem_ACCESS_READ ||
- access == java_io_FileSystem_ACCESS_EXECUTE) {
- return enable;
- }
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- DWORD a;
- a = GetFileAttributes(path);
- if (a != INVALID_FILE_ATTRIBUTES) {
- if (enable)
- a = a & ~FILE_ATTRIBUTE_READONLY;
- else
- a = a | FILE_ATTRIBUTE_READONLY;
- if (SetFileAttributes(path, a))
- rv = JNI_TRUE;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_io_Win32FileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
- jobject file)
-{
- jlong rv = 0;
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- /* Win95, Win98, WinME */
- WIN32_FIND_DATA fd;
- jlong temp = 0;
- LARGE_INTEGER modTime;
- HANDLE h = FindFirstFile(path, &fd);
- if (h != INVALID_HANDLE_VALUE) {
- FindClose(h);
- modTime.LowPart = (DWORD) fd.ftLastWriteTime.dwLowDateTime;
- modTime.HighPart = (LONG) fd.ftLastWriteTime.dwHighDateTime;
- rv = modTime.QuadPart / 10000;
- rv -= 11644473600000;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_io_Win32FileSystem_getLength(JNIEnv *env, jobject this,
- jobject file)
-{
- jlong rv = 0;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- struct _stati64 sb;
- if (_stati64(path, &sb) == 0) {
- rv = sb.st_size;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-
-/* -- File operations -- */
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_createFileExclusively(JNIEnv *env, jclass cls,
- jstring pathname)
-{
- jboolean rv = JNI_FALSE;
- DWORD a;
-
- WITH_PLATFORM_STRING(env, pathname, path) {
- int orv;
- int error;
- JVM_NativePath((char *)path);
- orv = JVM_Open(path, JVM_O_RDWR | JVM_O_CREAT | JVM_O_EXCL, 0666);
- if (orv < 0) {
- if (orv != JVM_EEXIST) {
- error = GetLastError();
-
- // If a directory by the named path already exists,
- // return false (behavior of solaris and linux) instead of
- // throwing an exception
- a = GetFileAttributes(path);
-
- if ((a == INVALID_FILE_ATTRIBUTES) ||
- !(a & FILE_ATTRIBUTE_DIRECTORY)) {
- SetLastError(error);
- JNU_ThrowIOExceptionWithLastError(env, path);
- }
- }
- } else {
- JVM_Close(orv);
- rv = JNI_TRUE;
- }
- } END_PLATFORM_STRING(env, path);
- return rv;
-}
-
-
-static int
-removeFileOrDirectory(const char *path) /* Returns 0 on success */
-{
- DWORD a;
-
- SetFileAttributes(path, 0);
- a = GetFileAttributes(path);
- if (a == INVALID_FILE_ATTRIBUTES) {
- return 1;
- } else if (a & FILE_ATTRIBUTE_DIRECTORY) {
- return !RemoveDirectory(path);
- } else {
- return !DeleteFile(path);
- }
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_delete0(JNIEnv *env, jobject this,
- jobject file)
-{
- jboolean rv = JNI_FALSE;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- if (removeFileOrDirectory(path) == 0) {
- rv = JNI_TRUE;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-
-/* ## Clean this up to use direct Win32 calls */
-
-JNIEXPORT jobjectArray JNICALL
-Java_java_io_Win32FileSystem_list(JNIEnv *env, jobject this,
- jobject file)
-{
- DIR *dir;
- struct dirent *ptr;
- int len, maxlen;
- jobjectArray rv, old;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- dir = opendir(path);
- } END_NATIVE_PATH(env, path);
- if (dir == NULL) return NULL;
-
- /* Allocate an initial String array */
- len = 0;
- maxlen = 16;
- rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
- if (rv == NULL) goto error;
-
- /* Scan the directory */
- while ((ptr = readdir(dir)) != NULL) {
- jstring name;
- if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
- continue;
- if (len == maxlen) {
- old = rv;
- rv = (*env)->NewObjectArray(env, maxlen <<= 1,
- JNU_ClassString(env), NULL);
- if (rv == NULL) goto error;
- if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
- (*env)->DeleteLocalRef(env, old);
- }
- name = JNU_NewStringPlatform(env, ptr->d_name);
- if (name == NULL) goto error;
- (*env)->SetObjectArrayElement(env, rv, len++, name);
- (*env)->DeleteLocalRef(env, name);
- }
- closedir(dir);
-
- /* Copy the final results into an appropriately-sized array */
- old = rv;
- rv = (*env)->NewObjectArray(env, len, JNU_ClassString(env), NULL);
- if (rv == NULL) goto error;
- if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
- return rv;
-
- error:
- closedir(dir);
- return NULL;
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_createDirectory(JNIEnv *env, jobject this,
- jobject file)
-{
- jboolean rv = JNI_FALSE;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- if (mkdir(path) == 0) {
- rv = JNI_TRUE;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_rename0(JNIEnv *env, jobject this,
- jobject from, jobject to)
-{
- jboolean rv = JNI_FALSE;
-
- WITH_NATIVE_PATH(env, from, ids.path, fromPath) {
- WITH_NATIVE_PATH(env, to, ids.path, toPath) {
- if (rename(fromPath, toPath) == 0) {
- rv = JNI_TRUE;
- }
- } END_NATIVE_PATH(env, toPath);
- } END_NATIVE_PATH(env, fromPath);
- return rv;
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
- jobject file, jlong time)
-{
- jboolean rv = JNI_FALSE;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- HANDLE h;
- h = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
- if (h != INVALID_HANDLE_VALUE) {
- LARGE_INTEGER modTime;
- FILETIME t;
- modTime.QuadPart = (time + 11644473600000L) * 10000L;
- t.dwLowDateTime = (DWORD)modTime.LowPart;
- t.dwHighDateTime = (DWORD)modTime.HighPart;
- if (SetFileTime(h, NULL, NULL, &t)) {
- rv = JNI_TRUE;
- }
- CloseHandle(h);
- }
- } END_NATIVE_PATH(env, path);
-
- return rv;
-}
-
-
-JNIEXPORT jboolean JNICALL
-Java_java_io_Win32FileSystem_setReadOnly(JNIEnv *env, jobject this,
- jobject file)
-{
- jboolean rv = JNI_FALSE;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- DWORD a;
- a = GetFileAttributes(path);
- if (a != INVALID_FILE_ATTRIBUTES) {
- if (SetFileAttributes(path, a | FILE_ATTRIBUTE_READONLY))
- rv = JNI_TRUE;
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
-
-
-/* -- Filesystem interface -- */
-
-
-JNIEXPORT jobject JNICALL
-Java_java_io_Win32FileSystem_getDriveDirectory(JNIEnv *env, jclass ignored,
- jint drive)
-{
- char buf[_MAX_PATH];
- char *p = _getdcwd(drive, buf, sizeof(buf));
- if (p == NULL) return NULL;
- if (isalpha(*p) && (p[1] == ':')) p += 2;
- return JNU_NewStringPlatform(env, p);
-}
-
-
-JNIEXPORT jint JNICALL
-Java_java_io_Win32FileSystem_listRoots0(JNIEnv *env, jclass ignored)
-{
- return GetLogicalDrives();
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_io_Win32FileSystem_getSpace0(JNIEnv *env, jobject this,
- jobject file, jint t)
-{
- jlong rv = 0L;
-
- WITH_NATIVE_PATH(env, file, ids.path, path) {
- ULARGE_INTEGER totalSpace, freeSpace, usableSpace;
- if (GetDiskFreeSpaceEx(path, &usableSpace, &totalSpace, &freeSpace)) {
- switch(t) {
- case java_io_FileSystem_SPACE_TOTAL:
- rv = long_to_jlong(totalSpace.QuadPart);
- break;
- case java_io_FileSystem_SPACE_FREE:
- rv = long_to_jlong(freeSpace.QuadPart);
- break;
- case java_io_FileSystem_SPACE_USABLE:
- rv = long_to_jlong(usableSpace.QuadPart);
- break;
- default:
- assert(0);
- }
- }
- } END_NATIVE_PATH(env, path);
- return rv;
-}
--- a/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/src/windows/native/java/io/WinNTFileSystem_md.c Thu Oct 11 11:47:05 2012 +0100
@@ -828,6 +828,12 @@
return ret;
}
+JNIEXPORT jint JNICALL
+Java_java_io_WinNTFileSystem_listRoots0(JNIEnv *env, jclass ignored)
+{
+ return GetLogicalDrives();
+}
+
JNIEXPORT jlong JNICALL
Java_java_io_WinNTFileSystem_getSpace0(JNIEnv *env, jobject this,
jobject file, jint t)
--- a/jdk/src/windows/native/java/io/io_util_md.c Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/src/windows/native/java/io/io_util_md.c Thu Oct 11 11:47:05 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -40,22 +40,8 @@
#include <limits.h>
#include <wincon.h>
-extern jboolean onNT = JNI_FALSE;
-
static DWORD MAX_INPUT_EVENTS = 2000;
-void
-initializeWindowsVersion() {
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- onNT = JNI_TRUE;
- } else {
- onNT = JNI_FALSE;
- }
-}
-
/* If this returns NULL then an exception is pending */
WCHAR*
fileToNTPath(JNIEnv *env, jobject file, jfieldID id) {
@@ -247,27 +233,21 @@
const DWORD flagsAndAttributes = maybeWriteThrough | maybeDeleteOnClose;
HANDLE h = NULL;
- if (onNT) {
- WCHAR *pathbuf = pathToNTPath(env, path, JNI_TRUE);
- if (pathbuf == NULL) {
- /* Exception already pending */
- return -1;
- }
- h = CreateFileW(
- pathbuf, /* Wide char path name */
- access, /* Read and/or write permission */
- sharing, /* File sharing flags */
- NULL, /* Security attributes */
- disposition, /* creation disposition */
- flagsAndAttributes, /* flags and attributes */
- NULL);
- free(pathbuf);
- } else {
- WITH_PLATFORM_STRING(env, path, _ps) {
- h = CreateFile(_ps, access, sharing, NULL, disposition,
- flagsAndAttributes, NULL);
- } END_PLATFORM_STRING(env, _ps);
+ WCHAR *pathbuf = pathToNTPath(env, path, JNI_TRUE);
+ if (pathbuf == NULL) {
+ /* Exception already pending */
+ return -1;
}
+ h = CreateFileW(
+ pathbuf, /* Wide char path name */
+ access, /* Read and/or write permission */
+ sharing, /* File sharing flags */
+ NULL, /* Security attributes */
+ disposition, /* creation disposition */
+ flagsAndAttributes, /* flags and attributes */
+ NULL);
+ free(pathbuf);
+
if (h == INVALID_HANDLE_VALUE) {
int error = GetLastError();
if (error == ERROR_TOO_MANY_OPEN_FILES) {
--- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c Thu Oct 11 11:47:05 2012 +0100
@@ -40,72 +40,6 @@
*/
#define PIPE_SIZE (4096+24)
-char *
-extractExecutablePath(JNIEnv *env, char *source)
-{
- char *p, *r;
-
- /* If no spaces, then use entire thing */
- if ((p = strchr(source, ' ')) == NULL)
- return source;
-
- /* If no quotes, or quotes after space, return up to space */
- if (((r = strchr(source, '"')) == NULL) || (r > p)) {
- *p = 0;
- return source;
- }
-
- /* Quotes before space, return up to space after next quotes */
- p = strchr(r, '"');
- if ((p = strchr(p, ' ')) == NULL)
- return source;
- *p = 0;
- return source;
-}
-
-DWORD
-selectProcessFlag(JNIEnv *env, jstring cmd0)
-{
- char buf[MAX_PATH];
- DWORD newFlag = 0;
- char *exe, *p, *name;
- unsigned char buffer[2];
- long headerLoc = 0;
- int fd = 0;
-
- exe = (char *)JNU_GetStringPlatformChars(env, cmd0, 0);
- exe = extractExecutablePath(env, exe);
-
- if (exe != NULL) {
- if ((p = strchr(exe, '\\')) == NULL) {
- SearchPath(NULL, exe, ".exe", MAX_PATH, buf, &name);
- } else {
- p = strrchr(exe, '\\');
- *p = 0;
- p++;
- SearchPath(exe, p, ".exe", MAX_PATH, buf, &name);
- }
- }
-
- fd = _open(buf, _O_RDONLY);
- if (fd > 0) {
- _read(fd, buffer, 2);
- if (buffer[0] == 'M' && buffer[1] == 'Z') {
- _lseek(fd, 60L, SEEK_SET);
- _read(fd, buffer, 2);
- headerLoc = (long)buffer[1] << 8 | (long)buffer[0];
- _lseek(fd, headerLoc, SEEK_SET);
- _read(fd, buffer, 2);
- if (buffer[0] == 'P' && buffer[1] == 'E') {
- newFlag = DETACHED_PROCESS;
- }
- }
- _close(fd);
- }
- JNU_ReleaseStringPlatformChars(env, cmd0, exe);
- return newFlag;
-}
-
static void
win32Error(JNIEnv *env, const char *functionName)
{
@@ -151,15 +85,8 @@
const jchar* penvBlock = NULL;
jlong *handles = NULL;
jlong ret = 0;
- OSVERSIONINFO ver;
- jboolean onNT = JNI_FALSE;
DWORD processFlag;
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
- onNT = JNI_TRUE;
-
assert(cmd != NULL);
pcmd = (*env)->GetStringChars(env, cmd, NULL);
if (pcmd == NULL) goto Catch;
@@ -229,10 +156,7 @@
}
SetHandleInformation(si.hStdError, HANDLE_FLAG_INHERIT, TRUE);
- if (onNT)
- processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
- else
- processFlag = selectProcessFlag(env, cmd) | CREATE_UNICODE_ENVIRONMENT;
+ processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
ret = CreateProcessW(0, /* executable name */
(LPWSTR)pcmd, /* command line */
0, /* process security attribute */
--- a/jdk/src/windows/native/java/util/TimeZone_md.c Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/src/windows/native/java/util/TimeZone_md.c Thu Oct 11 11:47:05 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -65,8 +65,6 @@
#define STANDARD_NAME 0
#define STD_NAME 2
-static int isNT = FALSE; /* TRUE if it is NT. */
-
/*
* Calls RegQueryValueEx() to get the value for the specified key. If
* the platform is NT, 2000 or XP, it calls the Unicode
@@ -95,12 +93,10 @@
int len;
*typePtr = 0;
- if (isNT) {
- ret = RegQueryValueExW(hKey, (WCHAR *) keyNames[keyIndex], NULL,
- typePtr, buf, bufLengthPtr);
- if (ret == ERROR_SUCCESS && *typePtr == REG_SZ) {
- return ret;
- }
+ ret = RegQueryValueExW(hKey, (WCHAR *) keyNames[keyIndex], NULL,
+ typePtr, buf, bufLengthPtr);
+ if (ret == ERROR_SUCCESS && *typePtr == REG_SZ) {
+ return ret;
}
valSize = sizeof(val);
@@ -180,8 +176,7 @@
*/
ver.dwOSVersionInfoSize = sizeof(ver);
GetVersionEx(&ver);
- isNT = ver.dwPlatformId == VER_PLATFORM_WIN32_NT;
- isVista = isNT && ver.dwMajorVersion >= 6;
+ isVista = ver.dwMajorVersion >= 6;
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
KEY_READ, (PHKEY)&hKey);
--- a/jdk/test/java/io/pathNames/win32/bug6344646.java Wed Oct 10 17:34:27 2012 -0400
+++ b/jdk/test/java/io/pathNames/win32/bug6344646.java Thu Oct 11 11:47:05 2012 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -23,7 +23,7 @@
/* @test
* @bug 6344646
- * @summary tests that Win32FileSystem.hashCode() uses
+ * @summary tests that WinNTFileSystem.hashCode() uses
* locale independent case mapping.
*/