• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(not(any(
217     windows,
218     target_os = "android",
219     target_os = "emscripten",
220     target_os = "haiku",
221     target_os = "ios",
222     target_os = "linux",
223     target_os = "macos",
224     target_os = "redox",
225     target_os = "solaris",
226 )))]
227 pub(super) use c::{preadv as libc_preadv, pwritev as libc_pwritev};
228 #[cfg(any(target_os = "linux", target_os = "emscripten"))]
229 pub(super) use c::{preadv64 as libc_preadv, pwritev64 as libc_pwritev};
230 
231 #[cfg(target_os = "android")]
232 mod readwrite_pv64 {
233     use super::c;
234 
235     // 64-bit offsets on 32-bit platforms are passed in endianness-specific
236     // lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
237     #[cfg(all(target_endian = "little", target_pointer_width = "32"))]
lo(x: u64) -> usize238     fn lo(x: u64) -> usize {
239         (x >> 32) as usize
240     }
241     #[cfg(all(target_endian = "little", target_pointer_width = "32"))]
hi(x: u64) -> usize242     fn hi(x: u64) -> usize {
243         (x & 0xffff_ffff) as usize
244     }
245     #[cfg(all(target_endian = "big", target_pointer_width = "32"))]
lo(x: u64) -> usize246     fn lo(x: u64) -> usize {
247         (x & 0xffff_ffff) as usize
248     }
249     #[cfg(all(target_endian = "big", target_pointer_width = "32"))]
hi(x: u64) -> usize250     fn hi(x: u64) -> usize {
251         (x >> 32) as usize
252     }
253 
preadv64( fd: c::c_int, iov: *const c::iovec, iovcnt: c::c_int, offset: c::off64_t, ) -> c::ssize_t254     pub(in super::super) unsafe fn preadv64(
255         fd: c::c_int,
256         iov: *const c::iovec,
257         iovcnt: c::c_int,
258         offset: c::off64_t,
259     ) -> c::ssize_t {
260         // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to
261         // test for it, and call back to `c::syscall`. We don't use
262         // `weak_or_syscall` here because we need to pass the 64-bit offset
263         // specially.
264         weak! {
265             fn preadv64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t
266         }
267         if let Some(fun) = preadv64.get() {
268             fun(fd, iov, iovcnt, offset)
269         } else {
270             #[cfg(target_pointer_width = "32")]
271             {
272                 c::syscall(
273                     c::SYS_preadv,
274                     fd,
275                     iov,
276                     iovcnt,
277                     hi(offset as u64),
278                     lo(offset as u64),
279                 ) as c::ssize_t
280             }
281             #[cfg(target_pointer_width = "64")]
282             {
283                 c::syscall(c::SYS_preadv, fd, iov, iovcnt, offset) as c::ssize_t
284             }
285         }
286     }
pwritev64( fd: c::c_int, iov: *const c::iovec, iovcnt: c::c_int, offset: c::off64_t, ) -> c::ssize_t287     pub(in super::super) unsafe fn pwritev64(
288         fd: c::c_int,
289         iov: *const c::iovec,
290         iovcnt: c::c_int,
291         offset: c::off64_t,
292     ) -> c::ssize_t {
293         // See the comments in `preadv64`.
294         weak! {
295             fn pwritev64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t
296         }
297         if let Some(fun) = pwritev64.get() {
298             fun(fd, iov, iovcnt, offset)
299         } else {
300             #[cfg(target_pointer_width = "32")]
301             {
302                 c::syscall(
303                     c::SYS_pwritev,
304                     fd,
305                     iov,
306                     iovcnt,
307                     hi(offset as u64),
308                     lo(offset as u64),
309                 ) as c::ssize_t
310             }
311             #[cfg(target_pointer_width = "64")]
312             {
313                 c::syscall(c::SYS_pwritev, fd, iov, iovcnt, offset) as c::ssize_t
314             }
315         }
316     }
317 }
318 #[cfg(target_os = "android")]
319 pub(super) use readwrite_pv64::{preadv64 as libc_preadv, pwritev64 as libc_pwritev};
320 
321 // macOS added preadv and pwritev in version 11.0
322 #[cfg(any(target_os = "ios", target_os = "macos"))]
323 mod readwrite_pv {
324     use super::c;
325 
326     weakcall! {
327         pub(in super::super) fn preadv(
328             fd: c::c_int,
329             iov: *const c::iovec,
330             iovcnt: c::c_int,
331             offset: c::off_t
332         ) -> c::ssize_t
333     }
334     weakcall! {
335         pub(in super::super) fn pwritev(
336             fd: c::c_int,
337             iov: *const c::iovec,
338             iovcnt: c::c_int, offset: c::off_t
339         ) -> c::ssize_t
340     }
341 }
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 // GLIBC added `preadv64v2` and `pwritev64v2` in version 2.26.
346 #[cfg(all(target_os = "linux", target_env = "gnu"))]
347 mod readwrite_pv64v2 {
348     use super::c;
349 
350     // 64-bit offsets on 32-bit platforms are passed in endianness-specific
351     // lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
352     #[cfg(all(target_endian = "little", target_pointer_width = "32"))]
lo(x: u64) -> usize353     fn lo(x: u64) -> usize {
354         (x >> 32) as usize
355     }
356     #[cfg(all(target_endian = "little", target_pointer_width = "32"))]
hi(x: u64) -> usize357     fn hi(x: u64) -> usize {
358         (x & 0xffff_ffff) as usize
359     }
360     #[cfg(all(target_endian = "big", target_pointer_width = "32"))]
lo(x: u64) -> usize361     fn lo(x: u64) -> usize {
362         (x & 0xffff_ffff) as usize
363     }
364     #[cfg(all(target_endian = "big", target_pointer_width = "32"))]
hi(x: u64) -> usize365     fn hi(x: u64) -> usize {
366         (x >> 32) as usize
367     }
368 
preadv64v2( fd: c::c_int, iov: *const c::iovec, iovcnt: c::c_int, offset: c::off64_t, flags: c::c_int, ) -> c::ssize_t369     pub(in super::super) unsafe fn preadv64v2(
370         fd: c::c_int,
371         iov: *const c::iovec,
372         iovcnt: c::c_int,
373         offset: c::off64_t,
374         flags: c::c_int,
375     ) -> c::ssize_t {
376         // Older GLIBC lacks `preadv64v2`, so use the `weak!` mechanism to
377         // test for it, and call back to `c::syscall`. We don't use
378         // `weak_or_syscall` here because we need to pass the 64-bit offset
379         // specially.
380         weak! {
381             fn preadv64v2(c::c_int, *const c::iovec, c::c_int, c::off64_t, c::c_int) -> c::ssize_t
382         }
383         if let Some(fun) = preadv64v2.get() {
384             fun(fd, iov, iovcnt, offset, flags)
385         } else {
386             #[cfg(target_pointer_width = "32")]
387             {
388                 c::syscall(
389                     c::SYS_preadv,
390                     fd,
391                     iov,
392                     iovcnt,
393                     hi(offset as u64),
394                     lo(offset as u64),
395                     flags,
396                 ) as c::ssize_t
397             }
398             #[cfg(target_pointer_width = "64")]
399             {
400                 c::syscall(c::SYS_preadv2, fd, iov, iovcnt, offset, flags) as c::ssize_t
401             }
402         }
403     }
pwritev64v2( fd: c::c_int, iov: *const c::iovec, iovcnt: c::c_int, offset: c::off64_t, flags: c::c_int, ) -> c::ssize_t404     pub(in super::super) unsafe fn pwritev64v2(
405         fd: c::c_int,
406         iov: *const c::iovec,
407         iovcnt: c::c_int,
408         offset: c::off64_t,
409         flags: c::c_int,
410     ) -> c::ssize_t {
411         // See the comments in `preadv64v2`.
412         weak! {
413             fn pwritev64v2(c::c_int, *const c::iovec, c::c_int, c::off64_t, c::c_int) -> c::ssize_t
414         }
415         if let Some(fun) = pwritev64v2.get() {
416             fun(fd, iov, iovcnt, offset, flags)
417         } else {
418             #[cfg(target_pointer_width = "32")]
419             {
420                 c::syscall(
421                     c::SYS_pwritev,
422                     fd,
423                     iov,
424                     iovcnt,
425                     hi(offset as u64),
426                     lo(offset as u64),
427                     flags,
428                 ) as c::ssize_t
429             }
430             #[cfg(target_pointer_width = "64")]
431             {
432                 c::syscall(c::SYS_pwritev2, fd, iov, iovcnt, offset, flags) as c::ssize_t
433             }
434         }
435     }
436 }
437 #[cfg(all(target_os = "linux", target_env = "gnu"))]
438 pub(super) use readwrite_pv64v2::{preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2};
439 
440 #[cfg(not(any(
441     windows,
442     target_os = "aix",
443     target_os = "android",
444     target_os = "dragonfly",
445     target_os = "fuchsia",
446     target_os = "illumos",
447     target_os = "ios",
448     target_os = "linux",
449     target_os = "l4re",
450     target_os = "macos",
451     target_os = "netbsd",
452     target_os = "openbsd",
453     target_os = "redox",
454     target_os = "solaris",
455 )))]
456 #[cfg(feature = "fs")]
457 pub(super) use c::posix_fallocate as libc_posix_fallocate;
458 #[cfg(target_os = "l4re")]
459 #[cfg(feature = "fs")]
460 pub(super) use c::posix_fallocate64 as libc_posix_fallocate;
461 #[cfg(not(any(
462     windows,
463     target_os = "android",
464     target_os = "emscripten",
465     target_os = "haiku",
466     target_os = "illumos",
467     target_os = "linux",
468     target_os = "l4re",
469     target_os = "netbsd",
470     target_os = "redox",
471     target_os = "solaris",
472     target_os = "wasi",
473 )))]
474 #[cfg(feature = "fs")]
475 pub(super) use {c::fstatfs as libc_fstatfs, c::statfs as libc_statfs};
476 #[cfg(not(any(
477     windows,
478     target_os = "android",
479     target_os = "emscripten",
480     target_os = "haiku",
481     target_os = "illumos",
482     target_os = "linux",
483     target_os = "l4re",
484     target_os = "redox",
485     target_os = "solaris",
486     target_os = "wasi",
487 )))]
488 #[cfg(feature = "fs")]
489 pub(super) use {c::fstatvfs as libc_fstatvfs, c::statvfs as libc_statvfs};
490 
491 #[cfg(any(
492     target_os = "android",
493     target_os = "linux",
494     target_os = "emscripten",
495     target_os = "l4re",
496 ))]
497 #[cfg(feature = "fs")]
498 pub(super) use {
499     c::fstatfs64 as libc_fstatfs, c::fstatvfs64 as libc_fstatvfs, c::statfs64 as libc_statfs,
500     c::statvfs64 as libc_statvfs,
501 };
502