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(); }
public static FileAttributes GetAttributes(string fullPath) { FileAttributes attributes = new FileInfo(fullPath, null).Attributes; if (attributes == (FileAttributes)(-1)) { FileSystemInfo.ThrowNotFound(fullPath); } return(attributes); }
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; }
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); } } }
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(); }
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(); }