Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Src/Libraries/Builtins/FileOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ internal static int GetNativeFileDescriptor(RubyIO/*!*/ io) {
[RubyMethod("flock", BuildConfig = "FEATURE_FILESYSTEM")]
public static object FileLock(RubyFile/*!*/ self, [DefaultProtocol]int operation) {
self.RequireInitialized();
if (!Posix.IsAvailable) {
if (!Posix.IsFlockAvailable) {
throw new IronRuby.Builtins.NotImplementedError("flock() function is unimplemented on this machine");
}

Expand All @@ -1118,7 +1118,7 @@ public static object FileLock(RubyFile/*!*/ self, [DefaultProtocol]int operation
if (Posix.Flock(fd, operation | Posix.LOCK_NB, out errno) == 0) {
return 0;
}
if (errno != Posix.EWOULDBLOCK) {
if (errno != Posix.EWouldBlock) {
throw Posix.Error(errno, self.Path);
}
if (nonBlocking) {
Expand Down
23 changes: 23 additions & 0 deletions Src/Libraries/Builtins/Posix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,29 @@ internal static class Posix {
System.IO.Path.DirectorySeparatorChar == '/' &&
!RuntimeInformation.IsOSPlatform(OSPlatform.OSX);

/// <summary>
/// flock(2) is the same call with the same operation bits on every Unix, so it is
/// offered on macOS too, where the rest of this class (statx, Linux errno numbers)
/// is not. RubyGems takes a lock on every binstub it writes, so without this
/// `gem install` of anything with an executable failed on a Mac.
/// </summary>
internal static readonly bool IsFlockAvailable = System.IO.Path.DirectorySeparatorChar == '/';

/// <summary>
/// errno for "would block" on this platform: EAGAIN is 11 on Linux and 35 on macOS and
/// the other BSDs, whose errno numbering macOS inherited. IsFlockAvailable lets every
/// Unix in, so a BSD has to get 35 too, or a contended LOCK_NB raises instead of
/// returning false and a blocking lock never retries.
/// </summary>
internal static readonly int EWouldBlock = IsBsdErrno() ? 35 : EWOULDBLOCK;

private static bool IsBsdErrno() {
return RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ||
RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("NETBSD")) ||
RuntimeInformation.IsOSPlatform(OSPlatform.Create("OPENBSD"));
}

#region errno numbers

internal const int EPERM = 1;
Expand Down
Loading