/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int mode) { Debug.Assert(path != null); SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); // If we fail to open the file due to a path not existing, we need to know whether to blame // the file itself or its directory. If we're creating the file, then we blame the directory, // otherwise we blame the file. bool enoentDueToDirectory = (flags & Interop.Sys.OpenFlags.O_CREAT) != 0; // Open the file. int fd; while (Interop.CheckIo(fd = Interop.Sys.Open(path, flags, mode), path, isDirectory: enoentDueToDirectory, errorRewriter: e => (e.Error == Interop.Error.EISDIR) ? Interop.Error.EACCES.Info() : e)) ; handle.SetHandle(fd); // Make sure it's not a directory; we do this after opening it once we have a file descriptor // to avoid race conditions. Interop.Sys.FileStatus status; if (Interop.Sys.FStat(fd, out status) != 0) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), path); } if ((status.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Error.EACCES.Info(), path, isDirectory: true); } return handle; }
/// <summary>Opens a SafeFileHandle for a file descriptor created by a provided delegate.</summary> /// <param name="fdFunc"> /// The function that creates the file descriptor. Returns the file descriptor on success, or -1 on error, /// with Marshal.GetLastWin32Error() set to the error code. /// </param> /// <returns>The created SafeFileHandle.</returns> internal static SafeFileHandle Open(Func<int> fdFunc) { var handle = new SafeFileHandle(ownsHandle: true); int fd; while (Interop.CheckIo(fd = fdFunc())) ; handle.SetHandle(fd); return handle; }
/// <summary>Opens a SafeFileHandle for a file descriptor created by a provided delegate.</summary> /// <param name="fdFunc"> /// The function that creates the file descriptor. Returns the file descriptor on success, or -1 on error, /// with Marshal.GetLastWin32Error() set to the error code. /// </param> /// <returns>The created SafeFileHandle.</returns> internal static SafeFileHandle Open(Func <int> fdFunc) { var handle = new SafeFileHandle(ownsHandle: true); int fd; while (Interop.CheckIo(fd = fdFunc())) { ; } handle.SetHandle(fd); return(handle); }
/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, Interop.libc.OpenFlags flags, int mode) { Debug.Assert(path != null); // SafeFileHandle wraps a file descriptor rather than a pointer, and a file descriptor is always 4 bytes // rather than being pointer sized, which means we can't utilize the runtime's ability to marshal safe handles. // Ideally this would be a constrained execution region, but we don't have access to PrepareConstrainedRegions. // We still use a finally block to house the code that opens the file and stores the handle in hopes // of making it as non-interruptable as possible. The SafeFileHandle is also allocated first to avoid // the allocation after getting the file descriptor but before storing it. SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); try { } finally { // If we fail to open the file due to a path not existing, we need to know whether to blame // the file itself or its directory. If we're creating the file, then we blame the directory, // otherwise we blame the file. bool enoentDueToDirectory = (flags & Interop.libc.OpenFlags.O_CREAT) != 0; // Open the file. int fd; while (Interop.CheckIo(fd = Interop.libc.open(path, flags, mode), path, isDirectory: enoentDueToDirectory, errorRewriter: errno => (errno == Interop.Errors.EISDIR) ? Interop.Errors.EACCES : errno)) { ; } Debug.Assert(fd >= 0); handle.SetHandle((IntPtr)fd); Debug.Assert(!handle.IsInvalid); // Make sure it's not a directory; we do this after opening it once we have a file descriptor // to avoid race conditions. Interop.libcoreclrpal.fileinfo buf; if (Interop.libcoreclrpal.GetFileInformationFromFd(fd, out buf) != 0) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Marshal.GetLastWin32Error(), path); } if ((buf.mode & Interop.libcoreclrpal.FileTypes.S_IFMT) == Interop.libcoreclrpal.FileTypes.S_IFDIR) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Errors.EACCES, path, isDirectory: true); } } return(handle); }
/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, int flags, int mode) { // SafeFileHandle wraps a file descriptor rather than a pointer, and a file descriptor is always 4 bytes // rather than being pointer sized, which means we can't utilize the runtime's ability to marshal safe handles. // Ideally this would be a constrained execution region, but we don't have access to PrepareConstrainedRegions. // We still use a finally block to house the code that opens the file and stores the handle in hopes // of making it as non-interruptable as possible. The SafeFileHandle is also allocated first to avoid // the allocation after getting the file descriptor but before storing it. SafeFileHandle handle = new SafeFileHandle(); try { } finally { int fd; while (Interop.CheckIo(fd = Interop.open64(path, flags, mode))) ; Contract.Assert(fd >= 0); handle.SetHandle((IntPtr)fd); } return handle; }
/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int mode) { Debug.Assert(path != null); // SafeFileHandle wraps a file descriptor rather than a pointer, and a file descriptor is always 4 bytes // rather than being pointer sized, which means we can't utilize the runtime's ability to marshal safe handles. // Ideally this would be a constrained execution region, but we don't have access to PrepareConstrainedRegions. // We still use a finally block to house the code that opens the file and stores the handle in hopes // of making it as non-interruptable as possible. The SafeFileHandle is also allocated first to avoid // the allocation after getting the file descriptor but before storing it. SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); try { } finally { // If we fail to open the file due to a path not existing, we need to know whether to blame // the file itself or its directory. If we're creating the file, then we blame the directory, // otherwise we blame the file. bool enoentDueToDirectory = (flags & Interop.Sys.OpenFlags.O_CREAT) != 0; // Open the file. int fd; while (Interop.CheckIo(fd = Interop.Sys.Open(path, flags, mode), path, isDirectory: enoentDueToDirectory, errorRewriter: e => (e.Error == Interop.Error.EISDIR) ? Interop.Error.EACCES.Info() : e)) ; Debug.Assert(fd >= 0); handle.SetHandle((IntPtr)fd); Debug.Assert(!handle.IsInvalid); // Make sure it's not a directory; we do this after opening it once we have a file descriptor // to avoid race conditions. Interop.Sys.FileStatus status; if (Interop.Sys.FStat(fd, out status) != 0) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), path); } if ((status.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Error.EACCES.Info(), path, isDirectory: true); } } return handle; }
/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, int flags, int mode) { // SafeFileHandle wraps a file descriptor rather than a pointer, and a file descriptor is always 4 bytes // rather than being pointer sized, which means we can't utilize the runtime's ability to marshal safe handles. // Ideally this would be a constrained execution region, but we don't have access to PrepareConstrainedRegions. // We still use a finally block to house the code that opens the file and stores the handle in hopes // of making it as non-interruptable as possible. The SafeFileHandle is also allocated first to avoid // the allocation after getting the file descriptor but before storing it. SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); try { } finally { int fd; while (Interop.CheckIo(fd = Interop.open64(path, flags, mode))) { ; } Contract.Assert(fd >= 0); handle.SetHandle((IntPtr)fd); } return(handle); }
/// <summary>Opens the specified file with the requested flags and mode.</summary> /// <param name="path">The path to the file.</param> /// <param name="flags">The flags with which to open the file.</param> /// <param name="mode">The mode for opening the file.</param> /// <returns>A SafeFileHandle for the opened file.</returns> internal static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int mode) { Debug.Assert(path != null); SafeFileHandle handle = new SafeFileHandle(ownsHandle: true); // If we fail to open the file due to a path not existing, we need to know whether to blame // the file itself or its directory. If we're creating the file, then we blame the directory, // otherwise we blame the file. bool enoentDueToDirectory = (flags & Interop.Sys.OpenFlags.O_CREAT) != 0; // Open the file. int fd; while (Interop.CheckIo(fd = Interop.Sys.Open(path, flags, mode), path, isDirectory: enoentDueToDirectory, errorRewriter: e => (e.Error == Interop.Error.EISDIR) ? Interop.Error.EACCES.Info() : e)) { ; } handle.SetHandle(fd); // Make sure it's not a directory; we do this after opening it once we have a file descriptor // to avoid race conditions. Interop.Sys.FileStatus status; if (Interop.Sys.FStat(fd, out status) != 0) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), path); } if ((status.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR) { handle.Dispose(); throw Interop.GetExceptionForIoErrno(Interop.Error.EACCES.Info(), path, isDirectory: true); } return(handle); }