private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options) { // FileStream performs most of the general argument validation. We can assume here that the arguments // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.) // Store the arguments _mode = mode; _options = options; if (_useAsyncIO) { _asyncState = new AsyncState(); } // Translate the arguments into arguments for an open call. Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, _access, share, options); // If the file gets created a new, we'll select the permissions for it. Most Unix utilities by default use 666 (read and // write for all), so we do the same (even though this doesn't match Windows, where by default it's possible to write out // a file and then execute it). No matter what we choose, it'll be subject to the umask applied by the system, such that the // actual permissions will typically be less than what we select here. const Interop.Sys.Permissions OpenPermissions = Interop.Sys.Permissions.S_IRUSR | Interop.Sys.Permissions.S_IWUSR | Interop.Sys.Permissions.S_IRGRP | Interop.Sys.Permissions.S_IWGRP | Interop.Sys.Permissions.S_IROTH | Interop.Sys.Permissions.S_IWOTH; // Open the file and store the safe handle. return(SafeFileHandle.Open(_path, openFlags, (int)OpenPermissions)); }
/// <summary> /// Initializes a new instance of the <see cref="Microsoft.Win32.SafeHandles.SafeFileHandle" /> class with the specified path, creation mode, read/write and sharing permission, the access other SafeFileHandles can have to the same file, additional file options and the allocation size. /// </summary> /// <param name="path">A relative or absolute path for the file that the current <see cref="Microsoft.Win32.SafeHandles.SafeFileHandle" /> instance will encapsulate.</param> /// <param name="mode">One of the enumeration values that determines how to open or create the file. The default value is <see cref="FileMode.Open" /></param> /// <param name="access">A bitwise combination of the enumeration values that determines how the file can be accessed. The default value is <see cref="FileAccess.Read" /></param> /// <param name="share">A bitwise combination of the enumeration values that determines how the file will be shared by processes. The default value is <see cref="FileShare.Read" />.</param> /// <param name="preallocationSize">The initial allocation size in bytes for the file. A positive value is effective only when a regular file is being created, overwritten, or replaced. /// Negative values are not allowed. In other cases (including the default 0 value), it's ignored.</param> /// <param name="options">An object that describes optional <see cref="Microsoft.Win32.SafeHandles.SafeFileHandle" /> parameters to use.</param> /// <exception cref="T:System.ArgumentNullException"><paramref name="path" /> is <see langword="null" />.</exception> /// <exception cref="T:System.ArgumentException"><paramref name="path" /> is an empty string (""), contains only white space, or contains one or more invalid characters. /// -or- /// <paramref name="path" /> refers to a non-file device, such as <c>CON:</c>, <c>COM1:</c>, <c>LPT1:</c>, etc. in an NTFS environment.</exception> /// <exception cref="T:System.NotSupportedException"><paramref name="path" /> refers to a non-file device, such as <c>CON:</c>, <c>COM1:</c>, <c>LPT1:</c>, etc. in a non-NTFS environment.</exception> /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="preallocationSize" /> is negative. /// -or- /// <paramref name="mode" />, <paramref name="access" />, or <paramref name="share" /> contain an invalid value.</exception> /// <exception cref="T:System.IO.FileNotFoundException">The file cannot be found, such as when <paramref name="mode" /> is <see cref="FileMode.Truncate" /> or <see cref="FileMode.Open" />, and the file specified by <paramref name="path" /> does not exist. The file must already exist in these modes.</exception> /// <exception cref="T:System.IO.IOException">An I/O error, such as specifying <see cref="FileMode.CreateNew" /> when the file specified by <paramref name="path" /> already exists, occurred. /// -or- /// The disk was full (when <paramref name="preallocationSize" /> was provided and <paramref name="path" /> was pointing to a regular file). /// -or- /// The file was too large (when <paramref name="preallocationSize" /> was provided and <paramref name="path" /> was pointing to a regular file).</exception> /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission.</exception> /// <exception cref="T:System.IO.DirectoryNotFoundException">The specified path is invalid, such as being on an unmapped drive.</exception> /// <exception cref="T:System.UnauthorizedAccessException">The <paramref name="access" /> requested is not permitted by the operating system for the specified <paramref name="path" />, such as when <paramref name="access" /> is <see cref="FileAccess.Write" /> or <see cref="FileAccess.ReadWrite" /> and the file or directory is set for read-only access. /// -or- /// <see cref="F:System.IO.FileOptions.Encrypted" /> is specified for <paramref name="options" />, but file encryption is not supported on the current platform.</exception> /// <exception cref="T:System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. </exception> public static SafeFileHandle OpenHandle(string path, FileMode mode = FileMode.Open, FileAccess access = FileAccess.Read, FileShare share = FileShare.Read, FileOptions options = FileOptions.None, long preallocationSize = 0) { Strategies.FileStreamHelpers.ValidateArguments(path, mode, access, share, bufferSize: 0, options, preallocationSize); return(SafeFileHandle.Open(Path.GetFullPath(path), mode, access, share, options, preallocationSize)); }
private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options) { // FileStream performs most of the general argument validation. We can assume here that the arguments // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.) // Store the arguments _mode = mode; _options = options; if (_useAsyncIO) { _asyncState = new AsyncState(); } // Translate the arguments into arguments for an open call. Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, _access, options); // FileShare currently ignored // If the file gets created a new, we'll select the permissions for it. Most utilities by default use 666 (read and // write for all). However, on Windows it's possible to write out a file and then execute it. To maintain that similarity, // we use 766, so that in addition the user has execute privileges. No matter what we choose, it'll be subject to the umask // applied by the system, such that the actual permissions will typically be less than what we select here. const Interop.Sys.Permissions openPermissions = Interop.Sys.Permissions.S_IRWXU | Interop.Sys.Permissions.S_IRGRP | Interop.Sys.Permissions.S_IWGRP | Interop.Sys.Permissions.S_IROTH | Interop.Sys.Permissions.S_IWOTH; // Open the file and store the safe handle. return(SafeFileHandle.Open(_path, openFlags, (int)openPermissions)); }
public static void CopyFile(string sourceFullPath, string destFullPath, bool overwrite) { long fileLength; UnixFileMode filePermissions; using SafeFileHandle src = SafeFileHandle.OpenReadOnly(sourceFullPath, FileOptions.None, out fileLength, out filePermissions); using SafeFileHandle dst = SafeFileHandle.Open(destFullPath, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, FileOptions.None, preallocationSize: 0, filePermissions, CreateOpenException); Interop.CheckIo(Interop.Sys.CopyFile(src, dst, fileLength));
public static void CopyFile(string sourceFullPath, string destFullPath, bool overwrite) { long fileLength; Interop.Sys.Permissions filePermissions; using SafeFileHandle src = SafeFileHandle.OpenReadOnly(sourceFullPath, FileOptions.None, out fileLength, out filePermissions); using SafeFileHandle dst = SafeFileHandle.Open(destFullPath, overwrite ? FileMode.Create : FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, FileOptions.None, preallocationSize: 0, openPermissions: filePermissions, (Interop.ErrorInfo error, Interop.Sys.OpenFlags flags, string path) => CreateOpenException(error, flags, path)); Interop.CheckIo(Interop.Sys.CopyFile(src, dst, fileLength));
/// <summary>Initializes a stream for reading or writing a Unix file.</summary> /// <param name="path">The path to the file.</param> /// <param name="mode">How the file should be opened.</param> /// <param name="access">Whether the file will be read, written, or both.</param> /// <param name="share">What other access to the file should be allowed. This is currently ignored.</param> /// <param name="bufferSize">The size of the buffer to use when buffering.</param> /// <param name="options">Additional options for working with the file.</param> internal UnixFileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, FileStream parent) : base(parent) { // FileStream performs most of the general argument validation. We can assume here that the arguments // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.) // Store the arguments _path = path; _access = access; _mode = mode; _options = options; _bufferLength = bufferSize; _useAsyncIO = (options & FileOptions.Asynchronous) != 0; // Translate the arguments into arguments for an open call Interop.libc.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, access, options); // FileShare currently ignored Interop.libc.Permissions openPermissions = Interop.libc.Permissions.S_IRWXU; // creator has read/write/execute permissions; no permissions for anyone else // Open the file and store the safe handle. Subsequent code in this method expects the safe handle to be initialized. _fileHandle = SafeFileHandle.Open(path, openFlags, (int)openPermissions); _fileHandle.IsAsync = _useAsyncIO; // Lock the file if requested via FileShare. This is only advisory locking. FileShare.None implies an exclusive // lock on the file and all other modes use a shared lock. While this is not as granular as Windows, not mandatory, // and not atomic with file opening, it's better than nothing. try { Interop.libc.LockOperations lockOperation = (share == FileShare.None) ? Interop.libc.LockOperations.LOCK_EX : Interop.libc.LockOperations.LOCK_SH; SysCall <Interop.libc.LockOperations, int>((fd, op, _) => Interop.libc.flock(fd, op), lockOperation | Interop.libc.LockOperations.LOCK_NB); } catch { _fileHandle.Dispose(); throw; } // Support additional options after the file has been opened. // These provide hints around how the file will be accessed. Interop.libc.Advice fadv = _options == FileOptions.RandomAccess ? Interop.libc.Advice.POSIX_FADV_RANDOM : _options == FileOptions.SequentialScan ? Interop.libc.Advice.POSIX_FADV_SEQUENTIAL : 0; if (fadv != 0) { SysCall <Interop.libc.Advice, int>((fd, advice, _) => Interop.libc.posix_fadvise(fd, 0, 0, advice), fadv); } // Jump to the end of the file if opened as Append. if (_mode == FileMode.Append) { _appendStart = SeekCore(0, SeekOrigin.End); } }