Path: blob/master/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java
41137 views
/*1* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import java.nio.file.attribute.*;28import java.util.concurrent.TimeUnit;29import java.util.Set;30import java.util.HashSet;3132/**33* Unix implementation of PosixFileAttributes.34*/3536class UnixFileAttributes37implements PosixFileAttributes38{39private int st_mode;40private long st_ino;41private long st_dev;42private long st_rdev;43private int st_nlink;44private int st_uid;45private int st_gid;46private long st_size;47private long st_atime_sec;48private long st_atime_nsec;49private long st_mtime_sec;50private long st_mtime_nsec;51private long st_ctime_sec;52private long st_ctime_nsec;53private long st_birthtime_sec;5455// created lazily56private volatile UserPrincipal owner;57private volatile GroupPrincipal group;58private volatile UnixFileKey key;5960private UnixFileAttributes() {61}6263// get the UnixFileAttributes for a given file64static UnixFileAttributes get(UnixPath path, boolean followLinks)65throws UnixException66{67UnixFileAttributes attrs = new UnixFileAttributes();68if (followLinks) {69UnixNativeDispatcher.stat(path, attrs);70} else {71UnixNativeDispatcher.lstat(path, attrs);72}73return attrs;74}7576// get the UnixFileAttributes for an open file77static UnixFileAttributes get(int fd) throws UnixException {78UnixFileAttributes attrs = new UnixFileAttributes();79UnixNativeDispatcher.fstat(fd, attrs);80return attrs;81}8283// get the UnixFileAttributes for a given file, relative to open directory84static UnixFileAttributes get(int dfd, UnixPath path, boolean followLinks)85throws UnixException86{87UnixFileAttributes attrs = new UnixFileAttributes();88int flag = (followLinks) ? 0 : UnixConstants.AT_SYMLINK_NOFOLLOW;89UnixNativeDispatcher.fstatat(dfd, path.asByteArray(), flag, attrs);90return attrs;91}9293// package-private94boolean isSameFile(UnixFileAttributes attrs) {95return ((st_ino == attrs.st_ino) && (st_dev == attrs.st_dev));96}9798// package-private99int mode() { return st_mode; }100long ino() { return st_ino; }101long dev() { return st_dev; }102long rdev() { return st_rdev; }103int nlink() { return st_nlink; }104int uid() { return st_uid; }105int gid() { return st_gid; }106107private static FileTime toFileTime(long sec, long nsec) {108if (nsec == 0) {109return FileTime.from(sec, TimeUnit.SECONDS);110} else {111try {112long nanos = Math.addExact(nsec,113Math.multiplyExact(sec, 1_000_000_000L));114return FileTime.from(nanos, TimeUnit.NANOSECONDS);115} catch (ArithmeticException ignore) {116// truncate to microseconds if nanoseconds overflow117long micro = sec*1_000_000L + nsec/1_000L;118return FileTime.from(micro, TimeUnit.MICROSECONDS);119}120}121}122123FileTime ctime() {124return toFileTime(st_ctime_sec, st_ctime_nsec);125}126127boolean isDevice() {128int type = st_mode & UnixConstants.S_IFMT;129return (type == UnixConstants.S_IFCHR ||130type == UnixConstants.S_IFBLK ||131type == UnixConstants.S_IFIFO);132}133134@Override135public FileTime lastModifiedTime() {136return toFileTime(st_mtime_sec, st_mtime_nsec);137}138139@Override140public FileTime lastAccessTime() {141return toFileTime(st_atime_sec, st_atime_nsec);142}143144@Override145public FileTime creationTime() {146if (UnixNativeDispatcher.birthtimeSupported()) {147return FileTime.from(st_birthtime_sec, TimeUnit.SECONDS);148} else {149// return last modified when birth time not supported150return lastModifiedTime();151}152}153154@Override155public boolean isRegularFile() {156return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFREG);157}158159@Override160public boolean isDirectory() {161return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR);162}163164@Override165public boolean isSymbolicLink() {166return ((st_mode & UnixConstants.S_IFMT) == UnixConstants.S_IFLNK);167}168169@Override170public boolean isOther() {171int type = st_mode & UnixConstants.S_IFMT;172return (type != UnixConstants.S_IFREG &&173type != UnixConstants.S_IFDIR &&174type != UnixConstants.S_IFLNK);175}176177@Override178public long size() {179return st_size;180}181182@Override183public UnixFileKey fileKey() {184if (key == null) {185synchronized (this) {186if (key == null) {187key = new UnixFileKey(st_dev, st_ino);188}189}190}191return key;192}193194@Override195public UserPrincipal owner() {196if (owner == null) {197synchronized (this) {198if (owner == null) {199owner = UnixUserPrincipals.fromUid(st_uid);200}201}202}203return owner;204}205206@Override207public GroupPrincipal group() {208if (group == null) {209synchronized (this) {210if (group == null) {211group = UnixUserPrincipals.fromGid(st_gid);212}213}214}215return group;216}217218@Override219public Set<PosixFilePermission> permissions() {220int bits = (st_mode & UnixConstants.S_IAMB);221HashSet<PosixFilePermission> perms = new HashSet<>();222223if ((bits & UnixConstants.S_IRUSR) > 0)224perms.add(PosixFilePermission.OWNER_READ);225if ((bits & UnixConstants.S_IWUSR) > 0)226perms.add(PosixFilePermission.OWNER_WRITE);227if ((bits & UnixConstants.S_IXUSR) > 0)228perms.add(PosixFilePermission.OWNER_EXECUTE);229230if ((bits & UnixConstants.S_IRGRP) > 0)231perms.add(PosixFilePermission.GROUP_READ);232if ((bits & UnixConstants.S_IWGRP) > 0)233perms.add(PosixFilePermission.GROUP_WRITE);234if ((bits & UnixConstants.S_IXGRP) > 0)235perms.add(PosixFilePermission.GROUP_EXECUTE);236237if ((bits & UnixConstants.S_IROTH) > 0)238perms.add(PosixFilePermission.OTHERS_READ);239if ((bits & UnixConstants.S_IWOTH) > 0)240perms.add(PosixFilePermission.OTHERS_WRITE);241if ((bits & UnixConstants.S_IXOTH) > 0)242perms.add(PosixFilePermission.OTHERS_EXECUTE);243244return perms;245}246247// wrap this object with BasicFileAttributes object to prevent leaking of248// user information249BasicFileAttributes asBasicFileAttributes() {250return UnixAsBasicFileAttributes.wrap(this);251}252253// unwrap BasicFileAttributes to get the underlying UnixFileAttributes254// object. Returns null is not wrapped.255static UnixFileAttributes toUnixFileAttributes(BasicFileAttributes attrs) {256if (attrs instanceof UnixFileAttributes)257return (UnixFileAttributes)attrs;258if (attrs instanceof UnixAsBasicFileAttributes) {259return ((UnixAsBasicFileAttributes)attrs).unwrap();260}261return null;262}263264// wrap a UnixFileAttributes object as a BasicFileAttributes265private static class UnixAsBasicFileAttributes implements BasicFileAttributes {266private final UnixFileAttributes attrs;267268private UnixAsBasicFileAttributes(UnixFileAttributes attrs) {269this.attrs = attrs;270}271272static UnixAsBasicFileAttributes wrap(UnixFileAttributes attrs) {273return new UnixAsBasicFileAttributes(attrs);274}275276UnixFileAttributes unwrap() {277return attrs;278}279280@Override281public FileTime lastModifiedTime() {282return attrs.lastModifiedTime();283}284@Override285public FileTime lastAccessTime() {286return attrs.lastAccessTime();287}288@Override289public FileTime creationTime() {290return attrs.creationTime();291}292@Override293public boolean isRegularFile() {294return attrs.isRegularFile();295}296@Override297public boolean isDirectory() {298return attrs.isDirectory();299}300@Override301public boolean isSymbolicLink() {302return attrs.isSymbolicLink();303}304@Override305public boolean isOther() {306return attrs.isOther();307}308@Override309public long size() {310return attrs.size();311}312@Override313public Object fileKey() {314return attrs.fileKey();315}316}317}318319320