Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.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.*;28import java.nio.ByteBuffer;29import java.nio.channels.FileChannel;30import java.io.IOException;31import java.util.*;3233import static sun.nio.fs.UnixNativeDispatcher.*;34import static sun.nio.fs.UnixConstants.*;35import static sun.nio.fs.SolarisConstants.*;3637/**38* Solaris emulation of NamedAttributeView using extended attributes.39*/4041class SolarisUserDefinedFileAttributeView42extends AbstractUserDefinedFileAttributeView43{44private static final byte[] HERE = { '.' };4546private byte[] nameAsBytes(UnixPath file, String name) throws IOException {47byte[] bytes = Util.toBytes(name);48// "", "." and ".." not allowed49if (bytes.length == 0 || bytes[0] == '.') {50if (bytes.length <= 1 ||51(bytes.length == 2 && bytes[1] == '.'))52{53throw new FileSystemException(file.getPathForExceptionMessage(),54null, "'" + name + "' is not a valid name");55}56}57return bytes;58}5960private final UnixPath file;61private final boolean followLinks;6263SolarisUserDefinedFileAttributeView(UnixPath file, boolean followLinks) {64this.file = file;65this.followLinks = followLinks;66}6768@Override69public List<String> list() throws IOException {70if (System.getSecurityManager() != null)71checkAccess(file.getPathForPermissionCheck(), true, false);7273int fd = file.openForAttributeAccess(followLinks);74try {75try {76// open extended attribute directory77int dfd = openat(fd, HERE, (O_RDONLY|O_XATTR), 0);78long dp;79try {80dp = fdopendir(dfd);81} catch (UnixException x) {82close(dfd);83throw x;84}8586// read list of extended attributes87List<String> list = new ArrayList<>();88try {89byte[] name;90while ((name = readdir(dp)) != null) {91String s = Util.toString(name);92if (!s.equals(".") && !s.equals(".."))93list.add(s);94}95} finally {96closedir(dp);97}98return Collections.unmodifiableList(list);99} catch (UnixException x) {100throw new FileSystemException(file.getPathForExceptionMessage(),101null, "Unable to get list of extended attributes: " +102x.getMessage());103}104} finally {105close(fd);106}107}108109@Override110public int size(String name) throws IOException {111if (System.getSecurityManager() != null)112checkAccess(file.getPathForPermissionCheck(), true, false);113114int fd = file.openForAttributeAccess(followLinks);115try {116try {117// open attribute file118int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);119try {120// read attribute's attributes121UnixFileAttributes attrs = UnixFileAttributes.get(afd);122long size = attrs.size();123if (size > Integer.MAX_VALUE)124throw new ArithmeticException("Extended attribute value too large");125return (int)size;126} finally {127close(afd);128}129} catch (UnixException x) {130throw new FileSystemException(file.getPathForExceptionMessage(),131null, "Unable to get size of extended attribute '" + name +132"': " + x.getMessage());133}134} finally {135close(fd);136}137}138139@Override140public int read(String name, ByteBuffer dst) throws IOException {141if (System.getSecurityManager() != null)142checkAccess(file.getPathForPermissionCheck(), true, false);143144int fd = file.openForAttributeAccess(followLinks);145try {146try {147// open attribute file148int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);149150// wrap with channel151FileChannel fc = UnixChannelFactory.newFileChannel(afd, file.toString(), true, false);152153// read to EOF (nothing we can do if I/O error occurs)154try {155if (fc.size() > dst.remaining())156throw new IOException("Extended attribute file too large");157int total = 0;158while (dst.hasRemaining()) {159int n = fc.read(dst);160if (n < 0)161break;162total += n;163}164return total;165} finally {166fc.close();167}168} catch (UnixException x) {169throw new FileSystemException(file.getPathForExceptionMessage(),170null, "Unable to read extended attribute '" + name +171"': " + x.getMessage());172}173} finally {174close(fd);175}176}177178@Override179public int write(String name, ByteBuffer src) throws IOException {180if (System.getSecurityManager() != null)181checkAccess(file.getPathForPermissionCheck(), false, true);182183int fd = file.openForAttributeAccess(followLinks);184try {185try {186// open/create attribute file187int afd = openat(fd, nameAsBytes(file,name),188(O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),189UnixFileModeAttribute.ALL_PERMISSIONS);190191// wrap with channel192FileChannel fc = UnixChannelFactory.newFileChannel(afd, file.toString(), false, true);193194// write value (nothing we can do if I/O error occurs)195try {196int rem = src.remaining();197while (src.hasRemaining()) {198fc.write(src);199}200return rem;201} finally {202fc.close();203}204} catch (UnixException x) {205throw new FileSystemException(file.getPathForExceptionMessage(),206null, "Unable to write extended attribute '" + name +207"': " + x.getMessage());208}209} finally {210close(fd);211}212}213214@Override215public void delete(String name) throws IOException {216if (System.getSecurityManager() != null)217checkAccess(file.getPathForPermissionCheck(), false, true);218219int fd = file.openForAttributeAccess(followLinks);220try {221int dfd = openat(fd, HERE, (O_RDONLY|O_XATTR), 0);222try {223unlinkat(dfd, nameAsBytes(file,name), 0);224} finally {225close(dfd);226}227} catch (UnixException x) {228throw new FileSystemException(file.getPathForExceptionMessage(),229null, "Unable to delete extended attribute '" + name +230"': " + x.getMessage());231} finally {232close(fd);233}234}235236/**237* Used by copyTo/moveTo to copy extended attributes from source to target.238*239* @param ofd240* file descriptor for source file241* @param nfd242* file descriptor for target file243*/244static void copyExtendedAttributes(int ofd, int nfd) {245try {246// open extended attribute directory247int dfd = openat(ofd, HERE, (O_RDONLY|O_XATTR), 0);248long dp = 0L;249try {250dp = fdopendir(dfd);251} catch (UnixException x) {252close(dfd);253throw x;254}255256// copy each extended attribute257try {258byte[] name;259while ((name = readdir(dp)) != null) {260// ignore "." and ".."261if (name[0] == '.') {262if (name.length == 1)263continue;264if (name.length == 2 && name[1] == '.')265continue;266}267copyExtendedAttribute(ofd, name, nfd);268}269} finally {270closedir(dp);271}272} catch (UnixException ignore) {273}274}275276private static void copyExtendedAttribute(int ofd, byte[] name, int nfd)277throws UnixException278{279// open source attribute file280int src = openat(ofd, name, (O_RDONLY|O_XATTR), 0);281try {282// create target attribute file283int dst = openat(nfd, name, (O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),284UnixFileModeAttribute.ALL_PERMISSIONS);285try {286UnixCopyFile.transfer(dst, src, 0L);287} finally {288close(dst);289}290} finally {291close(src);292}293}294}295296297