Xamarin Public Jenkins (auto-signing) 73ee7591e8 Imported Upstream version 6.8.0.73
Former-commit-id: d18deab1b47cfd3ad8cba82b3f37d00eec2170af
2019-12-10 18:00:56 +00:00

134 lines
3.5 KiB
C#

//
// Tests for FcntlCommand.F_OFD_{GETLK,SETLK,SETLKW}
//
// Authors:
// Steffen Kiess (kiess@ki4.de)
//
// Copyright (C) 2019 Steffen Kiess
//
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Mono.Unix;
using Mono.Unix.Native;
using NUnit.Framework;
namespace MonoTests.Mono.Unix.Native
{
[TestFixture, Category ("NotDotNet"), Category ("NotOnWindows"), Category ("NotOnMac")]
public class OFDLockTest {
string TempFolder;
[SetUp]
public void SetUp ()
{
TempFolder = Path.Combine (Path.GetTempPath (), this.GetType ().FullName);
if (Directory.Exists (TempFolder))
Directory.Delete (TempFolder, true);
Directory.CreateDirectory (TempFolder);
}
[TearDown]
public void TearDown()
{
if (Directory.Exists (TempFolder))
Directory.Delete (TempFolder, true);
}
[Test]
public void TestOFDLock ()
{
int fd1 = Syscall.open (TempFolder + "/testfile", OpenFlags.O_RDWR | OpenFlags.O_CREAT | OpenFlags.O_EXCL, FilePermissions.DEFFILEMODE);
if (fd1 < 0)
UnixMarshal.ThrowExceptionForLastError ();
int fd2 = Syscall.open (TempFolder + "/testfile", OpenFlags.O_RDWR);
if (fd2 < 0)
UnixMarshal.ThrowExceptionForLastError ();
int fd3 = Syscall.open (TempFolder + "/testfile", OpenFlags.O_RDWR);
if (fd3 < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Get read lock for first 100 bytes on fd1
var flock1 = new Flock {
l_type = LockType.F_RDLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 0,
l_len = 100,
};
if (Syscall.fcntl (fd1, FcntlCommand.F_OFD_SETLKW, ref flock1) < 0) {
// Old kernels and non-linux systems should return EINVAL
if (Stdlib.GetLastError () == Errno.EINVAL)
Assert.Ignore ("F_OFD_SETLKW does not seem to be supported.");
UnixMarshal.ThrowExceptionForLastError ();
}
// Get read lock for first 100 bytes on fd2
var flock2 = new Flock {
l_type = LockType.F_RDLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 0,
l_len = 100,
};
if (Syscall.fcntl (fd2, FcntlCommand.F_OFD_SETLK, ref flock2) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Get write lock for remaining bytes on fd1
var flock3 = new Flock {
l_type = LockType.F_WRLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 100,
l_len = 0,
};
if (Syscall.fcntl (fd1, FcntlCommand.F_OFD_SETLK, ref flock3) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Close fd3, should not release lock
if (Syscall.close (fd3) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// Get lock status for byte 150 from fd2
var flock4 = new Flock {
l_type = LockType.F_RDLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 150,
l_len = 1,
};
if (Syscall.fcntl (fd2, FcntlCommand.F_OFD_GETLK, ref flock4) < 0)
UnixMarshal.ThrowExceptionForLastError ();
// There should be a conflicting write lock
Assert.AreEqual (LockType.F_WRLCK, flock4.l_type);
// Get write byte 0 on fd1, should fail with EAGAIN
var flock5 = new Flock {
l_type = LockType.F_WRLCK,
l_whence = SeekFlags.SEEK_SET,
l_start = 0,
l_len = 1,
};
var res = Syscall.fcntl (fd1, FcntlCommand.F_OFD_SETLK, ref flock5);
Assert.AreEqual (-1, res);
Assert.AreEqual (Errno.EAGAIN, Stdlib.GetLastError ());
if (Syscall.close (fd1) < 0)
UnixMarshal.ThrowExceptionForLastError ();
if (Syscall.close (fd2) < 0)
UnixMarshal.ThrowExceptionForLastError ();
}
}
}
// vim: noexpandtab
// Local Variables:
// tab-width: 4
// c-basic-offset: 4
// indent-tabs-mode: t
// End: