1 //! Automatically enable “large file” support features.
2
3 #[cfg(not(windows))]
4 use super::c;
5
6 #[cfg(not(any(
7 windows,
8 target_os = "android",
9 target_os = "emscripten",
10 target_os = "l4re",
11 target_os = "linux",
12 )))]
13 #[cfg(feature = "fs")]
14 pub(super) use c::{
15 fstat as libc_fstat, fstatat as libc_fstatat, ftruncate as libc_ftruncate, lseek as libc_lseek,
16 off_t as libc_off_t,
17 };
18
19 #[cfg(any(
20 target_os = "android",
21 target_os = "emscripten",
22 target_os = "l4re",
23 target_os = "linux",
24 ))]
25 #[cfg(feature = "fs")]
26 pub(super) use c::{
27 fstat64 as libc_fstat, fstatat64 as libc_fstatat, ftruncate64 as libc_ftruncate,
28 lseek64 as libc_lseek, off64_t as libc_off_t,
29 };
30
31 #[cfg(any(
32 target_os = "android",
33 target_os = "emscripten",
34 target_os = "l4re",
35 target_os = "linux",
36 ))]
37 pub(super) use c::rlimit64 as libc_rlimit;
38
39 #[cfg(not(any(
40 windows,
41 target_os = "android",
42 target_os = "emscripten",
43 target_os = "l4re",
44 target_os = "linux",
45 target_os = "wasi",
46 )))]
47 #[cfg(feature = "mm")]
48 pub(super) use c::mmap as libc_mmap;
49
50 #[cfg(not(any(
51 windows,
52 target_os = "android",
53 target_os = "emscripten",
54 target_os = "fuchsia",
55 target_os = "l4re",
56 target_os = "linux",
57 target_os = "redox",
58 target_os = "wasi",
59 )))]
60 pub(super) use c::{rlimit as libc_rlimit, RLIM_INFINITY as LIBC_RLIM_INFINITY};
61
62 #[cfg(not(any(
63 windows,
64 target_os = "android",
65 target_os = "fuchsia",
66 target_os = "emscripten",
67 target_os = "l4re",
68 target_os = "linux",
69 target_os = "wasi",
70 )))]
71 pub(super) use c::{getrlimit as libc_getrlimit, setrlimit as libc_setrlimit};
72
73 // TODO: Add `RLIM64_INFINITY` to upstream libc.
74 #[cfg(any(
75 target_os = "android",
76 target_os = "linux",
77 target_os = "emscripten",
78 target_os = "l4re",
79 ))]
80 pub(super) const LIBC_RLIM_INFINITY: u64 = !0_u64;
81
82 #[cfg(any(
83 target_os = "android",
84 target_os = "linux",
85 target_os = "emscripten",
86 target_os = "l4re",
87 ))]
88 pub(super) use c::{getrlimit64 as libc_getrlimit, setrlimit64 as libc_setrlimit};
89
90 #[cfg(any(
91 target_os = "android",
92 target_os = "linux",
93 target_os = "emscripten",
94 target_os = "l4re",
95 ))]
96 #[cfg(feature = "mm")]
97 pub(super) use c::mmap64 as libc_mmap;
98
99 // `prlimit64` wasn't supported in glibc until 2.13.
100 #[cfg(all(target_os = "linux", target_env = "gnu"))]
101 weak_or_syscall! {
102 fn prlimit64(
103 pid: c::pid_t,
104 resource: c::__rlimit_resource_t,
105 new_limit: *const c::rlimit64,
106 old_limit: *mut c::rlimit64
107 ) via SYS_prlimit64 -> c::c_int
108 }
109 #[cfg(all(target_os = "linux", target_env = "musl"))]
110 weak_or_syscall! {
111 fn prlimit64(
112 pid: c::pid_t,
113 resource: c::c_int,
114 new_limit: *const c::rlimit64,
115 old_limit: *mut c::rlimit64
116 ) via SYS_prlimit64 -> c::c_int
117 }
118 #[cfg(target_os = "android")]
119 weak_or_syscall! {
120 fn prlimit64(
121 pid: c::pid_t,
122 resource: c::c_int,
123 new_limit: *const c::rlimit64,
124 old_limit: *mut c::rlimit64
125 ) via SYS_prlimit64 -> c::c_int
126 }
127 #[cfg(all(target_os = "linux", target_env = "gnu"))]
libc_prlimit( pid: c::pid_t, resource: c::__rlimit_resource_t, new_limit: *const c::rlimit64, old_limit: *mut c::rlimit64, ) -> c::c_int128 pub(super) unsafe fn libc_prlimit(
129 pid: c::pid_t,
130 resource: c::__rlimit_resource_t,
131 new_limit: *const c::rlimit64,
132 old_limit: *mut c::rlimit64,
133 ) -> c::c_int {
134 prlimit64(pid, resource, new_limit, old_limit)
135 }
136 #[cfg(all(target_os = "linux", target_env = "musl"))]
libc_prlimit( pid: c::pid_t, resource: c::c_int, new_limit: *const c::rlimit64, old_limit: *mut c::rlimit64, ) -> c::c_int137 pub(super) unsafe fn libc_prlimit(
138 pid: c::pid_t,
139 resource: c::c_int,
140 new_limit: *const c::rlimit64,
141 old_limit: *mut c::rlimit64,
142 ) -> c::c_int {
143 prlimit64(pid, resource, new_limit, old_limit)
144 }
145 #[cfg(target_os = "android")]
libc_prlimit( pid: c::pid_t, resource: c::c_int, new_limit: *const c::rlimit64, old_limit: *mut c::rlimit64, ) -> c::c_int146 pub(super) unsafe fn libc_prlimit(
147 pid: c::pid_t,
148 resource: c::c_int,
149 new_limit: *const c::rlimit64,
150 old_limit: *mut c::rlimit64,
151 ) -> c::c_int {
152 prlimit64(pid, resource, new_limit, old_limit)
153 }
154
155 #[cfg(not(any(
156 windows,
157 target_os = "android",
158 target_os = "linux",
159 target_os = "emscripten",
160 target_os = "l4re",
161 target_os = "redox",
162 )))]
163 #[cfg(feature = "fs")]
164 pub(super) use c::openat as libc_openat;
165 #[cfg(any(
166 target_os = "android",
167 target_os = "linux",
168 target_os = "emscripten",
169 target_os = "l4re",
170 ))]
171 #[cfg(feature = "fs")]
172 pub(super) use c::openat64 as libc_openat;
173
174 #[cfg(target_os = "fuchsia")]
175 #[cfg(feature = "fs")]
176 pub(super) use c::fallocate as libc_fallocate;
177 #[cfg(any(target_os = "android", target_os = "linux"))]
178 #[cfg(feature = "fs")]
179 pub(super) use c::fallocate64 as libc_fallocate;
180 #[cfg(not(any(
181 windows,
182 target_os = "android",
183 target_os = "dragonfly",
184 target_os = "emscripten",
185 target_os = "haiku",
186 target_os = "illumos",
187 target_os = "ios",
188 target_os = "linux",
189 target_os = "l4re",
190 target_os = "macos",
191 target_os = "netbsd",
192 target_os = "openbsd",
193 target_os = "redox",
194 target_os = "solaris",
195 )))]
196 #[cfg(feature = "fs")]
197 pub(super) use c::posix_fadvise as libc_posix_fadvise;
198 #[cfg(any(
199 target_os = "android",
200 target_os = "emscripten",
201 target_os = "linux",
202 target_os = "l4re",
203 ))]
204 #[cfg(feature = "fs")]
205 pub(super) use c::posix_fadvise64 as libc_posix_fadvise;
206
207 #[cfg(all(not(any(
208 windows,
209 target_os = "android",
210 target_os = "linux",
211 target_os = "emscripten",
212 ))))]
213 pub(super) use c::{pread as libc_pread, pwrite as libc_pwrite};
214 #[cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten"))]
215 pub(super) use c::{pread64 as libc_pread, pwrite64 as libc_pwrite};
216 #[cfg(any(target_os = "linux", target_os = "emscripten"))]
217 pub(super) use c::{preadv64 as libc_preadv, pwritev64 as libc_pwritev};
218 #[cfg(target_os = "android")]
219 mod readwrite_pv64 {
220 use super::c;
221
222 // 64-bit offsets on 32-bit platforms are passed in endianness-specific
223 // lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
224 #[cfg(all(target_endian = "little", target_pointer_width = "32"))]
lo(x: u64) -> usize225 fn lo(x: u64) -> usize {
226 (x >> 32) as usize
227 }
228 #[cfg(all(target_endian = "little", target_pointer_width = "32"))]
hi(x: u64) -> usize229 fn hi(x: u64) -> usize {
230 (x & 0xffff_ffff) as usize
231 }
232 #[cfg(all(target_endian = "big", target_pointer_width = "32"))]
lo(x: u64) -> usize233 fn lo(x: u64) -> usize {
234 (x & 0xffff_ffff) as usize
235 }
236 #[cfg(all(target_endian = "big", target_pointer_width = "32"))]
hi(x: u64) -> usize237 fn hi(x: u64) -> usize {
238 (x >> 32) as usize
239 }
240
preadv64( fd: c::c_int, iov: *const c::iovec, iovcnt: c::c_int, offset: c::off64_t, ) -> c::ssize_t241 pub(in super::super) unsafe fn preadv64(
242 fd: c::c_int,
243 iov: *const c::iovec,
244 iovcnt: c::c_int,
245 offset: c::off64_t,
246 ) -> c::ssize_t {
247 // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to
248 // test for it, and call back to `c::syscall`. We don't use
249 // `weak_or_syscall` here because we need to pass the 64-bit offset
250 // specially.
251 weak! {
252 fn preadv64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t
253 }
254 if let Some(fun) = preadv64.get() {
255 fun(fd, iov, iovcnt, offset)
256 } else {
257 #[cfg(target_pointer_width = "32")]
258 {
259 c::syscall(
260 c::SYS_preadv,
261 fd,
262 iov,
263 iovcnt,
264 hi(offset as u64),
265 lo(offset as u64),
266 ) as c::ssize_t
267 }
268 #[cfg(target_pointer_width = "64")]
269 {
270 c::syscall(c::SYS_preadv, fd, iov, iovcnt, offset) as c::ssize_t
271 }
272 }
273 }
pwritev64( fd: c::c_int, iov: *const c::iovec, iovcnt: c::c_int, offset: c::off64_t, ) -> c::ssize_t274 pub(in super::super) unsafe fn pwritev64(
275 fd: c::c_int,
276 iov: *const c::iovec,
277 iovcnt: c::c_int,
278 offset: c::off64_t,
279 ) -> c::ssize_t {
280 // See the comments in `preadv64`.
281 weak! {
282 fn pwritev64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t
283 }
284 if let Some(fun) = pwritev64.get() {
285 fun(fd, iov, iovcnt, offset)
286 } else {
287 #[cfg(target_pointer_width = "32")]
288 {
289 c::syscall(
290 c::SYS_pwritev,
291 fd,
292 iov,
293 iovcnt,
294 hi(offset as u64),
295 lo(offset as u64),
296 ) as c::ssize_t
297 }
298 #[cfg(target_pointer_width = "64")]
299 {
300 c::syscall(c::SYS_pwritev, fd, iov, iovcnt, offset) as c::ssize_t
301 }
302 }
303 }
304 }
305 #[cfg(not(any(
306 windows,
307 target_os = "android",
308 target_os = "emscripten",
309 target_os = "haiku",
310 target_os = "ios",
311 target_os = "linux",
312 target_os = "macos",
313 target_os = "redox",
314 target_os = "solaris",
315 )))]
316 pub(super) use c::{preadv as libc_preadv, pwritev as libc_pwritev};
317 #[cfg(target_os = "android")]
318 pub(super) use readwrite_pv64::{preadv64 as libc_preadv, pwritev64 as libc_pwritev};
319 // macOS added preadv and pwritev in version 11.0
320 #[cfg(any(target_os = "ios", target_os = "macos"))]
321 mod readwrite_pv {
322 use super::c;
323
324 weakcall! {
325 pub(in super::super) fn preadv(
326 fd: c::c_int,
327 iov: *const c::iovec,
328 iovcnt: c::c_int,
329 offset: c::off_t
330 ) -> c::ssize_t
331 }
332 weakcall! {
333 pub(in super::super) fn pwritev(
334 fd: c::c_int,
335 iov: *const c::iovec,
336 iovcnt: c::c_int, offset: c::off_t
337 ) -> c::ssize_t
338 }
339 }
340 #[cfg(all(target_os = "linux", target_env = "gnu"))]
341 pub(super) use c::{preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2};
342 #[cfg(any(target_os = "ios", target_os = "macos"))]
343 pub(super) use readwrite_pv::{preadv as libc_preadv, pwritev as libc_pwritev};
344
345 #[cfg(not(any(
346 windows,
347 target_os = "aix",
348 target_os = "android",
349 target_os = "dragonfly",
350 target_os = "fuchsia",
351 target_os = "illumos",
352 target_os = "ios",
353 target_os = "linux",
354 target_os = "l4re",
355 target_os = "macos",
356 target_os = "netbsd",
357 target_os = "openbsd",
358 target_os = "redox",
359 target_os = "solaris",
360 )))]
361 #[cfg(feature = "fs")]
362 pub(super) use c::posix_fallocate as libc_posix_fallocate;
363 #[cfg(target_os = "l4re")]
364 #[cfg(feature = "fs")]
365 pub(super) use c::posix_fallocate64 as libc_posix_fallocate;
366 #[cfg(not(any(
367 windows,
368 target_os = "android",
369 target_os = "emscripten",
370 target_os = "haiku",
371 target_os = "illumos",
372 target_os = "linux",
373 target_os = "l4re",
374 target_os = "netbsd",
375 target_os = "redox",
376 target_os = "solaris",
377 target_os = "wasi",
378 )))]
379 #[cfg(feature = "fs")]
380 pub(super) use {c::fstatfs as libc_fstatfs, c::statfs as libc_statfs};
381 #[cfg(not(any(
382 windows,
383 target_os = "android",
384 target_os = "emscripten",
385 target_os = "haiku",
386 target_os = "illumos",
387 target_os = "linux",
388 target_os = "l4re",
389 target_os = "redox",
390 target_os = "solaris",
391 target_os = "wasi",
392 )))]
393 #[cfg(feature = "fs")]
394 pub(super) use {c::fstatvfs as libc_fstatvfs, c::statvfs as libc_statvfs};
395
396 #[cfg(any(
397 target_os = "android",
398 target_os = "linux",
399 target_os = "emscripten",
400 target_os = "l4re",
401 ))]
402 #[cfg(feature = "fs")]
403 pub(super) use {
404 c::fstatfs64 as libc_fstatfs, c::fstatvfs64 as libc_fstatvfs, c::statfs64 as libc_statfs,
405 c::statvfs64 as libc_statvfs,
406 };
407