Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Fix handling of flock in FileStream on Unix (#23235)
Browse files Browse the repository at this point in the history
On Unix, we implement FileShare in FileStream with flock.  On some file systems, flock returns EACCES, which causes us to fail to allow usage of FileStream at all.  This commit changes the code to only handle the one error we actually care about, EWOULDBLOCK, which indicates that the operation would block and hence that sharing failed.  All other errors can be ignored, as this is only advisory / best-effort.
  • Loading branch information
danmoseley committed Aug 15, 2017
1 parent a54c0a9 commit ec5640f
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/System.IO.FileSystem/src/System/IO/UnixFileStream.cs
Expand Up @@ -130,11 +130,20 @@ internal UnixFileStream(String path, FileMode mode, FileAccess access, FileShare

// 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. Some kinds of files, e.g. FIFOs, don't support
// locking on some platforms, e.g. OSX, and so if flock returns ENOTSUP, we similarly treat it as a hint and ignore it,
// as we don't want to entirely prevent usage of a particular file simply because locking isn't supported.
// and not atomic with file opening, it's better than nothing.
Interop.Sys.LockOperations lockOperation = (share == FileShare.None) ? Interop.Sys.LockOperations.LOCK_EX : Interop.Sys.LockOperations.LOCK_SH;
CheckFileCall(Interop.Sys.FLock(_fileHandle, lockOperation | Interop.Sys.LockOperations.LOCK_NB), ignoreNotSupported: true);
if (Interop.Sys.FLock(_fileHandle, lockOperation | Interop.Sys.LockOperations.LOCK_NB) < 0)
{
// The only error we care about is EWOULDBLOCK, which indicates that the file is currently locked by someone
// else and we would block trying to access it. Other errors, such as ENOTSUP (locking isn't supported) or
// EACCES (the file system doesn't allow us to lock), will only hamper FileStream's usage without providing value,
// given again that this is only advisory / best-effort.
Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
if (errorInfo.Error == Interop.Error.EWOULDBLOCK)
{
throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
}
}

// These provide hints around how the file will be accessed. Specifying both RandomAccess
// and Sequential together doesn't make sense as they are two competing options on the same spectrum,
Expand Down

0 comments on commit ec5640f

Please sign in to comment.