//@ignore-target: windows # File handling is not implemented yet //@ignore-target: solaris # Does not have flock //@compile-flags: -Zmiri-disable-isolation use std::fs::File; use std::io::Error; use std::os::fd::AsRawFd; #[path = "../../utils/mod.rs"] mod utils; fn main() { let bytes = b"Hello, World!\n"; let path = utils::prepare_with_content("miri_test_fs_shared_lock.txt", bytes); let files: Vec = (0..3).map(|_| File::open(&path).unwrap()).collect(); // Test that we can apply many shared locks for file in files.iter() { let fd = file.as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_SH) }; if ret != 0 { panic!("flock error: {}", Error::last_os_error()); } } // Test that shared lock prevents exclusive lock { let fd = files[0].as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) }; assert_eq!(ret, -1); let err = Error::last_os_error().raw_os_error().unwrap(); assert_eq!(err, libc::EWOULDBLOCK); } // Unlock shared lock for file in files.iter() { let fd = file.as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_UN) }; if ret != 0 { panic!("flock error: {}", Error::last_os_error()); } } // Take exclusive lock { let fd = files[0].as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_EX) }; assert_eq!(ret, 0); } // Test that shared lock prevents exclusive and shared locks { let fd = files[1].as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB) }; assert_eq!(ret, -1); let err = Error::last_os_error().raw_os_error().unwrap(); assert_eq!(err, libc::EWOULDBLOCK); let fd = files[2].as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_SH | libc::LOCK_NB) }; assert_eq!(ret, -1); let err = Error::last_os_error().raw_os_error().unwrap(); assert_eq!(err, libc::EWOULDBLOCK); } // Unlock exclusive lock { let fd = files[0].as_raw_fd(); let ret = unsafe { libc::flock(fd, libc::LOCK_UN) }; assert_eq!(ret, 0); } }