Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java
32288 views
1
/*
2
* Copyright (c) 2008, 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 sun.nio.fs;
27
28
import java.io.FileDescriptor;
29
import java.io.IOException;
30
import java.nio.channels.AsynchronousFileChannel;
31
import java.nio.channels.FileChannel;
32
import java.nio.file.LinkOption;
33
import java.nio.file.OpenOption;
34
import java.nio.file.StandardOpenOption;
35
import java.util.Set;
36
37
import com.sun.nio.file.ExtendedOpenOption;
38
39
import sun.misc.JavaIOFileDescriptorAccess;
40
import sun.misc.SharedSecrets;
41
import sun.nio.ch.FileChannelImpl;
42
import sun.nio.ch.ThreadPool;
43
import sun.nio.ch.WindowsAsynchronousFileChannelImpl;
44
45
import static sun.nio.fs.WindowsNativeDispatcher.*;
46
import static sun.nio.fs.WindowsConstants.*;
47
48
/**
49
* Factory to create FileChannels and AsynchronousFileChannels.
50
*/
51
52
class WindowsChannelFactory {
53
private static final JavaIOFileDescriptorAccess fdAccess =
54
SharedSecrets.getJavaIOFileDescriptorAccess();
55
56
private WindowsChannelFactory() { }
57
58
/**
59
* Do not follow reparse points when opening an existing file. Do not fail
60
* if the file is a reparse point.
61
*/
62
static final OpenOption OPEN_REPARSE_POINT = new OpenOption() { };
63
64
/**
65
* Represents the flags from a user-supplied set of open options.
66
*/
67
private static class Flags {
68
boolean read;
69
boolean write;
70
boolean append;
71
boolean truncateExisting;
72
boolean create;
73
boolean createNew;
74
boolean deleteOnClose;
75
boolean sparse;
76
boolean overlapped;
77
boolean sync;
78
boolean dsync;
79
80
// non-standard
81
boolean shareRead = true;
82
boolean shareWrite = true;
83
boolean shareDelete = true;
84
boolean noFollowLinks;
85
boolean openReparsePoint;
86
87
static Flags toFlags(Set<? extends OpenOption> options) {
88
Flags flags = new Flags();
89
for (OpenOption option: options) {
90
if (option instanceof StandardOpenOption) {
91
switch ((StandardOpenOption)option) {
92
case READ : flags.read = true; break;
93
case WRITE : flags.write = true; break;
94
case APPEND : flags.append = true; break;
95
case TRUNCATE_EXISTING : flags.truncateExisting = true; break;
96
case CREATE : flags.create = true; break;
97
case CREATE_NEW : flags.createNew = true; break;
98
case DELETE_ON_CLOSE : flags.deleteOnClose = true; break;
99
case SPARSE : flags.sparse = true; break;
100
case SYNC : flags.sync = true; break;
101
case DSYNC : flags.dsync = true; break;
102
default: throw new UnsupportedOperationException();
103
}
104
continue;
105
}
106
if (option instanceof ExtendedOpenOption) {
107
switch ((ExtendedOpenOption)option) {
108
case NOSHARE_READ : flags.shareRead = false; break;
109
case NOSHARE_WRITE : flags.shareWrite = false; break;
110
case NOSHARE_DELETE : flags.shareDelete = false; break;
111
default: throw new UnsupportedOperationException();
112
}
113
continue;
114
}
115
if (option == LinkOption.NOFOLLOW_LINKS) {
116
flags.noFollowLinks = true;
117
continue;
118
}
119
if (option == OPEN_REPARSE_POINT) {
120
flags.openReparsePoint = true;
121
continue;
122
}
123
if (option == null)
124
throw new NullPointerException();
125
throw new UnsupportedOperationException();
126
}
127
return flags;
128
}
129
}
130
131
/**
132
* Open/creates file, returning FileChannel to access the file
133
*
134
* @param pathForWindows
135
* The path of the file to open/create
136
* @param pathToCheck
137
* The path used for permission checks (if security manager)
138
*/
139
static FileChannel newFileChannel(String pathForWindows,
140
String pathToCheck,
141
Set<? extends OpenOption> options,
142
long pSecurityDescriptor)
143
throws WindowsException
144
{
145
Flags flags = Flags.toFlags(options);
146
147
// default is reading; append => writing
148
if (!flags.read && !flags.write) {
149
if (flags.append) {
150
flags.write = true;
151
} else {
152
flags.read = true;
153
}
154
}
155
156
// validation
157
if (flags.read && flags.append)
158
throw new IllegalArgumentException("READ + APPEND not allowed");
159
if (flags.append && flags.truncateExisting)
160
throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
161
162
FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
163
return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, flags.append, null);
164
}
165
166
/**
167
* Open/creates file, returning AsynchronousFileChannel to access the file
168
*
169
* @param pathForWindows
170
* The path of the file to open/create
171
* @param pathToCheck
172
* The path used for permission checks (if security manager)
173
* @param pool
174
* The thread pool that the channel is associated with
175
*/
176
static AsynchronousFileChannel newAsynchronousFileChannel(String pathForWindows,
177
String pathToCheck,
178
Set<? extends OpenOption> options,
179
long pSecurityDescriptor,
180
ThreadPool pool)
181
throws IOException
182
{
183
Flags flags = Flags.toFlags(options);
184
185
// Overlapped I/O required
186
flags.overlapped = true;
187
188
// default is reading
189
if (!flags.read && !flags.write) {
190
flags.read = true;
191
}
192
193
// validation
194
if (flags.append)
195
throw new UnsupportedOperationException("APPEND not allowed");
196
197
// open file for overlapped I/O
198
FileDescriptor fdObj;
199
try {
200
fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
201
} catch (WindowsException x) {
202
x.rethrowAsIOException(pathForWindows);
203
return null;
204
}
205
206
// create the AsynchronousFileChannel
207
try {
208
return WindowsAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool);
209
} catch (IOException x) {
210
// IOException is thrown if the file handle cannot be associated
211
// with the completion port. All we can do is close the file.
212
long handle = fdAccess.getHandle(fdObj);
213
CloseHandle(handle);
214
throw x;
215
}
216
}
217
218
/**
219
* Opens file based on parameters and options, returning a FileDescriptor
220
* encapsulating the handle to the open file.
221
*/
222
private static FileDescriptor open(String pathForWindows,
223
String pathToCheck,
224
Flags flags,
225
long pSecurityDescriptor)
226
throws WindowsException
227
{
228
// set to true if file must be truncated after open
229
boolean truncateAfterOpen = false;
230
231
// map options
232
int dwDesiredAccess = 0;
233
if (flags.read)
234
dwDesiredAccess |= GENERIC_READ;
235
if (flags.write)
236
dwDesiredAccess |= GENERIC_WRITE;
237
238
int dwShareMode = 0;
239
if (flags.shareRead)
240
dwShareMode |= FILE_SHARE_READ;
241
if (flags.shareWrite)
242
dwShareMode |= FILE_SHARE_WRITE;
243
if (flags.shareDelete)
244
dwShareMode |= FILE_SHARE_DELETE;
245
246
int dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
247
int dwCreationDisposition = OPEN_EXISTING;
248
if (flags.write) {
249
if (flags.createNew) {
250
dwCreationDisposition = CREATE_NEW;
251
// force create to fail if file is orphaned reparse point
252
dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT;
253
} else {
254
if (flags.create)
255
dwCreationDisposition = OPEN_ALWAYS;
256
if (flags.truncateExisting) {
257
// Windows doesn't have a creation disposition that exactly
258
// corresponds to CREATE + TRUNCATE_EXISTING so we use
259
// the OPEN_ALWAYS mode and then truncate the file.
260
if (dwCreationDisposition == OPEN_ALWAYS) {
261
truncateAfterOpen = true;
262
} else {
263
dwCreationDisposition = TRUNCATE_EXISTING;
264
}
265
}
266
}
267
}
268
269
if (flags.dsync || flags.sync)
270
dwFlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
271
if (flags.overlapped)
272
dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
273
if (flags.deleteOnClose)
274
dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
275
276
// NOFOLLOW_LINKS and NOFOLLOW_REPARSEPOINT mean open reparse point
277
boolean okayToFollowLinks = true;
278
if (dwCreationDisposition != CREATE_NEW &&
279
(flags.noFollowLinks ||
280
flags.openReparsePoint ||
281
flags.deleteOnClose))
282
{
283
if (flags.noFollowLinks || flags.deleteOnClose)
284
okayToFollowLinks = false;
285
dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT;
286
}
287
288
// permission check
289
if (pathToCheck != null) {
290
SecurityManager sm = System.getSecurityManager();
291
if (sm != null) {
292
if (flags.read)
293
sm.checkRead(pathToCheck);
294
if (flags.write)
295
sm.checkWrite(pathToCheck);
296
if (flags.deleteOnClose)
297
sm.checkDelete(pathToCheck);
298
}
299
}
300
301
// open file
302
long handle = CreateFile(pathForWindows,
303
dwDesiredAccess,
304
dwShareMode,
305
pSecurityDescriptor,
306
dwCreationDisposition,
307
dwFlagsAndAttributes);
308
309
// make sure this isn't a symbolic link.
310
if (!okayToFollowLinks) {
311
try {
312
if (WindowsFileAttributes.readAttributes(handle).isSymbolicLink())
313
throw new WindowsException("File is symbolic link");
314
} catch (WindowsException x) {
315
CloseHandle(handle);
316
throw x;
317
}
318
}
319
320
// truncate file (for CREATE + TRUNCATE_EXISTING case)
321
if (truncateAfterOpen) {
322
try {
323
SetEndOfFile(handle);
324
} catch (WindowsException x) {
325
CloseHandle(handle);
326
throw x;
327
}
328
}
329
330
// make the file sparse if needed
331
if (dwCreationDisposition == CREATE_NEW && flags.sparse) {
332
try {
333
DeviceIoControlSetSparse(handle);
334
} catch (WindowsException x) {
335
// ignore as sparse option is hint
336
}
337
}
338
339
// create FileDescriptor and return
340
FileDescriptor fdObj = new FileDescriptor();
341
fdAccess.setHandle(fdObj, handle);
342
return fdObj;
343
}
344
}
345
346