rustix/io/
read_write.rs

1//! `read` and `write`, optionally positioned, optionally vectored
2
3use crate::{backend, io};
4use backend::fd::AsFd;
5
6// Declare `IoSlice` and `IoSliceMut`.
7#[cfg(not(windows))]
8pub use crate::maybe_polyfill::io::{IoSlice, IoSliceMut};
9
10#[cfg(linux_kernel)]
11pub use backend::io::types::ReadWriteFlags;
12
13/// `read(fd, buf)`—Reads from a stream.
14///
15/// # References
16///  - [POSIX]
17///  - [Linux]
18///  - [Apple]
19///  - [FreeBSD]
20///  - [NetBSD]
21///  - [OpenBSD]
22///  - [DragonFly BSD]
23///  - [illumos]
24///  - [glibc]
25///
26/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
27/// [Linux]: https://man7.org/linux/man-pages/man2/read.2.html
28/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/read.2.html
29/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=read&sektion=2
30/// [NetBSD]: https://man.netbsd.org/read.2
31/// [OpenBSD]: https://man.openbsd.org/read.2
32/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=read&section=2
33/// [illumos]: https://illumos.org/man/2/read
34/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/I_002fO-Primitives.html#index-reading-from-a-file-descriptor
35#[inline]
36pub fn read<Fd: AsFd>(fd: Fd, buf: &mut [u8]) -> io::Result<usize> {
37    backend::io::syscalls::read(fd.as_fd(), buf)
38}
39
40/// `write(fd, buf)`—Writes to a stream.
41///
42/// # References
43///  - [POSIX]
44///  - [Linux]
45///  - [Apple]
46///  - [FreeBSD]
47///  - [NetBSD]
48///  - [OpenBSD]
49///  - [DragonFly BSD]
50///  - [illumos]
51///  - [glibc]
52///
53/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
54/// [Linux]: https://man7.org/linux/man-pages/man2/write.2.html
55/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/write.2.html
56/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=write&sektion=2
57/// [NetBSD]: https://man.netbsd.org/write.2
58/// [OpenBSD]: https://man.openbsd.org/write.2
59/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=write&section=2
60/// [illumos]: https://illumos.org/man/2/write
61/// [glibc]: https://www.gnu.org/software/libc/manual/html_node/I_002fO-Primitives.html#index-writing-to-a-file-descriptor
62#[inline]
63pub fn write<Fd: AsFd>(fd: Fd, buf: &[u8]) -> io::Result<usize> {
64    backend::io::syscalls::write(fd.as_fd(), buf)
65}
66
67/// `pread(fd, buf, offset)`—Reads from a file at a given position.
68///
69/// # References
70///  - [POSIX]
71///  - [Linux]
72///  - [Apple]
73///  - [FreeBSD]
74///  - [NetBSD]
75///  - [OpenBSD]
76///  - [DragonFly BSD]
77///  - [illumos]
78///
79/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html
80/// [Linux]: https://man7.org/linux/man-pages/man2/pread.2.html
81/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pread.2.html
82/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pread&sektion=2
83/// [NetBSD]: https://man.netbsd.org/pread.2
84/// [OpenBSD]: https://man.openbsd.org/pread.2
85/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pread&section=2
86/// [illumos]: https://illumos.org/man/2/pread
87#[inline]
88pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: u64) -> io::Result<usize> {
89    backend::io::syscalls::pread(fd.as_fd(), buf, offset)
90}
91
92/// `pwrite(fd, bufs)`—Writes to a file at a given position.
93///
94/// Contrary to POSIX, on many popular platforms including Linux and FreeBSD,
95/// if the file is opened in append mode, this ignores the offset appends the
96/// data to the end of the file.
97///
98/// # References
99///  - [POSIX]
100///  - [Linux]
101///  - [Apple]
102///  - [FreeBSD]
103///  - [NetBSD]
104///  - [OpenBSD]
105///  - [DragonFly BSD]
106///  - [illumos]
107///
108/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html
109/// [Linux]: https://man7.org/linux/man-pages/man2/pwrite.2.html
110/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pwrite.2.html
111/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pwrite&sektion=2
112/// [NetBSD]: https://man.netbsd.org/pwrite.2
113/// [OpenBSD]: https://man.openbsd.org/pwrite.2
114/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pwrite&section=2
115/// [illumos]: https://illumos.org/man/2/pwrite
116#[inline]
117pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: u64) -> io::Result<usize> {
118    backend::io::syscalls::pwrite(fd.as_fd(), buf, offset)
119}
120
121/// `readv(fd, bufs)`—Reads from a stream into multiple buffers.
122///
123/// # References
124///  - [POSIX]
125///  - [Linux]
126///  - [Apple]
127///  - [FreeBSD]
128///  - [NetBSD]
129///  - [OpenBSD]
130///  - [DragonFly BSD]
131///  - [illumos]
132///
133/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html
134/// [Linux]: https://man7.org/linux/man-pages/man2/readv.2.html
135/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/readv.2.html
136/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=readv&sektion=2
137/// [NetBSD]: https://man.netbsd.org/readv.2
138/// [OpenBSD]: https://man.openbsd.org/readv.2
139/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=readv&section=2
140/// [illumos]: https://illumos.org/man/2/readv
141#[cfg(not(target_os = "espidf"))]
142#[inline]
143pub fn readv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
144    backend::io::syscalls::readv(fd.as_fd(), bufs)
145}
146
147/// `writev(fd, bufs)`—Writes to a stream from multiple buffers.
148///
149/// # References
150///  - [POSIX]
151///  - [Linux]
152///  - [Apple]
153///  - [FreeBSD]
154///  - [NetBSD]
155///  - [OpenBSD]
156///  - [DragonFly BSD]
157///  - [illumos]
158///
159/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html
160/// [Linux]: https://man7.org/linux/man-pages/man2/writev.2.html
161/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/writev.2.html
162/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=writev&sektion=2
163/// [NetBSD]: https://man.netbsd.org/writev.2
164/// [OpenBSD]: https://man.openbsd.org/writev.2
165/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=writev&section=2
166/// [illumos]: https://illumos.org/man/2/writev
167#[cfg(not(target_os = "espidf"))]
168#[inline]
169pub fn writev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
170    backend::io::syscalls::writev(fd.as_fd(), bufs)
171}
172
173/// `preadv(fd, bufs, offset)`—Reads from a file at a given position into
174/// multiple buffers.
175///
176/// # References
177///  - [Linux]
178///  - [FreeBSD]
179///  - [NetBSD]
180///  - [OpenBSD]
181///  - [DragonFly BSD]
182///  - [illumos]
183///
184/// [Linux]: https://man7.org/linux/man-pages/man2/preadv.2.html
185/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=preadv&sektion=2
186/// [NetBSD]: https://man.netbsd.org/preadv.2
187/// [OpenBSD]: https://man.openbsd.org/preadv.2
188/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=preadv&section=2
189/// [illumos]: https://illumos.org/man/2/preadv
190#[cfg(not(any(
191    target_os = "espidf",
192    target_os = "haiku",
193    target_os = "nto",
194    target_os = "redox",
195    target_os = "solaris",
196    target_os = "vita"
197)))]
198#[inline]
199pub fn preadv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
200    backend::io::syscalls::preadv(fd.as_fd(), bufs, offset)
201}
202
203/// `pwritev(fd, bufs, offset)`—Writes to a file at a given position from
204/// multiple buffers.
205///
206/// Contrary to POSIX, on many popular platforms including Linux and FreeBSD,
207/// if the file is opened in append mode, this ignores the offset appends the
208/// data to the end of the file.
209///
210/// # References
211///  - [Linux]
212///  - [FreeBSD]
213///  - [NetBSD]
214///  - [OpenBSD]
215///  - [DragonFly BSD]
216///  - [illumos]
217///
218/// [Linux]: https://man7.org/linux/man-pages/man2/pwritev.2.html
219/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=pwritev&sektion=2
220/// [NetBSD]: https://man.netbsd.org/pwritev.2
221/// [OpenBSD]: https://man.openbsd.org/pwritev.2
222/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=pwritev&section=2
223/// [illumos]: https://illumos.org/man/2/pwritev
224#[cfg(not(any(
225    target_os = "espidf",
226    target_os = "haiku",
227    target_os = "nto",
228    target_os = "redox",
229    target_os = "solaris",
230    target_os = "vita"
231)))]
232#[inline]
233pub fn pwritev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
234    backend::io::syscalls::pwritev(fd.as_fd(), bufs, offset)
235}
236
237/// `preadv2(fd, bufs, offset, flags)`—Reads data, with several options.
238///
239/// An `offset` of `u64::MAX` means to use and update the current file offset.
240///
241/// # References
242///  - [Linux]
243///
244/// [Linux]: https://man7.org/linux/man-pages/man2/preadv2.2.html
245#[cfg(linux_kernel)]
246#[inline]
247pub fn preadv2<Fd: AsFd>(
248    fd: Fd,
249    bufs: &mut [IoSliceMut<'_>],
250    offset: u64,
251    flags: ReadWriteFlags,
252) -> io::Result<usize> {
253    backend::io::syscalls::preadv2(fd.as_fd(), bufs, offset, flags)
254}
255
256/// `pwritev2(fd, bufs, offset, flags)`—Writes data, with several options.
257///
258/// An `offset` of `u64::MAX` means to use and update the current file offset.
259///
260/// # References
261///  - [Linux]
262///
263/// [Linux]: https://man7.org/linux/man-pages/man2/pwritev2.2.html
264#[cfg(linux_kernel)]
265#[inline]
266pub fn pwritev2<Fd: AsFd>(
267    fd: Fd,
268    bufs: &[IoSlice<'_>],
269    offset: u64,
270    flags: ReadWriteFlags,
271) -> io::Result<usize> {
272    backend::io::syscalls::pwritev2(fd.as_fd(), bufs, offset, flags)
273}