Skip to content

Commit

Permalink
Emulate flock() on Solaris via fcntl()
Browse files Browse the repository at this point in the history
This should resolve problem with Rust build:
rust-lang/rust#103630
  • Loading branch information
psumbera committed Feb 24, 2023
1 parent 2f58d9f commit def0966
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 5 deletions.
33 changes: 32 additions & 1 deletion src/backend/libc/fs/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ use crate::fs::Advice;
target_os = "solaris",
)))]
use crate::fs::FallocateFlags;
#[cfg(not(any(target_os = "solaris", target_os = "wasi")))]
#[cfg(not(target_os = "wasi"))]
use crate::fs::FlockOperation;
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
use crate::fs::MemfdFlags;
Expand Down Expand Up @@ -968,6 +968,37 @@ pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result
unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) }
}

#[cfg(target_os = "solaris")]
pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> {
// Solaris lacks flock(), so try to emulate using fcntl()
let flag = operation as c::c_int;
let mut flock = c::flock {
l_type: 0,
l_whence: 0,
l_start: 0,
l_len: 0,
l_sysid: 0,
l_pid: 0,
l_pad: [0, 0, 0, 0],
};
flock.l_type = if flag & libc::LOCK_UN != 0 {
libc::F_UNLCK
} else if flag & libc::LOCK_EX != 0 {
libc::F_WRLCK
} else if flag & libc::LOCK_SH != 0 {
libc::F_RDLCK
} else {
panic!("unexpected flock() operation")
};

let mut cmd = libc::F_SETLKW;
if (flag & libc::LOCK_NB) != 0 {
cmd = libc::F_SETLK;
}

unsafe { ret(c::fcntl(borrowed_fd(fd), cmd, &flock)) }
}

pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> {
// 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use
// `statx`.
Expand Down
2 changes: 1 addition & 1 deletion src/backend/libc/fs/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ bitflags! {
/// `LOCK_*` constants for use with [`flock`]
///
/// [`flock`]: crate::fs::flock
#[cfg(not(any(target_os = "solaris", target_os = "wasi")))]
#[cfg(not(target_os = "wasi"))]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(i32)]
pub enum FlockOperation {
Expand Down
4 changes: 2 additions & 2 deletions src/fs/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::process::{Gid, Uid};
use crate::{backend, io};
use backend::fd::{AsFd, BorrowedFd};

#[cfg(not(any(target_os = "solaris", target_os = "wasi")))]
#[cfg(not(target_os = "wasi"))]
pub use backend::fs::types::FlockOperation;

#[cfg(not(any(
Expand Down Expand Up @@ -343,7 +343,7 @@ pub fn ftruncate<Fd: AsFd>(fd: Fd, length: u64) -> io::Result<()> {
/// - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man2/flock.2.html
#[cfg(not(any(target_os = "solaris", target_os = "wasi")))]
#[cfg(not(target_os = "wasi"))]
#[inline]
pub fn flock<Fd: AsFd>(fd: Fd, operation: FlockOperation) -> io::Result<()> {
backend::fs::syscalls::flock(fd.as_fd(), operation)
Expand Down
2 changes: 1 addition & 1 deletion src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ pub use fd::fdatasync;
pub use fd::{fallocate, FallocateFlags};
#[cfg(not(target_os = "wasi"))]
pub use fd::{fchmod, fchown};
#[cfg(not(any(target_os = "solaris", target_os = "wasi")))]
#[cfg(not(target_os = "wasi"))]
pub use fd::{flock, FlockOperation};
pub use fd::{fstat, fsync, ftruncate, futimens, is_file_read_write, seek, tell, Stat, Timestamps};
#[cfg(not(any(
Expand Down

0 comments on commit def0966

Please sign in to comment.