示例#1
0
        private void SetUnixFileMode(SafeFileHandle?handle, string?path, UnixFileMode mode)
        {
            if ((mode & ~FileSystem.ValidUnixFileModes) != 0)
            {
                throw new ArgumentException(SR.Arg_InvalidUnixFileMode, nameof(UnixFileMode));
            }

            // Use ThrowNotFound to throw the appropriate exception when the file doesn't exist.
            if (handle is null && path is not null)
            {
                EnsureCachesInitialized(path);

                if (!EntryExists || IsBrokenLink)
                {
                    FileSystemInfo.ThrowNotFound(path);
                }
            }

            // Linux does not support link permissions.
            // To have consistent cross-platform behavior we operate on the link target.
            int rv = handle is not null?Interop.Sys.FChMod(handle, (int)mode)
                         : Interop.Sys.ChMod(path !, (int)mode);

            Interop.CheckIo(rv, path);

            InvalidateCaches();
        }
示例#2
0
        public static FileAttributes GetAttributes(string fullPath)
        {
            FileAttributes attributes = new FileInfo(fullPath, null).Attributes;

            if (attributes == (FileAttributes)(-1))
            {
                FileSystemInfo.ThrowNotFound(fullPath);
            }

            return(attributes);
        }
示例#3
0
        public void SetAttributes(string path, FileAttributes attributes)
        {
            // Validate that only flags from the attribute are being provided.  This is an
            // approximation for the validation done by the Win32 function.
            const FileAttributes allValidFlags =
                FileAttributes.Archive | FileAttributes.Compressed | FileAttributes.Device |
                FileAttributes.Directory | FileAttributes.Encrypted | FileAttributes.Hidden |
                FileAttributes.Hidden | FileAttributes.IntegrityStream | FileAttributes.Normal |
                FileAttributes.NoScrubData | FileAttributes.NotContentIndexed | FileAttributes.Offline |
                FileAttributes.ReadOnly | FileAttributes.ReparsePoint | FileAttributes.SparseFile |
                FileAttributes.System | FileAttributes.Temporary;

            if ((attributes & ~allValidFlags) != 0)
            {
                // Using constant string for argument to match historical throw
                throw new ArgumentException(SR.Arg_InvalidFileAttrs, "Attributes");
            }

            EnsureStatInitialized(path);

            if (!_exists)
            {
                FileSystemInfo.ThrowNotFound(path);
            }

            // The only thing we can reasonably change is whether the file object is readonly by changing permissions.

            int newMode = _fileStatus.Mode;

            if ((attributes & FileAttributes.ReadOnly) != 0)
            {
                // Take away all write permissions from user/group/everyone
                newMode &= ~(int)(Interop.Sys.Permissions.S_IWUSR | Interop.Sys.Permissions.S_IWGRP | Interop.Sys.Permissions.S_IWOTH);
            }
            else if ((newMode & (int)Interop.Sys.Permissions.S_IRUSR) != 0)
            {
                // Give write permission to the owner if the owner has read permission
                newMode |= (int)Interop.Sys.Permissions.S_IWUSR;
            }

            // Change the permissions on the file
            if (newMode != _fileStatus.Mode)
            {
                Interop.CheckIo(Interop.Sys.ChMod(path, newMode), path, InitiallyDirectory);
            }

            _fileStatusInitialized = -1;
        }
