• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[cfg(feature = "fs")]
2 use std::io::{IoSlice, IoSliceMut};
3 
4 #[cfg(feature = "fs")]
5 #[cfg(not(target_os = "solaris"))] // no preadv/pwritev
6 #[cfg(not(target_os = "haiku"))] // no preadv/pwritev
7 #[test]
test_readwrite_pv()8 fn test_readwrite_pv() {
9     use rustix::fs::{cwd, openat, Mode, OFlags};
10     use rustix::io::{preadv, pwritev};
11 
12     let tmp = tempfile::tempdir().unwrap();
13     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
14     let foo = openat(
15         &dir,
16         "foo",
17         OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC,
18         Mode::RUSR | Mode::WUSR,
19     )
20     .unwrap();
21 
22     // For most targets, just call `pwritev`.
23     #[cfg(not(any(target_os = "ios", target_os = "macos")))]
24     {
25         pwritev(&foo, &[IoSlice::new(b"hello")], 200).unwrap();
26     }
27     // macOS only has pwritev in newer versions; allow it to fail with `ENOSYS`.
28     #[cfg(any(target_os = "ios", target_os = "macos"))]
29     {
30         match pwritev(&foo, &[IoSlice::new(b"hello")], 200) {
31             Ok(_) => (),
32             Err(rustix::io::Errno::NOSYS) => return,
33             Err(err) => Err(err).unwrap(),
34         }
35     }
36     pwritev(&foo, &[IoSlice::new(b"world")], 300).unwrap();
37     let mut buf = [0_u8; 5];
38     preadv(&foo, &mut [IoSliceMut::new(&mut buf)], 200).unwrap();
39     assert_eq!(&buf, b"hello");
40     preadv(&foo, &mut [IoSliceMut::new(&mut buf)], 300).unwrap();
41     assert_eq!(&buf, b"world");
42 }
43 
44 #[cfg(feature = "fs")]
45 #[test]
test_readwrite_p()46 fn test_readwrite_p() {
47     use rustix::fs::{cwd, openat, Mode, OFlags};
48     use rustix::io::{pread, pwrite};
49 
50     let tmp = tempfile::tempdir().unwrap();
51     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
52     let foo = openat(
53         &dir,
54         "foo",
55         OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC,
56         Mode::RUSR | Mode::WUSR,
57     )
58     .unwrap();
59 
60     pwrite(&foo, b"hello", 200).unwrap();
61     pwrite(&foo, b"world", 300).unwrap();
62     let mut buf = [0_u8; 5];
63     pread(&foo, &mut buf, 200).unwrap();
64     assert_eq!(&buf, b"hello");
65     pread(&foo, &mut buf, 300).unwrap();
66     assert_eq!(&buf, b"world");
67 }
68 
69 #[cfg(feature = "fs")]
70 #[test]
test_readwrite_v()71 fn test_readwrite_v() {
72     use rustix::fs::{cwd, openat, seek, Mode, OFlags};
73     use rustix::io::{readv, writev, SeekFrom};
74 
75     let tmp = tempfile::tempdir().unwrap();
76     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
77     let foo = openat(
78         &dir,
79         "foo",
80         OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC,
81         Mode::RUSR | Mode::WUSR,
82     )
83     .unwrap();
84 
85     writev(&foo, &[IoSlice::new(b"hello")]).unwrap();
86     writev(&foo, &[IoSlice::new(b"world")]).unwrap();
87     seek(&foo, SeekFrom::Start(0)).unwrap();
88     let mut buf = [0_u8; 5];
89     readv(&foo, &mut [IoSliceMut::new(&mut buf)]).unwrap();
90     assert_eq!(&buf, b"hello");
91     readv(&foo, &mut [IoSliceMut::new(&mut buf)]).unwrap();
92     assert_eq!(&buf, b"world");
93 }
94 
95 #[cfg(feature = "fs")]
96 #[test]
test_readwrite()97 fn test_readwrite() {
98     use rustix::fs::{cwd, openat, seek, Mode, OFlags};
99     use rustix::io::{read, write};
100     use std::io::SeekFrom;
101 
102     let tmp = tempfile::tempdir().unwrap();
103     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
104     let foo = openat(
105         &dir,
106         "foo",
107         OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC,
108         Mode::RUSR | Mode::WUSR,
109     )
110     .unwrap();
111 
112     write(&foo, b"hello").unwrap();
113     write(&foo, b"world").unwrap();
114     seek(&foo, SeekFrom::Start(0)).unwrap();
115     let mut buf = [0_u8; 5];
116     read(&foo, &mut buf).unwrap();
117     assert_eq!(&buf, b"hello");
118     read(&foo, &mut buf).unwrap();
119     assert_eq!(&buf, b"world");
120 }
121 
122 #[cfg(all(target_os = "linux", target_env = "gnu"))]
123 #[test]
test_rwf_values()124 fn test_rwf_values() {
125     // We use the kernel's values for these flags; check that libc doesn't
126     // have different values.
127     assert_eq!(
128         rustix::io::ReadWriteFlags::APPEND.bits() as i32,
129         libc::RWF_APPEND
130     );
131     assert_eq!(
132         rustix::io::ReadWriteFlags::DSYNC.bits() as i32,
133         libc::RWF_DSYNC
134     );
135     assert_eq!(
136         rustix::io::ReadWriteFlags::HIPRI.bits() as i32,
137         libc::RWF_HIPRI
138     );
139     assert_eq!(
140         rustix::io::ReadWriteFlags::NOWAIT.bits() as i32,
141         libc::RWF_NOWAIT
142     );
143     assert_eq!(
144         rustix::io::ReadWriteFlags::SYNC.bits() as i32,
145         libc::RWF_SYNC
146     );
147 }
148 
149 #[cfg(any(target_os = "android", target_os = "linux"))]
150 #[cfg(feature = "fs")]
151 #[test]
test_pwritev2()152 fn test_pwritev2() {
153     use rustix::fs::{cwd, openat, seek, Mode, OFlags};
154     use rustix::io::{preadv2, pwritev2, writev, ReadWriteFlags, SeekFrom};
155 
156     let tmp = tempfile::tempdir().unwrap();
157     let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap();
158     let foo = openat(
159         &dir,
160         "foo",
161         OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC,
162         Mode::RUSR | Mode::WUSR,
163     )
164     .unwrap();
165 
166     writev(&foo, &[IoSlice::new(b"hello")]).unwrap();
167     seek(&foo, SeekFrom::Start(0)).unwrap();
168 
169     // pwritev2 to append with a 0 offset: don't update the current position.
170     match pwritev2(&foo, &[IoSlice::new(b"world")], 0, ReadWriteFlags::APPEND) {
171         Ok(_) => {}
172         // Skip the rest of the test if we don't have `pwritev2` and `RWF_APPEND`.
173         Err(rustix::io::Errno::NOSYS) | Err(rustix::io::Errno::NOTSUP) => return,
174         Err(err) => Err(err).unwrap(),
175     }
176     assert_eq!(seek(&foo, SeekFrom::Current(0)).unwrap(), 0);
177 
178     // pwritev2 to append with a !0 offset: do update the current position.
179     pwritev2(&foo, &[IoSlice::new(b"world")], !0, ReadWriteFlags::APPEND).unwrap();
180     assert_eq!(seek(&foo, SeekFrom::Current(0)).unwrap(), 15);
181 
182     seek(&foo, SeekFrom::Start(0)).unwrap();
183     let mut buf = [0_u8; 5];
184     preadv2(
185         &foo,
186         &mut [IoSliceMut::new(&mut buf)],
187         0,
188         ReadWriteFlags::empty(),
189     )
190     .unwrap();
191     assert_eq!(&buf, b"hello");
192     preadv2(
193         &foo,
194         &mut [IoSliceMut::new(&mut buf)],
195         5,
196         ReadWriteFlags::empty(),
197     )
198     .unwrap();
199     assert_eq!(&buf, b"world");
200 }
201