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