Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/java/io/UnixFileSystem.java
32287 views
1
/*
2
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.io;
27
28
import java.security.AccessController;
29
import sun.security.action.GetPropertyAction;
30
31
32
class UnixFileSystem extends FileSystem {
33
34
private final char slash;
35
private final char colon;
36
private final String javaHome;
37
38
public UnixFileSystem() {
39
slash = AccessController.doPrivileged(
40
new GetPropertyAction("file.separator")).charAt(0);
41
colon = AccessController.doPrivileged(
42
new GetPropertyAction("path.separator")).charAt(0);
43
javaHome = AccessController.doPrivileged(
44
new GetPropertyAction("java.home"));
45
}
46
47
48
/* -- Normalization and construction -- */
49
50
public char getSeparator() {
51
return slash;
52
}
53
54
public char getPathSeparator() {
55
return colon;
56
}
57
58
/* A normal Unix pathname contains no duplicate slashes and does not end
59
with a slash. It may be the empty string. */
60
61
/* Normalize the given pathname, whose length is len, starting at the given
62
offset; everything before this offset is already normal. */
63
private String normalize(String pathname, int len, int off) {
64
if (len == 0) return pathname;
65
int n = len;
66
while ((n > 0) && (pathname.charAt(n - 1) == '/')) n--;
67
if (n == 0) return "/";
68
StringBuffer sb = new StringBuffer(pathname.length());
69
if (off > 0) sb.append(pathname.substring(0, off));
70
char prevChar = 0;
71
for (int i = off; i < n; i++) {
72
char c = pathname.charAt(i);
73
if ((prevChar == '/') && (c == '/')) continue;
74
sb.append(c);
75
prevChar = c;
76
}
77
return sb.toString();
78
}
79
80
/* Check that the given pathname is normal. If not, invoke the real
81
normalizer on the part of the pathname that requires normalization.
82
This way we iterate through the whole pathname string only once. */
83
public String normalize(String pathname) {
84
int n = pathname.length();
85
char prevChar = 0;
86
for (int i = 0; i < n; i++) {
87
char c = pathname.charAt(i);
88
if ((prevChar == '/') && (c == '/'))
89
return normalize(pathname, n, i - 1);
90
prevChar = c;
91
}
92
if (prevChar == '/') return normalize(pathname, n, n - 1);
93
return pathname;
94
}
95
96
public int prefixLength(String pathname) {
97
if (pathname.length() == 0) return 0;
98
return (pathname.charAt(0) == '/') ? 1 : 0;
99
}
100
101
public String resolve(String parent, String child) {
102
if (child.equals("")) return parent;
103
if (child.charAt(0) == '/') {
104
if (parent.equals("/")) return child;
105
return parent + child;
106
}
107
if (parent.equals("/")) return parent + child;
108
return parent + '/' + child;
109
}
110
111
public String getDefaultParent() {
112
return "/";
113
}
114
115
public String fromURIPath(String path) {
116
String p = path;
117
if (p.endsWith("/") && (p.length() > 1)) {
118
// "/foo/" --> "/foo", but "/" --> "/"
119
p = p.substring(0, p.length() - 1);
120
}
121
return p;
122
}
123
124
125
/* -- Path operations -- */
126
127
public boolean isAbsolute(File f) {
128
return (f.getPrefixLength() != 0);
129
}
130
131
public String resolve(File f) {
132
if (isAbsolute(f)) return f.getPath();
133
return resolve(System.getProperty("user.dir"), f.getPath());
134
}
135
136
// Caches for canonicalization results to improve startup performance.
137
// The first cache handles repeated canonicalizations of the same path
138
// name. The prefix cache handles repeated canonicalizations within the
139
// same directory, and must not create results differing from the true
140
// canonicalization algorithm in canonicalize_md.c. For this reason the
141
// prefix cache is conservative and is not used for complex path names.
142
private ExpiringCache cache = new ExpiringCache();
143
// On Unix symlinks can jump anywhere in the file system, so we only
144
// treat prefixes in java.home as trusted and cacheable in the
145
// canonicalization algorithm
146
private ExpiringCache javaHomePrefixCache = new ExpiringCache();
147
148
public String canonicalize(String path) throws IOException {
149
if (!useCanonCaches) {
150
return canonicalize0(path);
151
} else {
152
String res = cache.get(path);
153
if (res == null) {
154
String dir = null;
155
String resDir = null;
156
if (useCanonPrefixCache) {
157
// Note that this can cause symlinks that should
158
// be resolved to a destination directory to be
159
// resolved to the directory they're contained in
160
dir = parentOrNull(path);
161
if (dir != null) {
162
resDir = javaHomePrefixCache.get(dir);
163
if (resDir != null) {
164
// Hit only in prefix cache; full path is canonical
165
String filename = path.substring(1 + dir.length());
166
res = resDir + slash + filename;
167
cache.put(dir + slash + filename, res);
168
}
169
}
170
}
171
if (res == null) {
172
res = canonicalize0(path);
173
cache.put(path, res);
174
if (useCanonPrefixCache &&
175
dir != null && dir.startsWith(javaHome)) {
176
resDir = parentOrNull(res);
177
// Note that we don't allow a resolved symlink
178
// to elsewhere in java.home to pollute the
179
// prefix cache (java.home prefix cache could
180
// just as easily be a set at this point)
181
if (resDir != null && resDir.equals(dir)) {
182
File f = new File(res);
183
if (f.exists() && !f.isDirectory()) {
184
javaHomePrefixCache.put(dir, resDir);
185
}
186
}
187
}
188
}
189
}
190
return res;
191
}
192
}
193
private native String canonicalize0(String path) throws IOException;
194
// Best-effort attempt to get parent of this path; used for
195
// optimization of filename canonicalization. This must return null for
196
// any cases where the code in canonicalize_md.c would throw an
197
// exception or otherwise deal with non-simple pathnames like handling
198
// of "." and "..". It may conservatively return null in other
199
// situations as well. Returning null will cause the underlying
200
// (expensive) canonicalization routine to be called.
201
static String parentOrNull(String path) {
202
if (path == null) return null;
203
char sep = File.separatorChar;
204
int last = path.length() - 1;
205
int idx = last;
206
int adjacentDots = 0;
207
int nonDotCount = 0;
208
while (idx > 0) {
209
char c = path.charAt(idx);
210
if (c == '.') {
211
if (++adjacentDots >= 2) {
212
// Punt on pathnames containing . and ..
213
return null;
214
}
215
} else if (c == sep) {
216
if (adjacentDots == 1 && nonDotCount == 0) {
217
// Punt on pathnames containing . and ..
218
return null;
219
}
220
if (idx == 0 ||
221
idx >= last - 1 ||
222
path.charAt(idx - 1) == sep) {
223
// Punt on pathnames containing adjacent slashes
224
// toward the end
225
return null;
226
}
227
return path.substring(0, idx);
228
} else {
229
++nonDotCount;
230
adjacentDots = 0;
231
}
232
--idx;
233
}
234
return null;
235
}
236
237
/* -- Attribute accessors -- */
238
239
public native int getBooleanAttributes0(File f);
240
241
public int getBooleanAttributes(File f) {
242
int rv = getBooleanAttributes0(f);
243
String name = f.getName();
244
boolean hidden = (name.length() > 0) && (name.charAt(0) == '.');
245
return rv | (hidden ? BA_HIDDEN : 0);
246
}
247
248
public native boolean checkAccess(File f, int access);
249
public native long getLastModifiedTime(File f);
250
public native long getLength(File f);
251
public native boolean setPermission(File f, int access, boolean enable, boolean owneronly);
252
253
/* -- File operations -- */
254
255
public native boolean createFileExclusively(String path)
256
throws IOException;
257
public boolean delete(File f) {
258
// Keep canonicalization caches in sync after file deletion
259
// and renaming operations. Could be more clever than this
260
// (i.e., only remove/update affected entries) but probably
261
// not worth it since these entries expire after 30 seconds
262
// anyway.
263
cache.clear();
264
javaHomePrefixCache.clear();
265
return delete0(f);
266
}
267
private native boolean delete0(File f);
268
public native String[] list(File f);
269
public native boolean createDirectory(File f);
270
public boolean rename(File f1, File f2) {
271
// Keep canonicalization caches in sync after file deletion
272
// and renaming operations. Could be more clever than this
273
// (i.e., only remove/update affected entries) but probably
274
// not worth it since these entries expire after 30 seconds
275
// anyway.
276
cache.clear();
277
javaHomePrefixCache.clear();
278
return rename0(f1, f2);
279
}
280
private native boolean rename0(File f1, File f2);
281
public native boolean setLastModifiedTime(File f, long time);
282
public native boolean setReadOnly(File f);
283
284
285
/* -- Filesystem interface -- */
286
287
public File[] listRoots() {
288
try {
289
SecurityManager security = System.getSecurityManager();
290
if (security != null) {
291
security.checkRead("/");
292
}
293
return new File[] { new File("/") };
294
} catch (SecurityException x) {
295
return new File[0];
296
}
297
}
298
299
/* -- Disk usage -- */
300
public native long getSpace(File f, int t);
301
302
/* -- Basic infrastructure -- */
303
304
public int compare(File f1, File f2) {
305
return f1.getPath().compareTo(f2.getPath());
306
}
307
308
public int hashCode(File f) {
309
return f.getPath().hashCode() ^ 1234321;
310
}
311
312
313
private static native void initIDs();
314
315
static {
316
initIDs();
317
}
318
319
}
320
321