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.nio.file.*;
29 import java.nio.file.attribute.*;
30 import java.nio.file.spi.FileSystemProvider;
31 import java.nio.channels.*;
32 import java.net.URI;
33 import java.util.concurrent.ExecutorService;
34 import java.io.IOException;
35 import java.util.*;
36
37 import sun.nio.ch.ThreadPool;
38
39 /**
40 * Base implementation of FileSystemProvider
41 */
42
43 public abstract class UnixFileSystemProvider
44 extends FileSystemProvider
45 {
46 private static final String USER_DIR = "user.dir";
47 private final UnixFileSystem theFileSystem;
48
49 public UnixFileSystemProvider() {
50 String userDir = System.getProperty(USER_DIR);
51 theFileSystem = newFileSystem(userDir);
52 }
53
54 /**
55 * Constructs a new file system using the given default directory.
56 */
57 abstract UnixFileSystem newFileSystem(String dir);
58
59 @Override
60 public final String getScheme() {
61 return "file";
62 }
63
64 private void checkUri(URI uri) {
76 throw new IllegalArgumentException("Fragment component present");
77 }
78
79 @Override
80 public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
81 checkUri(uri);
82 throw new FileSystemAlreadyExistsException();
83 }
84
85 @Override
86 public final FileSystem getFileSystem(URI uri) {
87 checkUri(uri);
88 return theFileSystem;
89 }
90
91 @Override
92 public Path getPath(URI uri) {
93 return UnixUriUtils.fromUri(theFileSystem, uri);
94 }
95
96 protected UnixPath checkPath(Path obj) {
97 if (obj == null)
98 throw new NullPointerException();
99 if (!(obj instanceof UnixPath))
100 throw new ProviderMismatchException();
101 return (UnixPath)obj;
102 }
103
104 @Override
105 public FileChannel newFileChannel(Path obj,
106 Set<? extends OpenOption> options,
107 FileAttribute<?>... attrs)
108 throws IOException
109 {
110 UnixPath file = checkPath(obj);
111 int mode = UnixFileModeAttribute
112 .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
113 try {
114 return UnixChannelFactory.newFileChannel(file, options, mode);
115 } catch (UnixException x) {
116 x.rethrowAsIOException(file);
117 return null;
118 }
119 }
120
121 @Override
122 public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
123 Set<? extends OpenOption> options,
124 ExecutorService executor,
125 FileAttribute<?>... attrs) throws IOException
126 {
127 UnixPath file = checkPath(obj);
128 int mode = UnixFileModeAttribute
129 .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
130 ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
131 try {
132 return UnixChannelFactory
133 .newAsynchronousFileChannel(file, options, mode, pool);
134 } catch (UnixException x) {
135 x.rethrowAsIOException(file);
136 return null;
137 }
138 }
139 }
|
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.nio.file.*;
29 import java.nio.file.attribute.*;
30 import java.nio.channels.*;
31 import java.net.URI;
32 import java.util.concurrent.ExecutorService;
33 import java.io.IOException;
34 import java.io.FilePermission;
35 import java.util.*;
36 import java.security.AccessController;
37
38 import sun.nio.ch.ThreadPool;
39 import sun.security.util.SecurityConstants;
40 import static sun.nio.fs.UnixNativeDispatcher.*;
41 import static sun.nio.fs.UnixConstants.*;
42
43 /**
44 * Base implementation of FileSystemProvider
45 */
46
47 public abstract class UnixFileSystemProvider
48 extends AbstractFileSystemProvider
49 {
50 private static final String USER_DIR = "user.dir";
51 private final UnixFileSystem theFileSystem;
52
53 public UnixFileSystemProvider() {
54 String userDir = System.getProperty(USER_DIR);
55 theFileSystem = newFileSystem(userDir);
56 }
57
58 /**
59 * Constructs a new file system using the given default directory.
60 */
61 abstract UnixFileSystem newFileSystem(String dir);
62
63 @Override
64 public final String getScheme() {
65 return "file";
66 }
67
68 private void checkUri(URI uri) {
80 throw new IllegalArgumentException("Fragment component present");
81 }
82
83 @Override
84 public final FileSystem newFileSystem(URI uri, Map<String,?> env) {
85 checkUri(uri);
86 throw new FileSystemAlreadyExistsException();
87 }
88
89 @Override
90 public final FileSystem getFileSystem(URI uri) {
91 checkUri(uri);
92 return theFileSystem;
93 }
94
95 @Override
96 public Path getPath(URI uri) {
97 return UnixUriUtils.fromUri(theFileSystem, uri);
98 }
99
100 UnixPath checkPath(Path obj) {
101 if (obj == null)
102 throw new NullPointerException();
103 if (!(obj instanceof UnixPath))
104 throw new ProviderMismatchException();
105 return (UnixPath)obj;
106 }
107
108 boolean followLinks(LinkOption... options) {
109 boolean followLinks = true;
110 for (LinkOption option: options) {
111 if (option == LinkOption.NOFOLLOW_LINKS) {
112 followLinks = false;
113 continue;
114 }
115 if (option == null)
116 throw new NullPointerException();
117 throw new AssertionError("Should not get here");
118 }
119 return followLinks;
120 }
121
122 @Override
123 @SuppressWarnings("unchecked")
124 public <V extends FileAttributeView> V getFileAttributeView(Path obj,
125 Class<V> type,
126 LinkOption... options)
127 {
128 UnixPath file = UnixPath.toUnixPath(obj);
129 boolean followLinks = followLinks(options);
130 if (type == BasicFileAttributeView.class)
131 return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
132 if (type == PosixFileAttributeView.class)
133 return (V) UnixFileAttributeViews.createPosixView(file, followLinks);
134 if (type == FileOwnerAttributeView.class)
135 return (V) UnixFileAttributeViews.createOwnerView(file, followLinks);
136 if (type == null)
137 throw new NullPointerException();
138 return (V) null;
139 }
140
141 @Override
142 @SuppressWarnings("unchecked")
143 public <A extends BasicFileAttributes> A readAttributes(Path file,
144 Class<A> type,
145 LinkOption... options)
146 throws IOException
147 {
148 Class<? extends BasicFileAttributeView> view;
149 if (type == BasicFileAttributes.class)
150 view = BasicFileAttributeView.class;
151 else if (type == PosixFileAttributes.class)
152 view = PosixFileAttributeView.class;
153 else if (type == null)
154 throw new NullPointerException();
155 else
156 throw new UnsupportedOperationException();
157 return (A) getFileAttributeView(file, view, options).readAttributes();
158 }
159
160 @Override
161 protected DynamicFileAttributeView getFileAttributeView(Path obj,
162 String name,
163 LinkOption... options)
164 {
165 UnixPath file = UnixPath.toUnixPath(obj);
166 boolean followLinks = followLinks(options);
167 if (name.equals("basic"))
168 return UnixFileAttributeViews.createBasicView(file, followLinks);
169 if (name.equals("posix"))
170 return UnixFileAttributeViews.createPosixView(file, followLinks);
171 if (name.equals("unix"))
172 return UnixFileAttributeViews.createUnixView(file, followLinks);
173 if (name.equals("owner"))
174 return UnixFileAttributeViews.createOwnerView(file, followLinks);
175 return null;
176 }
177
178 @Override
179 public FileChannel newFileChannel(Path obj,
180 Set<? extends OpenOption> options,
181 FileAttribute<?>... attrs)
182 throws IOException
183 {
184 UnixPath file = checkPath(obj);
185 int mode = UnixFileModeAttribute
186 .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
187 try {
188 return UnixChannelFactory.newFileChannel(file, options, mode);
189 } catch (UnixException x) {
190 x.rethrowAsIOException(file);
191 return null;
192 }
193 }
194
195 @Override
196 public AsynchronousFileChannel newAsynchronousFileChannel(Path obj,
197 Set<? extends OpenOption> options,
198 ExecutorService executor,
199 FileAttribute<?>... attrs) throws IOException
200 {
201 UnixPath file = checkPath(obj);
202 int mode = UnixFileModeAttribute
203 .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
204 ThreadPool pool = (executor == null) ? null : ThreadPool.wrap(executor, 0);
205 try {
206 return UnixChannelFactory
207 .newAsynchronousFileChannel(file, options, mode, pool);
208 } catch (UnixException x) {
209 x.rethrowAsIOException(file);
210 return null;
211 }
212 }
213
214
215 @Override
216 public SeekableByteChannel newByteChannel(Path obj,
217 Set<? extends OpenOption> options,
218 FileAttribute<?>... attrs)
219 throws IOException
220 {
221 UnixPath file = UnixPath.toUnixPath(obj);
222 int mode = UnixFileModeAttribute
223 .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs);
224 try {
225 return UnixChannelFactory.newFileChannel(file, options, mode);
226 } catch (UnixException x) {
227 x.rethrowAsIOException(file);
228 return null; // keep compiler happy
229 }
230 }
231
232 @Override
233 boolean implDelete(Path obj, boolean failIfNotExists) throws IOException {
234 UnixPath file = UnixPath.toUnixPath(obj);
235 file.checkDelete();
236
237 // need file attributes to know if file is directory
238 UnixFileAttributes attrs = null;
239 try {
240 attrs = UnixFileAttributes.get(file, false);
241 if (attrs.isDirectory()) {
242 rmdir(file);
243 } else {
244 unlink(file);
245 }
246 return true;
247 } catch (UnixException x) {
248 // no-op if file does not exist
249 if (!failIfNotExists && x.errno() == ENOENT)
250 return false;
251
252 // DirectoryNotEmptyException if not empty
253 if (attrs != null && attrs.isDirectory() &&
254 (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
255 throw new DirectoryNotEmptyException(file.getPathForExecptionMessage());
256
257 x.rethrowAsIOException(file);
258 return false;
259 }
260 }
261
262 @Override
263 public void copy(Path source, Path target, CopyOption... options)
264 throws IOException
265 {
266 UnixCopyFile.copy(UnixPath.toUnixPath(source),
267 UnixPath.toUnixPath(target),
268 options);
269 }
270
271 @Override
272 public void move(Path source, Path target, CopyOption... options)
273 throws IOException
274 {
275 UnixCopyFile.move(UnixPath.toUnixPath(source),
276 UnixPath.toUnixPath(target),
277 options);
278 }
279
280 @Override
281 public void checkAccess(Path obj, AccessMode... modes) throws IOException {
282 UnixPath file = UnixPath.toUnixPath(obj);
283 boolean e = false;
284 boolean r = false;
285 boolean w = false;
286 boolean x = false;
287
288 if (modes.length == 0) {
289 e = true;
290 } else {
291 for (AccessMode mode: modes) {
292 switch (mode) {
293 case READ : r = true; break;
294 case WRITE : w = true; break;
295 case EXECUTE : x = true; break;
296 default: throw new AssertionError("Should not get here");
297 }
298 }
299 }
300
301 int mode = 0;
302 if (e || r) {
303 file.checkRead();
304 mode |= (r) ? R_OK : F_OK;
305 }
306 if (w) {
307 file.checkWrite();
308 mode |= W_OK;
309 }
310 if (x) {
311 SecurityManager sm = System.getSecurityManager();
312 if (sm != null) {
313 // not cached
314 sm.checkExec(file.getPathForPermissionCheck());
315 }
316 mode |= X_OK;
317 }
318 try {
319 access(file, mode);
320 } catch (UnixException exc) {
321 exc.rethrowAsIOException(file);
322 }
323 }
324
325 @Override
326 public boolean isSameFile(Path obj1, Path obj2) throws IOException {
327 UnixPath file1 = UnixPath.toUnixPath(obj1);
328 if (file1.equals(obj2))
329 return true;
330 if (obj2 == null)
331 throw new NullPointerException();
332 if (!(obj2 instanceof UnixPath))
333 return false;
334 UnixPath file2 = (UnixPath)obj2;
335
336 // check security manager access to both files
337 file1.checkRead();
338 file2.checkRead();
339
340 UnixFileAttributes attrs1;
341 UnixFileAttributes attrs2;
342 try {
343 attrs1 = UnixFileAttributes.get(file1, true);
344 } catch (UnixException x) {
345 x.rethrowAsIOException(file1);
346 return false; // keep compiler happy
347 }
348 try {
349 attrs2 = UnixFileAttributes.get(file2, true);
350 } catch (UnixException x) {
351 x.rethrowAsIOException(file2);
352 return false; // keep compiler happy
353 }
354 return attrs1.isSameFile(attrs2);
355 }
356
357 @Override
358 public boolean isHidden(Path obj) {
359 UnixPath file = UnixPath.toUnixPath(obj);
360 file.checkRead();
361 UnixPath name = file.getFileName();
362 if (name == null)
363 return false;
364 return (name.asByteArray()[0] == '.');
365 }
366
367 /**
368 * Returns a FileStore to represent the file system where the given file
369 * reside.
370 */
371 abstract FileStore getFileStore(UnixPath path) throws IOException;
372
373 @Override
374 public FileStore getFileStore(Path obj) throws IOException {
375 UnixPath file = UnixPath.toUnixPath(obj);
376 SecurityManager sm = System.getSecurityManager();
377 if (sm != null) {
378 sm.checkPermission(new RuntimePermission("getFileStoreAttributes"));
379 file.checkRead();
380 }
381 return getFileStore(file);
382 }
383
384 @Override
385 public void createDirectory(Path obj, FileAttribute<?>... attrs)
386 throws IOException
387 {
388 UnixPath dir = UnixPath.toUnixPath(obj);
389 dir.checkWrite();
390
391 int mode = UnixFileModeAttribute
392 .toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs);
393 try {
394 mkdir(dir, mode);
395 } catch (UnixException x) {
396 x.rethrowAsIOException(dir);
397 }
398 }
399
400
401 @Override
402 public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter<? super Path> filter)
403 throws IOException
404 {
405 UnixPath dir = UnixPath.toUnixPath(obj);
406 dir.checkRead();
407 if (filter == null)
408 throw new NullPointerException();
409
410 // can't return SecureDirectoryStream on kernels that don't support
411 // openat, etc.
412 if (!supportsAtSysCalls()) {
413 try {
414 long ptr = opendir(dir);
415 return new UnixDirectoryStream(dir, ptr, filter);
416 } catch (UnixException x) {
417 if (x.errno() == ENOTDIR)
418 throw new NotDirectoryException(dir.getPathForExecptionMessage());
419 x.rethrowAsIOException(dir);
420 }
421 }
422
423 // open directory and dup file descriptor for use by
424 // opendir/readdir/closedir
425 int dfd1 = -1;
426 int dfd2 = -1;
427 long dp = 0L;
428 try {
429 dfd1 = open(dir, O_RDONLY, 0);
430 dfd2 = dup(dfd1);
431 dp = fdopendir(dfd1);
432 } catch (UnixException x) {
433 if (dfd1 != -1)
434 UnixNativeDispatcher.close(dfd1);
435 if (dfd2 != -1)
436 UnixNativeDispatcher.close(dfd2);
437 if (x.errno() == UnixConstants.ENOTDIR)
438 throw new NotDirectoryException(dir.getPathForExecptionMessage());
439 x.rethrowAsIOException(dir);
440 }
441 return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
442 }
443
444 @Override
445 public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs)
446 throws IOException
447 {
448 UnixPath link = UnixPath.toUnixPath(obj1);
449 UnixPath target = UnixPath.toUnixPath(obj2);
450
451 // no attributes supported when creating links
452 if (attrs.length > 0) {
453 UnixFileModeAttribute.toUnixMode(0, attrs); // may throw NPE or UOE
454 throw new UnsupportedOperationException("Initial file attributes" +
455 "not supported when creating symbolic link");
456 }
457
458 // permission check
459 SecurityManager sm = System.getSecurityManager();
460 if (sm != null) {
461 sm.checkPermission(new LinkPermission("symbolic"));
462 link.checkWrite();
463 }
464
465 // create link
466 try {
467 symlink(target.asByteArray(), link);
468 } catch (UnixException x) {
469 x.rethrowAsIOException(link);
470 }
471 }
472
473 @Override
474 public void createLink(Path obj1, Path obj2) throws IOException {
475 UnixPath link = UnixPath.toUnixPath(obj1);
476 UnixPath existing = UnixPath.toUnixPath(obj2);
477
478 // permission check
479 SecurityManager sm = System.getSecurityManager();
480 if (sm != null) {
481 sm.checkPermission(new LinkPermission("hard"));
482 link.checkWrite();
483 existing.checkWrite();
484 }
485 try {
486 link(existing, link);
487 } catch (UnixException x) {
488 x.rethrowAsIOException(link, existing);
489 }
490 }
491
492 @Override
493 public Path readSymbolicLink(Path obj1) throws IOException {
494 UnixPath link = UnixPath.toUnixPath(obj1);
495 // permission check
496 SecurityManager sm = System.getSecurityManager();
497 if (sm != null) {
498 FilePermission perm = new FilePermission(link.getPathForPermissionCheck(),
499 SecurityConstants.FILE_READLINK_ACTION);
500 AccessController.checkPermission(perm);
501 }
502 try {
503 byte[] target = readlink(link);
504 return new UnixPath(link.getFileSystem(), target);
505 } catch (UnixException x) {
506 if (x.errno() == UnixConstants.EINVAL)
507 throw new NotLinkException(link.getPathForExecptionMessage());
508 x.rethrowAsIOException(link);
509 return null; // keep compiler happy
510 }
511 }
512 }
|