diff options
| author | Weihang Lo <me@weihanglo.tw> | 2025-09-06 02:30:50 -0600 |
|---|---|---|
| committer | Weihang Lo <me@weihanglo.tw> | 2025-09-07 00:05:13 -0400 |
| commit | 01edb24d3ced043116a00bc45cc6c459b4ba9638 (patch) | |
| tree | 2dbe8f5a98be283209e3d1948f4b7fe259c99d8b /library/std/src | |
| parent | 0d0f4eac8b98133e5da6d3604d86a8f3b5a67844 (diff) | |
| download | rust-01edb24d3ced043116a00bc45cc6c459b4ba9638.tar.gz rust-01edb24d3ced043116a00bc45cc6c459b4ba9638.zip | |
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
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/fs/tests.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/fs/unix.rs | 66 |
2 files changed, 70 insertions, 0 deletions
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index f4431cedd18..f8dfb0d6334 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -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() { diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 3b525406223..dfd6ce56a76 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1293,6 +1293,15 @@ impl File { 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 @@ impl File { 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 @@ impl File { 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 @@ impl File { 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 @@ impl File { } } + #[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 @@ impl File { 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 @@ impl File { } } + #[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 @@ impl File { 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 @@ impl File { 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 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "cygwin", + target_os = "solaris", target_vendor = "apple", )))] pub fn unlock(&self) -> io::Result<()> { |
