1b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 2b8a62b91Sopenharmony_ciuse rustix::fs::Stat; 3b8a62b91Sopenharmony_ci 4b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 5b8a62b91Sopenharmony_cifn same(a: &Stat, b: &Stat) -> bool { 6b8a62b91Sopenharmony_ci a.st_ino == b.st_ino && a.st_dev == b.st_dev 7b8a62b91Sopenharmony_ci} 8b8a62b91Sopenharmony_ci 9b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 10b8a62b91Sopenharmony_ci#[test] 11b8a62b91Sopenharmony_cifn test_renameat() { 12b8a62b91Sopenharmony_ci use rustix::fs::{cwd, openat, renameat, statat, AtFlags, Mode, OFlags}; 13b8a62b91Sopenharmony_ci 14b8a62b91Sopenharmony_ci let tmp = tempfile::tempdir().unwrap(); 15b8a62b91Sopenharmony_ci let dir = openat( 16b8a62b91Sopenharmony_ci cwd(), 17b8a62b91Sopenharmony_ci tmp.path(), 18b8a62b91Sopenharmony_ci OFlags::RDONLY | OFlags::PATH, 19b8a62b91Sopenharmony_ci Mode::empty(), 20b8a62b91Sopenharmony_ci ) 21b8a62b91Sopenharmony_ci .unwrap(); 22b8a62b91Sopenharmony_ci 23b8a62b91Sopenharmony_ci let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); 24b8a62b91Sopenharmony_ci let before = statat(&dir, "foo", AtFlags::empty()).unwrap(); 25b8a62b91Sopenharmony_ci renameat(&dir, "foo", &dir, "bar").unwrap(); 26b8a62b91Sopenharmony_ci let renamed = statat(&dir, "bar", AtFlags::empty()).unwrap(); 27b8a62b91Sopenharmony_ci assert!(same(&before, &renamed)); 28b8a62b91Sopenharmony_ci} 29b8a62b91Sopenharmony_ci 30b8a62b91Sopenharmony_ci/// Like `test_renameat` but the file already exists, so `renameat` 31b8a62b91Sopenharmony_ci/// overwrites it. 32b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 33b8a62b91Sopenharmony_ci#[test] 34b8a62b91Sopenharmony_cifn test_renameat_overwrite() { 35b8a62b91Sopenharmony_ci use rustix::fs::{cwd, openat, renameat, statat, AtFlags, Mode, OFlags}; 36b8a62b91Sopenharmony_ci 37b8a62b91Sopenharmony_ci let tmp = tempfile::tempdir().unwrap(); 38b8a62b91Sopenharmony_ci let dir = openat( 39b8a62b91Sopenharmony_ci cwd(), 40b8a62b91Sopenharmony_ci tmp.path(), 41b8a62b91Sopenharmony_ci OFlags::RDONLY | OFlags::PATH, 42b8a62b91Sopenharmony_ci Mode::empty(), 43b8a62b91Sopenharmony_ci ) 44b8a62b91Sopenharmony_ci .unwrap(); 45b8a62b91Sopenharmony_ci 46b8a62b91Sopenharmony_ci let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); 47b8a62b91Sopenharmony_ci let _ = openat(&dir, "bar", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); 48b8a62b91Sopenharmony_ci let before = statat(&dir, "foo", AtFlags::empty()).unwrap(); 49b8a62b91Sopenharmony_ci renameat(&dir, "foo", &dir, "bar").unwrap(); 50b8a62b91Sopenharmony_ci let renamed = statat(&dir, "bar", AtFlags::empty()).unwrap(); 51b8a62b91Sopenharmony_ci assert!(same(&before, &renamed)); 52b8a62b91Sopenharmony_ci} 53b8a62b91Sopenharmony_ci 54b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))] 55b8a62b91Sopenharmony_ci#[test] 56b8a62b91Sopenharmony_cifn test_renameat_with() { 57b8a62b91Sopenharmony_ci use rustix::fs::{cwd, openat, renameat_with, statat, AtFlags, Mode, OFlags, RenameFlags}; 58b8a62b91Sopenharmony_ci 59b8a62b91Sopenharmony_ci let tmp = tempfile::tempdir().unwrap(); 60b8a62b91Sopenharmony_ci let dir = openat( 61b8a62b91Sopenharmony_ci cwd(), 62b8a62b91Sopenharmony_ci tmp.path(), 63b8a62b91Sopenharmony_ci OFlags::RDONLY | OFlags::PATH, 64b8a62b91Sopenharmony_ci Mode::empty(), 65b8a62b91Sopenharmony_ci ) 66b8a62b91Sopenharmony_ci .unwrap(); 67b8a62b91Sopenharmony_ci 68b8a62b91Sopenharmony_ci let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); 69b8a62b91Sopenharmony_ci let before = statat(&dir, "foo", AtFlags::empty()).unwrap(); 70b8a62b91Sopenharmony_ci 71b8a62b91Sopenharmony_ci match renameat_with(&dir, "foo", &dir, "red", RenameFlags::empty()) { 72b8a62b91Sopenharmony_ci Ok(()) => (), 73b8a62b91Sopenharmony_ci Err(err) if err == rustix::io::Errno::NOSYS => return, 74b8a62b91Sopenharmony_ci Err(err) => unreachable!("unexpected error from renameat_with: {:?}", err), 75b8a62b91Sopenharmony_ci } 76b8a62b91Sopenharmony_ci 77b8a62b91Sopenharmony_ci let renamed = statat(&dir, "red", AtFlags::empty()).unwrap(); 78b8a62b91Sopenharmony_ci assert!(same(&before, &renamed)); 79b8a62b91Sopenharmony_ci 80b8a62b91Sopenharmony_ci let _ = openat( 81b8a62b91Sopenharmony_ci &dir, 82b8a62b91Sopenharmony_ci "green", 83b8a62b91Sopenharmony_ci OFlags::CREATE | OFlags::WRONLY, 84b8a62b91Sopenharmony_ci Mode::empty(), 85b8a62b91Sopenharmony_ci ) 86b8a62b91Sopenharmony_ci .unwrap(); 87b8a62b91Sopenharmony_ci 88b8a62b91Sopenharmony_ci #[cfg(all(target_os = "linux", target_env = "gnu"))] 89b8a62b91Sopenharmony_ci { 90b8a62b91Sopenharmony_ci let green = statat(&dir, "green", AtFlags::empty()).unwrap(); 91b8a62b91Sopenharmony_ci 92b8a62b91Sopenharmony_ci renameat_with(&dir, "red", &dir, "green", RenameFlags::NOREPLACE).unwrap_err(); 93b8a62b91Sopenharmony_ci let renamed = statat(&dir, "red", AtFlags::empty()).unwrap(); 94b8a62b91Sopenharmony_ci assert!(same(&before, &renamed)); 95b8a62b91Sopenharmony_ci let orig = statat(&dir, "green", AtFlags::empty()).unwrap(); 96b8a62b91Sopenharmony_ci assert!(same(&green, &orig)); 97b8a62b91Sopenharmony_ci 98b8a62b91Sopenharmony_ci renameat_with(&dir, "red", &dir, "green", RenameFlags::EXCHANGE).unwrap(); 99b8a62b91Sopenharmony_ci let renamed = statat(&dir, "red", AtFlags::empty()).unwrap(); 100b8a62b91Sopenharmony_ci assert!(same(&green, &renamed)); 101b8a62b91Sopenharmony_ci let orig = statat(&dir, "green", AtFlags::empty()).unwrap(); 102b8a62b91Sopenharmony_ci assert!(same(&before, &orig)); 103b8a62b91Sopenharmony_ci } 104b8a62b91Sopenharmony_ci} 105