mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Switch to using fcntl from flock on unix
This commit is contained in:
@@ -55,27 +55,77 @@ namespace Velopack.Util
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int flock(int fd, int operation);
|
||||
|
||||
private const int LOCK_SH = 1; // Shared lock
|
||||
private const int LOCK_EX = 2; // Exclusive lock
|
||||
private const int LOCK_NB = 4; // Non-blocking
|
||||
private const int LOCK_UN = 8; // Unlock
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
[SupportedOSPlatform("macos")]
|
||||
private void UnixExclusiveLock(int fd)
|
||||
{
|
||||
int ret = flock(fd, LOCK_EX | LOCK_NB);
|
||||
if (ret != 0) {
|
||||
throw new IOException("flock returned error: " + ret);
|
||||
int ret;
|
||||
if (VelopackRuntimeInfo.IsLinux) {
|
||||
var lockOpt = new linux_flock {
|
||||
l_type = F_WRLCK,
|
||||
l_whence = SEEK_SET,
|
||||
l_start = 0,
|
||||
l_len = 0, // 0 means to lock the entire file
|
||||
l_pid = 0,
|
||||
};
|
||||
ret = fcntl(fd, F_SETLK, ref lockOpt);
|
||||
} else if (VelopackRuntimeInfo.IsOSX) {
|
||||
var lockOpt = new osx_flock {
|
||||
l_start = 0,
|
||||
l_len = 0, // 0 means to lock the entire file
|
||||
l_pid = 0,
|
||||
l_type = F_WRLCK,
|
||||
l_whence = SEEK_SET,
|
||||
};
|
||||
Console.WriteLine("hello");
|
||||
ret = fcntl(fd, F_SETLK, ref lockOpt);
|
||||
} else {
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
Console.WriteLine(ret);
|
||||
if (ret == -1) {
|
||||
int errno = Marshal.GetLastWin32Error();
|
||||
throw new IOException($"fcntl F_SETLK failed, errno: {errno}", new Win32Exception(errno));
|
||||
}
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int fcntl(int fd, int cmd, ref linux_flock linux_flock);
|
||||
|
||||
[SupportedOSPlatform("macos")]
|
||||
[DllImport("libc", SetLastError = true)]
|
||||
private static extern int fcntl(int fd, int cmd, ref osx_flock linux_flock);
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct linux_flock
|
||||
{
|
||||
public short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
|
||||
public short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */
|
||||
public long l_start; /* Starting offset for lock */
|
||||
public long l_len; /* Number of bytes to lock */
|
||||
public int l_pid; /* PID of the process blocking our lock (F_GETLK only) */
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("macos")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct osx_flock
|
||||
{
|
||||
public long l_start; /* Starting offset for lock */
|
||||
public long l_len; /* Number of bytes to lock */
|
||||
public int l_pid; /* PID of the process blocking our lock (F_GETLK only) */
|
||||
public short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
|
||||
public short l_whence; /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */
|
||||
}
|
||||
|
||||
private const int F_SETLK = 6; /* Non-blocking lock */
|
||||
private const short F_RDLCK = 0; /* Read lock */
|
||||
private const short F_WRLCK = 1; /* Write lock */
|
||||
private const short F_UNLCK = 2; /* Remove lock */
|
||||
private const short SEEK_SET = 0;
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern bool LockFileEx(SafeFileHandle hFile, uint dwFlags, uint dwReserved, uint nNumberOfBytesToLockLow, uint nNumberOfBytesToLockHigh,
|
||||
|
||||
@@ -35,7 +35,7 @@ impl LockFile {
|
||||
{
|
||||
use std::os::unix::io::AsRawFd;
|
||||
let fd = file.as_raw_fd();
|
||||
self.unix_exclusive_lock(fd)?;
|
||||
lock_file.unix_exclusive_lock(fd)?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -60,10 +60,19 @@ impl LockFile {
|
||||
/// Acquires an exclusive, non-blocking lock on Unix-like systems.
|
||||
#[cfg(unix)]
|
||||
fn unix_exclusive_lock(&self, fd: std::os::unix::io::RawFd) -> Result<()> {
|
||||
use libc::{flock, LOCK_EX, LOCK_NB};
|
||||
use libc::{fcntl, F_SETLK, F_WRLCK, SEEK_SET};
|
||||
|
||||
let ret = unsafe { flock(fd, LOCK_EX | LOCK_NB) };
|
||||
if ret != 0 {
|
||||
let lock = libc::flock {
|
||||
l_type: F_WRLCK as libc::c_short,
|
||||
l_whence: SEEK_SET as libc::c_short,
|
||||
l_start: 0,
|
||||
l_len: 0, // 0 means to lock the entire file
|
||||
l_pid: 0,
|
||||
};
|
||||
|
||||
let ret = unsafe { fcntl(fd, F_SETLK, &lock) };
|
||||
|
||||
if ret == -1 {
|
||||
let err = Error::last_os_error();
|
||||
Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
|
||||
Reference in New Issue
Block a user