示例#4
0
        private unsafe void SetAccessOrWriteTimeCore(SafeFileHandle?handle, string?path, DateTimeOffset time, bool isAccessTime, bool checkCreationTime, bool asDirectory)
        {
            // This api is used to set creation time on non OSX platforms, and as a fallback for OSX platforms.
            // The reason why we use it to set 'creation time' is the below comment:
            // Unix provides APIs to update the last access time (atime) and last modification time (mtime).
            // There is no API to update the CreationTime.
            // Some platforms (e.g. Linux) don't store a creation time. On those platforms, the creation time
            // is synthesized as the oldest of last status change time (ctime) and last modification time (mtime).
            // We update the LastWriteTime (mtime).
            // This triggers a metadata change for FileSystemWatcher NotifyFilters.CreationTime.
            // Updating the mtime, causes the ctime to be set to 'now'. So, on platforms that don't store a
            // CreationTime, GetCreationTime will return the value that was previously set (when that value
            // wasn't in the future).

            // force a refresh so that we have an up-to-date times for values not being overwritten
            InvalidateCaches();
            EnsureCachesInitialized(handle, path);

            if (!EntryExists)
            {
                FileSystemInfo.ThrowNotFound(path);
            }

            // we use utimes()/utimensat() to set the accessTime and writeTime
            Interop.Sys.TimeSpec *buf = stackalloc Interop.Sys.TimeSpec[2];

            long seconds     = time.ToUnixTimeSeconds();
            long nanoseconds = UnixTimeSecondsToNanoseconds(time, seconds);

#if TARGET_BROWSER
            buf[0].TvSec  = seconds;
            buf[0].TvNsec = nanoseconds;
            buf[1].TvSec  = seconds;
            buf[1].TvNsec = nanoseconds;
#else
            if (isAccessTime)
            {
                buf[0].TvSec  = seconds;
                buf[0].TvNsec = nanoseconds;
                buf[1].TvSec  = _fileCache.MTime;
                buf[1].TvNsec = _fileCache.MTimeNsec;
            }
            else
            {
                buf[0].TvSec  = _fileCache.ATime;
                buf[0].TvNsec = _fileCache.ATimeNsec;
                buf[1].TvSec  = seconds;
                buf[1].TvNsec = nanoseconds;
            }
#endif
            int rv = handle is not null
                ? Interop.Sys.FUTimens(handle, buf)
                : Interop.Sys.UTimensat(path !, buf);

            Interop.CheckIo(rv, path, asDirectory);

            // On OSX-like platforms, when the modification time is less than the creation time (including
            // when the modification time is already less than but access time is being set), the creation
            // time is set to the modification time due to the api we're currently using; this is not
            // desirable behaviour since it is inconsistent with windows behaviour and is not logical to
            // the programmer (ie. we'd have to document it), so these api calls revert the creation time
            // when it shouldn't be set (since we're setting modification time and access time here).
            // checkCreationTime is only true on OSX-like platforms.
            // allowFallbackToLastWriteTime is ignored on non OSX-like platforms.
            bool updateCreationTime = checkCreationTime && (_fileCache.Flags & Interop.Sys.FileStatusFlags.HasBirthTime) != 0 &&
                                      (buf[1].TvSec < _fileCache.BirthTime || (buf[1].TvSec == _fileCache.BirthTime && buf[1].TvNsec < _fileCache.BirthTimeNsec));

            InvalidateCaches();

            if (updateCreationTime)
            {
                Interop.Error error = SetCreationTimeCore(handle, path, _fileCache.BirthTime, _fileCache.BirthTimeNsec);
                if (error != Interop.Error.SUCCESS && error != Interop.Error.ENOTSUP)
                {
                    Interop.CheckIo(error, path, asDirectory);
                }
            }
        }
示例#5
0
        private void SetAttributes(SafeFileHandle?handle, string?path, FileAttributes attributes, bool asDirectory)
        {
            // Validate that only flags from the attribute are being provided.  This is an
            // approximation for the validation done by the Win32 function.
            const FileAttributes allValidFlags =
                FileAttributes.Archive | FileAttributes.Compressed | FileAttributes.Device |
                FileAttributes.Directory | FileAttributes.Encrypted | FileAttributes.Hidden |
                FileAttributes.IntegrityStream | FileAttributes.Normal | FileAttributes.NoScrubData |
                FileAttributes.NotContentIndexed | FileAttributes.Offline | FileAttributes.ReadOnly |
                FileAttributes.ReparsePoint | FileAttributes.SparseFile | FileAttributes.System |
                FileAttributes.Temporary;

            if ((attributes & ~allValidFlags) != 0)
            {
                // Using constant string for argument to match historical throw
                throw new ArgumentException(SR.Arg_InvalidFileAttrs, "Attributes");
            }

            EnsureCachesInitialized(handle, path);

            if (!EntryExists)
            {
                FileSystemInfo.ThrowNotFound(path);
            }

            if (Interop.Sys.CanSetHiddenFlag)
            {
                bool hidden = (attributes & FileAttributes.Hidden) != 0;
                if (hidden ^ HasHiddenFlag)
                {
                    uint flags = hidden ? _fileCache.UserFlags | (uint)Interop.Sys.UserFlags.UF_HIDDEN :
                                 _fileCache.UserFlags & ~(uint)Interop.Sys.UserFlags.UF_HIDDEN;
                    int rv = handle is not null?Interop.Sys.FChflags(handle, flags) :
                                 Interop.Sys.LChflags(path !, flags);

                    Interop.CheckIo(rv, path, asDirectory);
                }
            }

            // The only thing we can reasonably change is whether the file object is readonly by changing permissions.

            int oldMode = _fileCache.Mode & (int)FileSystem.ValidUnixFileModes;
            int newMode = oldMode;

            if ((attributes & FileAttributes.ReadOnly) != 0)
            {
                // Take away all write permissions from user/group/everyone
                newMode &= ~(int)(UnixFileMode.UserWrite | UnixFileMode.GroupWrite | UnixFileMode.OtherWrite);
            }
            else if ((newMode & (int)UnixFileMode.UserRead) != 0)
            {
                // Give write permission to the owner if the owner has read permission
                newMode |= (int)UnixFileMode.UserWrite;
            }

            // Change the permissions on the file
            if (newMode != oldMode)
            {
                int rv = handle is not null?Interop.Sys.FChMod(handle, newMode) :
                             Interop.Sys.ChMod(path !, newMode);

                Interop.CheckIo(rv, path, asDirectory);
            }

            InvalidateCaches();
        }
