Skip to content

Commit

Permalink
Fix compilation error on Solaris due to flock usage
Browse files Browse the repository at this point in the history
PR 130999 added the file_lock feature, but libc does not define
flock() for the Solaris platform leading to a compilation error.

Additionally, I went through all the Tier 2 platforms and read through
their documentation to see whether flock was implemented. This turned up
5 more Unix platforms where flock is not supported, even though it may
exist in the libc crate.
  • Loading branch information
cberner committed Nov 13, 2024
1 parent 81eef2d commit 0df3ef4
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
28 changes: 28 additions & 0 deletions library/std/src/fs/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ fn file_test_io_seek_and_write() {
}

#[test]
#[cfg(any(
windows,
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
fn file_lock_multiple_shared() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_lock_multiple_shared_test.txt");
Expand All @@ -220,6 +227,13 @@ fn file_lock_multiple_shared() {
}

#[test]
#[cfg(any(
windows,
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
fn file_lock_blocking() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_lock_blocking_test.txt");
Expand All @@ -237,6 +251,13 @@ fn file_lock_blocking() {
}

#[test]
#[cfg(any(
windows,
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
fn file_lock_drop() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_lock_dup_test.txt");
Expand All @@ -251,6 +272,13 @@ fn file_lock_drop() {
}

#[test]
#[cfg(any(
windows,
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
fn file_lock_dup() {
let tmpdir = tmpdir();
let filename = &tmpdir.join("file_lock_dup_test.txt");
Expand Down
80 changes: 80 additions & 0 deletions library/std/src/sys/pal/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,16 +1254,54 @@ impl File {
}
}

#[cfg(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
pub fn lock(&self) -> io::Result<()> {
cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX) })?;
return Ok(());
}

#[cfg(not(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)))]
pub fn lock(&self) -> io::Result<()> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock() not supported"))
}

#[cfg(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
pub fn lock_shared(&self) -> io::Result<()> {
cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH) })?;
return Ok(());
}

#[cfg(not(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)))]
pub fn lock_shared(&self) -> io::Result<()> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "lock_shared() not supported"))
}

#[cfg(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
pub fn try_lock(&self) -> io::Result<bool> {
let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) });
if let Err(ref err) = result {
Expand All @@ -1275,6 +1313,22 @@ impl File {
return Ok(true);
}

#[cfg(not(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)))]
pub fn try_lock(&self) -> io::Result<bool> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock() not supported"))
}

#[cfg(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
pub fn try_lock_shared(&self) -> io::Result<bool> {
let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) });
if let Err(ref err) = result {
Expand All @@ -1286,11 +1340,37 @@ impl File {
return Ok(true);
}

#[cfg(not(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)))]
pub fn try_lock_shared(&self) -> io::Result<bool> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "try_lock_shared() not supported"))
}

#[cfg(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
pub fn unlock(&self) -> io::Result<()> {
cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_UN) })?;
return Ok(());
}

#[cfg(not(any(
target_os = "freebsd",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
)))]
pub fn unlock(&self) -> io::Result<()> {
Err(io::const_io_error!(io::ErrorKind::Unsupported, "unlock() not supported"))
}

pub fn truncate(&self, size: u64) -> io::Result<()> {
let size: off64_t =
size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
Expand Down

0 comments on commit 0df3ef4

Please sign in to comment.