about summary refs log tree commit diff
path: root/compiler/rustc_data_structures/src/flock/unix.rs
diff options
context:
space:
mode:
authorAndy Russell <arussell123@gmail.com>2022-04-14 18:29:21 -0400
committerAndy Russell <arussell123@gmail.com>2022-04-14 18:30:53 -0400
commit219d81f19bd902e280fe6f5f40aded185db7ba0a (patch)
tree5c7d6c52ea1ea52d90a378df9bfe117ac6e9e55d /compiler/rustc_data_structures/src/flock/unix.rs
parente7575f9670f3c837def3d186ae09366c75c7632e (diff)
downloadrust-219d81f19bd902e280fe6f5f40aded185db7ba0a.tar.gz
rust-219d81f19bd902e280fe6f5f40aded185db7ba0a.zip
separate flock implementations into separate modules
Diffstat (limited to 'compiler/rustc_data_structures/src/flock/unix.rs')
-rw-r--r--compiler/rustc_data_structures/src/flock/unix.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/rustc_data_structures/src/flock/unix.rs b/compiler/rustc_data_structures/src/flock/unix.rs
new file mode 100644
index 00000000000..4e5297d582e
--- /dev/null
+++ b/compiler/rustc_data_structures/src/flock/unix.rs
@@ -0,0 +1,51 @@
+use std::fs::{File, OpenOptions};
+use std::io;
+use std::mem;
+use std::os::unix::prelude::*;
+use std::path::Path;
+
+#[derive(Debug)]
+pub struct Lock {
+    file: File,
+}
+
+impl Lock {
+    pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result<Lock> {
+        let file = OpenOptions::new()
+            .read(true)
+            .write(true)
+            .create(create)
+            .mode(libc::S_IRWXU as u32)
+            .open(p)?;
+
+        let lock_type = if exclusive { libc::F_WRLCK } else { libc::F_RDLCK };
+
+        let mut flock: libc::flock = unsafe { mem::zeroed() };
+        flock.l_type = lock_type as libc::c_short;
+        flock.l_whence = libc::SEEK_SET as libc::c_short;
+        flock.l_start = 0;
+        flock.l_len = 0;
+
+        let cmd = if wait { libc::F_SETLKW } else { libc::F_SETLK };
+        let ret = unsafe { libc::fcntl(file.as_raw_fd(), cmd, &flock) };
+        if ret == -1 { Err(io::Error::last_os_error()) } else { Ok(Lock { file }) }
+    }
+
+    pub fn error_unsupported(err: &io::Error) -> bool {
+        matches!(err.raw_os_error(), Some(libc::ENOTSUP) | Some(libc::ENOSYS))
+    }
+}
+
+impl Drop for Lock {
+    fn drop(&mut self) {
+        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;
+        flock.l_start = 0;
+        flock.l_len = 0;
+
+        unsafe {
+            libc::fcntl(self.file.as_raw_fd(), libc::F_SETLK, &flock);
+        }
+    }
+}