示例#6
0
        internal void SetAttributes(string path, FileAttributes attributes, bool asDirectory)
        {
            // Validate that only flags from the attribute are being provided.  This is an
            // approximation for the validation done by the Win32 function.
            const FileAttributes allValidFlags =
                FileAttributes.Archive | FileAttributes.Compressed | FileAttributes.Device |
                FileAttributes.Directory | FileAttributes.Encrypted | FileAttributes.Hidden |
                FileAttributes.IntegrityStream | FileAttributes.Normal | FileAttributes.NoScrubData |
                FileAttributes.NotContentIndexed | FileAttributes.Offline | FileAttributes.ReadOnly |
                FileAttributes.ReparsePoint | FileAttributes.SparseFile | FileAttributes.System |
                FileAttributes.Temporary;

            if ((attributes & ~allValidFlags) != 0)
            {
                // Using constant string for argument to match historical throw
                throw new ArgumentException(SR.Arg_InvalidFileAttrs, "Attributes");
            }

            EnsureCachesInitialized(path);

            if (!EntryExists)
            {
                FileSystemInfo.ThrowNotFound(path);
            }

            if (Interop.Sys.CanSetHiddenFlag)
            {
                if ((attributes & FileAttributes.Hidden) != 0 && (_fileCache.UserFlags & (uint)Interop.Sys.UserFlags.UF_HIDDEN) == 0)
                {
                    // If Hidden flag is set and cached file status does not have the flag set then set it
                    Interop.CheckIo(Interop.Sys.LChflags(path, (_fileCache.UserFlags | (uint)Interop.Sys.UserFlags.UF_HIDDEN)), path, asDirectory);
                }
                else if (HasHiddenFlag)
                {
                    // If Hidden flag is not set and cached file status does have the flag set then remove it
                    Interop.CheckIo(Interop.Sys.LChflags(path, (_fileCache.UserFlags & ~(uint)Interop.Sys.UserFlags.UF_HIDDEN)), path, asDirectory);
                }
            }

            // The only thing we can reasonably change is whether the file object is readonly by changing permissions.

            int newMode = _fileCache.Mode;

            if ((attributes & FileAttributes.ReadOnly) != 0)
            {
                // Take away all write permissions from user/group/everyone
                newMode &= ~(int)(Interop.Sys.Permissions.S_IWUSR | Interop.Sys.Permissions.S_IWGRP | Interop.Sys.Permissions.S_IWOTH);
            }
            else if ((newMode & (int)Interop.Sys.Permissions.S_IRUSR) != 0)
            {
                // Give write permission to the owner if the owner has read permission
                newMode |= (int)Interop.Sys.Permissions.S_IWUSR;
            }

            // Change the permissions on the file
            if (newMode != _fileCache.Mode)
            {
                Interop.CheckIo(Interop.Sys.ChMod(path, newMode), path, asDirectory);
            }

            InvalidateCaches();
        }