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))]
8#[cfg(not(feature = "std"))]
9pub use backend::io::io_slice::{IoSlice, IoSliceMut};
10#[cfg(not(windows))]
11#[cfg(feature = "std")]
12pub use std::io::{IoSlice, IoSliceMut};
13
14/// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`].
15#[cfg(any(target_os = "android", target_os = "linux"))]
16pub use backend::io::types::ReadWriteFlags;
17
18/// `read(fd, buf)`—Reads from a stream.
19///
20/// # References
21///  - [POSIX]
22///  - [Linux]
23///  - [Apple]
24///
25/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
26/// [Linux]: https://man7.org/linux/man-pages/man2/read.2.html
27/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/read.2.html
28#[inline]
29pub fn read<Fd: AsFd>(fd: Fd, buf: &mut [u8]) -> io::Result<usize> {
30    backend::io::syscalls::read(fd.as_fd(), buf)
31}
32
33/// `write(fd, buf)`—Writes to a stream.
34///
35/// # References
36///  - [POSIX]
37///  - [Linux]
38///  - [Apple]
39///
40/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
41/// [Linux]: https://man7.org/linux/man-pages/man2/write.2.html
42/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/write.2.html
43#[inline]
44pub fn write<Fd: AsFd>(fd: Fd, buf: &[u8]) -> io::Result<usize> {
45    backend::io::syscalls::write(fd.as_fd(), buf)
46}
47
48/// `pread(fd, buf, offset)`—Reads from a file at a given position.
49///
50/// # References
51///  - [POSIX]
52///  - [Linux]
53///  - [Apple]
54///
55/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html
56/// [Linux]: https://man7.org/linux/man-pages/man2/pread.2.html
57/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pread.2.html
58#[inline]
59pub fn pread<Fd: AsFd>(fd: Fd, buf: &mut [u8], offset: u64) -> io::Result<usize> {
60    backend::io::syscalls::pread(fd.as_fd(), buf, offset)
61}
62
63/// `pwrite(fd, bufs)`—Writes to a file at a given position.
64///
65/// Contrary to POSIX, on many popular platforms including Linux and FreeBSD,
66/// if the file is opened in append mode, this ignores the offset appends the
67/// data to the end of the file.
68///
69/// # References
70///  - [POSIX]
71///  - [Linux]
72///  - [Apple]
73///
74/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html
75/// [Linux]: https://man7.org/linux/man-pages/man2/pwrite.2.html
76/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pwrite.2.html
77#[inline]
78pub fn pwrite<Fd: AsFd>(fd: Fd, buf: &[u8], offset: u64) -> io::Result<usize> {
79    backend::io::syscalls::pwrite(fd.as_fd(), buf, offset)
80}
81
82/// `readv(fd, bufs)`—Reads from a stream into multiple buffers.
83///
84/// # References
85///  - [POSIX]
86///  - [Linux]
87///  - [Apple]
88///
89/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html
90/// [Linux]: https://man7.org/linux/man-pages/man2/readv.2.html
91/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/readv.2.html
92#[inline]
93pub fn readv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
94    backend::io::syscalls::readv(fd.as_fd(), bufs)
95}
96
97/// `writev(fd, bufs)`—Writes to a stream from multiple buffers.
98///
99/// # References
100///  - [POSIX]
101///  - [Linux]
102///  - [Apple]
103///
104/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html
105/// [Linux]: https://man7.org/linux/man-pages/man2/writev.2.html
106/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/writev.2.html
107#[inline]
108pub fn writev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
109    backend::io::syscalls::writev(fd.as_fd(), bufs)
110}
111
112/// `preadv(fd, bufs, offset)`—Reads from a file at a given position into
113/// multiple buffers.
114///
115/// # References
116///  - [Linux]
117///
118/// [Linux]: https://man7.org/linux/man-pages/man2/preadv.2.html
119#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))]
120#[inline]
121pub fn preadv<Fd: AsFd>(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
122    backend::io::syscalls::preadv(fd.as_fd(), bufs, offset)
123}
124
125/// `pwritev(fd, bufs, offset)`—Writes to a file at a given position from
126/// multiple buffers.
127///
128/// Contrary to POSIX, on many popular platforms including Linux and FreeBSD,
129/// if the file is opened in append mode, this ignores the offset appends the
130/// data to the end of the file.
131///
132/// # References
133///  - [Linux]
134///
135/// [Linux]: https://man7.org/linux/man-pages/man2/pwritev.2.html
136#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))]
137#[inline]
138pub fn pwritev<Fd: AsFd>(fd: Fd, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
139    backend::io::syscalls::pwritev(fd.as_fd(), bufs, offset)
140}
141
142/// `preadv2(fd, bufs, offset, flags)`—Reads data, with several options.
143///
144/// An `offset` of `u64::MAX` means to use and update the current file offset.
145///
146/// # References
147///  - [Linux]
148///
149/// [Linux]: https://man7.org/linux/man-pages/man2/preadv2.2.html
150#[cfg(any(target_os = "android", target_os = "linux"))]
151#[inline]
152pub fn preadv2<Fd: AsFd>(
153    fd: Fd,
154    bufs: &mut [IoSliceMut<'_>],
155    offset: u64,
156    flags: ReadWriteFlags,
157) -> io::Result<usize> {
158    backend::io::syscalls::preadv2(fd.as_fd(), bufs, offset, flags)
159}
160
161/// `pwritev2(fd, bufs, offset, flags)`—Writes data, with several options.
162///
163/// An `offset` of `u64::MAX` means to use and update the current file offset.
164///
165/// # References
166///  - [Linux]
167///
168/// [Linux]: https://man7.org/linux/man-pages/man2/pwritev2.2.html
169#[cfg(any(target_os = "android", target_os = "linux"))]
170#[inline]
171pub fn pwritev2<Fd: AsFd>(
172    fd: Fd,
173    bufs: &[IoSlice<'_>],
174    offset: u64,
175    flags: ReadWriteFlags,
176) -> io::Result<usize> {
177    backend::io::syscalls::pwritev2(fd.as_fd(), bufs, offset, flags)
178}
179