mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-30 06:43:20 +03:00
feat(std): emulate flock for solaris via fcntl
Upstream Solaris flock emulation to libstd from cargo. This is borrowed from https://github.com/rust-lang/cargo/blob/3b379fcc541b39321a7758552d37e5e0cc4277b9/src/cargo/util/flock.rs#L502-L536 which was implemented by an Oracle employee. The code has been in cargo since 2022-12. Python's `fcntl.flock` emulates like this as well: https://github.com/python/cpython/blob/c919d02edecfe9d75fe374756fb8aa1db8d95f55/Modules/fcntlmodule.c#L337-L400 We did the same thing in https://github.com/rust-lang/rust/blob/0d0f4eac8b98133e5da6d3604d86a8f3b5a67844/compiler/rustc_data_structures/src/flock/unix.rs#L13-L39
This commit is contained in:
@@ -226,6 +226,7 @@ fn file_test_io_seek_and_write() {
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
fn file_lock_multiple_shared() {
|
||||
@@ -249,6 +250,7 @@ fn file_lock_multiple_shared() {
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
fn file_lock_blocking() {
|
||||
@@ -273,6 +275,7 @@ fn file_lock_blocking() {
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
fn file_lock_drop() {
|
||||
@@ -294,6 +297,7 @@ fn file_lock_drop() {
|
||||
target_os = "freebsd",
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
))]
|
||||
fn file_lock_dup() {
|
||||
|
||||
@@ -1293,6 +1293,15 @@ pub fn lock(&self) -> io::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "solaris")]
|
||||
pub fn lock(&self) -> io::Result<()> {
|
||||
let mut flock: libc::flock = unsafe { mem::zeroed() };
|
||||
flock.l_type = libc::F_WRLCK as libc::c_short;
|
||||
flock.l_whence = libc::SEEK_SET as libc::c_short;
|
||||
cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLKW, &flock) })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@@ -1300,6 +1309,7 @@ pub fn lock(&self) -> io::Result<()> {
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "cygwin",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn lock(&self) -> io::Result<()> {
|
||||
@@ -1320,6 +1330,15 @@ pub fn lock_shared(&self) -> io::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "solaris")]
|
||||
pub fn lock_shared(&self) -> io::Result<()> {
|
||||
let mut flock: libc::flock = unsafe { mem::zeroed() };
|
||||
flock.l_type = libc::F_RDLCK as libc::c_short;
|
||||
flock.l_whence = libc::SEEK_SET as libc::c_short;
|
||||
cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLKW, &flock) })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@@ -1327,6 +1346,7 @@ pub fn lock_shared(&self) -> io::Result<()> {
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "cygwin",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn lock_shared(&self) -> io::Result<()> {
|
||||
@@ -1355,6 +1375,23 @@ pub fn try_lock(&self) -> Result<(), TryLockError> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "solaris")]
|
||||
pub fn try_lock(&self) -> Result<(), TryLockError> {
|
||||
let mut flock: libc::flock = unsafe { mem::zeroed() };
|
||||
flock.l_type = libc::F_WRLCK as libc::c_short;
|
||||
flock.l_whence = libc::SEEK_SET as libc::c_short;
|
||||
let result = cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLK, &flock) });
|
||||
if let Err(err) = result {
|
||||
if err.kind() == io::ErrorKind::WouldBlock {
|
||||
Err(TryLockError::WouldBlock)
|
||||
} else {
|
||||
Err(TryLockError::Error(err))
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@@ -1362,6 +1399,7 @@ pub fn try_lock(&self) -> Result<(), TryLockError> {
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "cygwin",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn try_lock(&self) -> Result<(), TryLockError> {
|
||||
@@ -1393,6 +1431,23 @@ pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "solaris")]
|
||||
pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
|
||||
let mut flock: libc::flock = unsafe { mem::zeroed() };
|
||||
flock.l_type = libc::F_RDLCK as libc::c_short;
|
||||
flock.l_whence = libc::SEEK_SET as libc::c_short;
|
||||
let result = cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLK, &flock) });
|
||||
if let Err(err) = result {
|
||||
if err.kind() == io::ErrorKind::WouldBlock {
|
||||
Err(TryLockError::WouldBlock)
|
||||
} else {
|
||||
Err(TryLockError::Error(err))
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@@ -1400,6 +1455,7 @@ pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "cygwin",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
|
||||
@@ -1423,6 +1479,15 @@ pub fn unlock(&self) -> io::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "solaris")]
|
||||
pub fn unlock(&self) -> io::Result<()> {
|
||||
let mut flock: libc::flock = unsafe { mem::zeroed() };
|
||||
flock.l_type = libc::F_UNLCK as libc::c_short;
|
||||
flock.l_whence = libc::SEEK_SET as libc::c_short;
|
||||
cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLKW, &flock) })?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "fuchsia",
|
||||
@@ -1430,6 +1495,7 @@ pub fn unlock(&self) -> io::Result<()> {
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "cygwin",
|
||||
target_os = "solaris",
|
||||
target_vendor = "apple",
|
||||
)))]
|
||||
pub fn unlock(&self) -> io::Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user