]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! Libc call arguments and return values are often things like `c_int`, |
2 | //! `c_uint`, or libc-specific pointer types. This module provides functions | |
3 | //! for converting between rustix's types and libc types. | |
4 | ||
064997fb | 5 | use super::c; |
781aab86 | 6 | #[cfg(all(feature = "alloc", not(any(windows, target_os = "espidf"))))] |
add651ee FG |
7 | use super::fd::IntoRawFd; |
8 | use super::fd::{AsRawFd, BorrowedFd, FromRawFd, LibcFd, OwnedFd, RawFd}; | |
064997fb | 9 | #[cfg(not(windows))] |
064997fb | 10 | use crate::ffi::CStr; |
487cf647 | 11 | use crate::io; |
064997fb FG |
12 | |
13 | #[cfg(not(windows))] | |
14 | #[inline] | |
15 | pub(super) fn c_str(c: &CStr) -> *const c::c_char { | |
16 | c.as_ptr() | |
17 | } | |
18 | ||
ed00b5ec | 19 | #[cfg(not(any(windows, target_os = "espidf", target_os = "vita", target_os = "wasi")))] |
064997fb FG |
20 | #[inline] |
21 | pub(super) fn no_fd() -> LibcFd { | |
22 | -1 | |
23 | } | |
24 | ||
25 | #[inline] | |
26 | pub(super) fn borrowed_fd(fd: BorrowedFd<'_>) -> LibcFd { | |
27 | fd.as_raw_fd() as LibcFd | |
28 | } | |
29 | ||
781aab86 FG |
30 | #[cfg(all( |
31 | feature = "alloc", | |
32 | not(any(windows, target_os = "espidf", target_os = "redox")) | |
33 | ))] | |
064997fb FG |
34 | #[inline] |
35 | pub(super) fn owned_fd(fd: OwnedFd) -> LibcFd { | |
36 | fd.into_raw_fd() as LibcFd | |
37 | } | |
38 | ||
39 | #[inline] | |
40 | pub(super) fn ret(raw: c::c_int) -> io::Result<()> { | |
41 | if raw == 0 { | |
42 | Ok(()) | |
43 | } else { | |
44 | Err(io::Errno::last_os_error()) | |
45 | } | |
46 | } | |
47 | ||
add651ee | 48 | #[cfg(apple)] |
064997fb FG |
49 | #[inline] |
50 | pub(super) fn nonnegative_ret(raw: c::c_int) -> io::Result<()> { | |
51 | if raw >= 0 { | |
52 | Ok(()) | |
53 | } else { | |
54 | Err(io::Errno::last_os_error()) | |
55 | } | |
56 | } | |
57 | ||
add651ee | 58 | #[cfg(not(any(windows, target_os = "wasi")))] |
064997fb FG |
59 | #[inline] |
60 | pub(super) unsafe fn ret_infallible(raw: c::c_int) { | |
61 | debug_assert_eq!(raw, 0, "unexpected error: {:?}", io::Errno::last_os_error()); | |
62 | } | |
63 | ||
64 | #[inline] | |
65 | pub(super) fn ret_c_int(raw: c::c_int) -> io::Result<c::c_int> { | |
66 | if raw == -1 { | |
67 | Err(io::Errno::last_os_error()) | |
68 | } else { | |
69 | Ok(raw) | |
70 | } | |
71 | } | |
72 | ||
add651ee | 73 | #[cfg(linux_kernel)] |
064997fb FG |
74 | #[inline] |
75 | pub(super) fn ret_u32(raw: c::c_int) -> io::Result<u32> { | |
76 | if raw == -1 { | |
77 | Err(io::Errno::last_os_error()) | |
78 | } else { | |
79 | Ok(raw as u32) | |
80 | } | |
81 | } | |
82 | ||
83 | #[inline] | |
49aad941 | 84 | pub(super) fn ret_usize(raw: c::ssize_t) -> io::Result<usize> { |
064997fb FG |
85 | if raw == -1 { |
86 | Err(io::Errno::last_os_error()) | |
87 | } else { | |
49aad941 FG |
88 | debug_assert!(raw >= 0); |
89 | Ok(raw as usize) | |
064997fb FG |
90 | } |
91 | } | |
92 | ||
064997fb | 93 | #[cfg(not(windows))] |
487cf647 | 94 | #[cfg(feature = "fs")] |
064997fb | 95 | #[inline] |
fe692bf9 | 96 | pub(super) fn ret_off_t(raw: c::off_t) -> io::Result<c::off_t> { |
064997fb FG |
97 | if raw == -1 { |
98 | Err(io::Errno::last_os_error()) | |
99 | } else { | |
100 | Ok(raw) | |
101 | } | |
102 | } | |
103 | ||
add651ee | 104 | #[cfg(not(any(windows, target_os = "wasi")))] |
064997fb FG |
105 | #[inline] |
106 | pub(super) fn ret_pid_t(raw: c::pid_t) -> io::Result<c::pid_t> { | |
107 | if raw == -1 { | |
108 | Err(io::Errno::last_os_error()) | |
109 | } else { | |
110 | Ok(raw) | |
111 | } | |
112 | } | |
113 | ||
114 | /// Convert a `c_int` returned from a libc function to an `OwnedFd`, if valid. | |
115 | /// | |
116 | /// # Safety | |
117 | /// | |
118 | /// The caller must ensure that this is the return value of a libc function | |
119 | /// which returns an owned file descriptor. | |
120 | #[inline] | |
121 | pub(super) unsafe fn ret_owned_fd(raw: LibcFd) -> io::Result<OwnedFd> { | |
122 | if raw == !0 { | |
123 | Err(io::Errno::last_os_error()) | |
124 | } else { | |
125 | Ok(OwnedFd::from_raw_fd(raw as RawFd)) | |
126 | } | |
127 | } | |
128 | ||
add651ee | 129 | #[cfg(not(any(windows, target_os = "wasi")))] |
064997fb FG |
130 | #[inline] |
131 | pub(super) fn ret_discarded_fd(raw: LibcFd) -> io::Result<()> { | |
132 | if raw == !0 { | |
133 | Err(io::Errno::last_os_error()) | |
134 | } else { | |
135 | Ok(()) | |
136 | } | |
137 | } | |
138 | ||
781aab86 | 139 | #[cfg(all(feature = "alloc", not(any(windows, target_os = "wasi"))))] |
064997fb FG |
140 | #[inline] |
141 | pub(super) fn ret_discarded_char_ptr(raw: *mut c::c_char) -> io::Result<()> { | |
142 | if raw.is_null() { | |
143 | Err(io::Errno::last_os_error()) | |
144 | } else { | |
145 | Ok(()) | |
146 | } | |
147 | } | |
148 | ||
064997fb | 149 | /// Convert the buffer-length argument value of a `send` or `recv` call. |
add651ee | 150 | #[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] |
064997fb FG |
151 | #[inline] |
152 | pub(super) fn send_recv_len(len: usize) -> usize { | |
153 | len | |
154 | } | |
155 | ||
156 | /// Convert the buffer-length argument value of a `send` or `recv` call. | |
157 | #[cfg(windows)] | |
158 | #[inline] | |
159 | pub(super) fn send_recv_len(len: usize) -> i32 { | |
160 | // On Windows, the length argument has type `i32`; saturate the length, | |
161 | // since `send` and `recv` are allowed to send and recv less data than | |
162 | // requested. | |
163 | len.try_into().unwrap_or(i32::MAX) | |
164 | } | |
165 | ||
166 | /// Convert the return value of a `send` or `recv` call. | |
add651ee | 167 | #[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] |
064997fb | 168 | #[inline] |
49aad941 FG |
169 | pub(super) fn ret_send_recv(len: isize) -> io::Result<usize> { |
170 | ret_usize(len) | |
064997fb FG |
171 | } |
172 | ||
173 | /// Convert the return value of a `send` or `recv` call. | |
174 | #[cfg(windows)] | |
175 | #[inline] | |
49aad941 FG |
176 | pub(super) fn ret_send_recv(len: i32) -> io::Result<usize> { |
177 | ret_usize(len as isize) | |
064997fb | 178 | } |
fe692bf9 FG |
179 | |
180 | /// Convert the value to the `msg_iovlen` field of a `msghdr` struct. | |
181 | #[cfg(all( | |
add651ee | 182 | not(any(windows, target_os = "espidf", target_os = "redox", target_os = "wasi")), |
fe692bf9 FG |
183 | any( |
184 | target_os = "android", | |
185 | all(target_os = "linux", not(target_env = "musl")) | |
186 | ) | |
187 | ))] | |
188 | #[inline] | |
189 | pub(super) fn msg_iov_len(len: usize) -> c::size_t { | |
190 | len | |
191 | } | |
192 | ||
193 | /// Convert the value to the `msg_iovlen` field of a `msghdr` struct. | |
194 | #[cfg(all( | |
ed00b5ec FG |
195 | not(any( |
196 | windows, | |
197 | target_os = "espidf", | |
198 | target_os = "redox", | |
199 | target_os = "vita", | |
200 | target_os = "wasi" | |
201 | )), | |
fe692bf9 FG |
202 | not(any( |
203 | target_os = "android", | |
204 | all(target_os = "linux", not(target_env = "musl")) | |
205 | )) | |
206 | ))] | |
207 | #[inline] | |
208 | pub(crate) fn msg_iov_len(len: usize) -> c::c_int { | |
209 | len.try_into().unwrap_or(c::c_int::MAX) | |
210 | } | |
211 | ||
212 | /// Convert the value to a `socklen_t`. | |
213 | #[cfg(any( | |
214 | bsd, | |
215 | solarish, | |
216 | target_env = "musl", | |
781aab86 | 217 | target_os = "aix", |
fe692bf9 | 218 | target_os = "emscripten", |
add651ee | 219 | target_os = "fuchsia", |
fe692bf9 | 220 | target_os = "haiku", |
add651ee | 221 | target_os = "nto", |
fe692bf9 FG |
222 | ))] |
223 | #[inline] | |
224 | pub(crate) fn msg_control_len(len: usize) -> c::socklen_t { | |
225 | len.try_into().unwrap_or(c::socklen_t::MAX) | |
226 | } | |
227 | ||
228 | /// Convert the value to a `size_t`. | |
229 | #[cfg(not(any( | |
230 | bsd, | |
231 | solarish, | |
add651ee | 232 | windows, |
fe692bf9 | 233 | target_env = "musl", |
781aab86 | 234 | target_os = "aix", |
fe692bf9 | 235 | target_os = "emscripten", |
add651ee | 236 | target_os = "espidf", |
fe692bf9 | 237 | target_os = "fuchsia", |
add651ee FG |
238 | target_os = "haiku", |
239 | target_os = "nto", | |
240 | target_os = "redox", | |
ed00b5ec | 241 | target_os = "vita", |
add651ee | 242 | target_os = "wasi", |
fe692bf9 FG |
243 | )))] |
244 | #[inline] | |
245 | pub(crate) fn msg_control_len(len: usize) -> c::size_t { | |
246 | len | |
247 | } |