• 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(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