Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/fs/LinuxDosFileAttributeView.java
32288 views
/*1* Copyright (c) 2008, 2013, 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.Map;29import java.util.Set;30import java.io.IOException;31import sun.misc.Unsafe;3233import static sun.nio.fs.UnixNativeDispatcher.*;34import static sun.nio.fs.UnixConstants.*;3536/**37* Linux implementation of DosFileAttributeView for use on file systems such38* as ext3 that have extended attributes enabled and SAMBA configured to store39* DOS attributes.40*/4142class LinuxDosFileAttributeView43extends UnixFileAttributeViews.Basic implements DosFileAttributeView44{45private static final Unsafe unsafe = Unsafe.getUnsafe();4647private static final String READONLY_NAME = "readonly";48private static final String ARCHIVE_NAME = "archive";49private static final String SYSTEM_NAME = "system";50private static final String HIDDEN_NAME = "hidden";5152private static final String DOS_XATTR_NAME = "user.DOSATTRIB";53private static final byte[] DOS_XATTR_NAME_AS_BYTES = Util.toBytes(DOS_XATTR_NAME);5455private static final int DOS_XATTR_READONLY = 0x01;56private static final int DOS_XATTR_HIDDEN = 0x02;57private static final int DOS_XATTR_SYSTEM = 0x04;58private static final int DOS_XATTR_ARCHIVE = 0x20;5960// the names of the DOS attributes (includes basic)61private static final Set<String> dosAttributeNames =62Util.newSet(basicAttributeNames, READONLY_NAME, ARCHIVE_NAME, SYSTEM_NAME, HIDDEN_NAME);6364LinuxDosFileAttributeView(UnixPath file, boolean followLinks) {65super(file, followLinks);66}6768@Override69public String name() {70return "dos";71}7273@Override74public void setAttribute(String attribute, Object value)75throws IOException76{77if (attribute.equals(READONLY_NAME)) {78setReadOnly((Boolean)value);79return;80}81if (attribute.equals(ARCHIVE_NAME)) {82setArchive((Boolean)value);83return;84}85if (attribute.equals(SYSTEM_NAME)) {86setSystem((Boolean)value);87return;88}89if (attribute.equals(HIDDEN_NAME)) {90setHidden((Boolean)value);91return;92}93super.setAttribute(attribute, value);94}9596@Override97public Map<String,Object> readAttributes(String[] attributes)98throws IOException99{100AttributesBuilder builder =101AttributesBuilder.create(dosAttributeNames, attributes);102DosFileAttributes attrs = readAttributes();103addRequestedBasicAttributes(attrs, builder);104if (builder.match(READONLY_NAME))105builder.add(READONLY_NAME, attrs.isReadOnly());106if (builder.match(ARCHIVE_NAME))107builder.add(ARCHIVE_NAME, attrs.isArchive());108if (builder.match(SYSTEM_NAME))109builder.add(SYSTEM_NAME, attrs.isSystem());110if (builder.match(HIDDEN_NAME))111builder.add(HIDDEN_NAME, attrs.isHidden());112return builder.unmodifiableMap();113}114115@Override116public DosFileAttributes readAttributes() throws IOException {117file.checkRead();118119int fd = file.openForAttributeAccess(followLinks);120try {121final UnixFileAttributes attrs = UnixFileAttributes.get(fd);122final int dosAttribute = getDosAttribute(fd);123124return new DosFileAttributes() {125@Override126public FileTime lastModifiedTime() {127return attrs.lastModifiedTime();128}129@Override130public FileTime lastAccessTime() {131return attrs.lastAccessTime();132}133@Override134public FileTime creationTime() {135return attrs.creationTime();136}137@Override138public boolean isRegularFile() {139return attrs.isRegularFile();140}141@Override142public boolean isDirectory() {143return attrs.isDirectory();144}145@Override146public boolean isSymbolicLink() {147return attrs.isSymbolicLink();148}149@Override150public boolean isOther() {151return attrs.isOther();152}153@Override154public long size() {155return attrs.size();156}157@Override158public Object fileKey() {159return attrs.fileKey();160}161@Override162public boolean isReadOnly() {163return (dosAttribute & DOS_XATTR_READONLY) != 0;164}165@Override166public boolean isHidden() {167return (dosAttribute & DOS_XATTR_HIDDEN) != 0;168}169@Override170public boolean isArchive() {171return (dosAttribute & DOS_XATTR_ARCHIVE) != 0;172}173@Override174public boolean isSystem() {175return (dosAttribute & DOS_XATTR_SYSTEM) != 0;176}177};178179} catch (UnixException x) {180x.rethrowAsIOException(file);181return null; // keep compiler happy182} finally {183close(fd);184}185}186187@Override188public void setReadOnly(boolean value) throws IOException {189updateDosAttribute(DOS_XATTR_READONLY, value);190}191192@Override193public void setHidden(boolean value) throws IOException {194updateDosAttribute(DOS_XATTR_HIDDEN, value);195}196197@Override198public void setArchive(boolean value) throws IOException {199updateDosAttribute(DOS_XATTR_ARCHIVE, value);200}201202@Override203public void setSystem(boolean value) throws IOException {204updateDosAttribute(DOS_XATTR_SYSTEM, value);205}206207/**208* Reads the value of the user.DOSATTRIB extended attribute209*/210private int getDosAttribute(int fd) throws UnixException {211final int size = 24;212213NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);214try {215int len = LinuxNativeDispatcher216.fgetxattr(fd, DOS_XATTR_NAME_AS_BYTES, buffer.address(), size);217218if (len > 0) {219// ignore null terminator220if (unsafe.getByte(buffer.address()+len-1) == 0)221len--;222223// convert to String and parse224byte[] buf = new byte[len];225unsafe.copyMemory(null, buffer.address(), buf,226Unsafe.ARRAY_BYTE_BASE_OFFSET, len);227String value = Util.toString(buf);228229// should be something like 0x20230if (value.length() >= 3 && value.startsWith("0x")) {231try {232return Integer.parseInt(value.substring(2), 16);233} catch (NumberFormatException x) {234// ignore235}236}237}238throw new UnixException("Value of " + DOS_XATTR_NAME + " attribute is invalid");239} catch (UnixException x) {240// default value when attribute does not exist241if (x.errno() == ENODATA)242return 0;243throw x;244} finally {245buffer.release();246}247}248249/**250* Updates the value of the user.DOSATTRIB extended attribute251*/252private void updateDosAttribute(int flag, boolean enable) throws IOException {253file.checkWrite();254255int fd = file.openForAttributeAccess(followLinks);256try {257int oldValue = getDosAttribute(fd);258int newValue = oldValue;259if (enable) {260newValue |= flag;261} else {262newValue &= ~flag;263}264if (newValue != oldValue) {265byte[] value = Util.toBytes("0x" + Integer.toHexString(newValue));266NativeBuffer buffer = NativeBuffers.asNativeBuffer(value);267try {268LinuxNativeDispatcher.fsetxattr(fd, DOS_XATTR_NAME_AS_BYTES,269buffer.address(), value.length+1);270} finally {271buffer.release();272}273}274} catch (UnixException x) {275x.rethrowAsIOException(file);276} finally {277close(fd);278}279}280}281282283