Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        /// <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));
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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));
Exemplo n.º 5
0
        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));
Exemplo n.º 6
0
        /// <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);
            }
        }