]> git.proxmox.com Git - rustc.git/blame - vendor/rustix/src/backend/libc/c.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / vendor / rustix / src / backend / libc / c.rs
CommitLineData
781aab86
FG
1//! Libc and supplemental types and constants.
2
fe692bf9
FG
3#![allow(unused_imports)]
4
5// Import everything from libc, but we'll add some stuff and override some
6// things below.
353b0b11
FG
7pub(crate) use libc::*;
8
9/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem.
fe692bf9 10#[cfg(all(linux_kernel, target_env = "musl"))]
353b0b11
FG
11pub(crate) const PROC_SUPER_MAGIC: u32 = 0x0000_9fa0;
12
13/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem.
fe692bf9 14#[cfg(all(linux_kernel, target_env = "musl"))]
353b0b11 15pub(crate) const NFS_SUPER_MAGIC: u32 = 0x0000_6969;
fe692bf9 16
781aab86
FG
17#[cfg(feature = "process")]
18#[cfg(not(any(target_os = "espidf", target_os = "wasi")))]
19pub(crate) const EXIT_SIGNALED_SIGABRT: c_int = 128 + SIGABRT as c_int;
20
fe692bf9
FG
21// TODO: Upstream these.
22#[cfg(all(linux_kernel, feature = "net"))]
23pub(crate) const ETH_P_TSN: c_int = linux_raw_sys::if_ether::ETH_P_TSN as _;
24#[cfg(all(linux_kernel, feature = "net"))]
25pub(crate) const ETH_P_ERSPAN2: c_int = linux_raw_sys::if_ether::ETH_P_ERSPAN2 as _;
26#[cfg(all(linux_kernel, feature = "net"))]
27pub(crate) const ETH_P_ERSPAN: c_int = linux_raw_sys::if_ether::ETH_P_ERSPAN as _;
28#[cfg(all(linux_kernel, feature = "net"))]
29pub(crate) const ETH_P_PROFINET: c_int = linux_raw_sys::if_ether::ETH_P_PROFINET as _;
30#[cfg(all(linux_kernel, feature = "net"))]
31pub(crate) const ETH_P_REALTEK: c_int = linux_raw_sys::if_ether::ETH_P_REALTEK as _;
32#[cfg(all(linux_kernel, feature = "net"))]
33pub(crate) const ETH_P_ETHERCAT: c_int = linux_raw_sys::if_ether::ETH_P_ETHERCAT as _;
34#[cfg(all(linux_kernel, feature = "net"))]
35pub(crate) const ETH_P_PREAUTH: c_int = linux_raw_sys::if_ether::ETH_P_PREAUTH as _;
36#[cfg(all(linux_kernel, feature = "net"))]
37pub(crate) const ETH_P_LLDP: c_int = linux_raw_sys::if_ether::ETH_P_LLDP as _;
38#[cfg(all(linux_kernel, feature = "net"))]
39pub(crate) const ETH_P_MRP: c_int = linux_raw_sys::if_ether::ETH_P_MRP as _;
40#[cfg(all(linux_kernel, feature = "net"))]
41pub(crate) const ETH_P_NCSI: c_int = linux_raw_sys::if_ether::ETH_P_NCSI as _;
42#[cfg(all(linux_kernel, feature = "net"))]
43pub(crate) const ETH_P_CFM: c_int = linux_raw_sys::if_ether::ETH_P_CFM as _;
44#[cfg(all(linux_kernel, feature = "net"))]
45pub(crate) const ETH_P_IBOE: c_int = linux_raw_sys::if_ether::ETH_P_IBOE as _;
46#[cfg(all(linux_kernel, feature = "net"))]
47pub(crate) const ETH_P_HSR: c_int = linux_raw_sys::if_ether::ETH_P_HSR as _;
48#[cfg(all(linux_kernel, feature = "net"))]
49pub(crate) const ETH_P_NSH: c_int = linux_raw_sys::if_ether::ETH_P_NSH as _;
50#[cfg(all(linux_kernel, feature = "net"))]
51pub(crate) const ETH_P_DSA_8021Q: c_int = linux_raw_sys::if_ether::ETH_P_DSA_8021Q as _;
52#[cfg(all(linux_kernel, feature = "net"))]
53pub(crate) const ETH_P_DSA_A5PSW: c_int = linux_raw_sys::if_ether::ETH_P_DSA_A5PSW as _;
54#[cfg(all(linux_kernel, feature = "net"))]
55pub(crate) const ETH_P_IFE: c_int = linux_raw_sys::if_ether::ETH_P_IFE as _;
56#[cfg(all(linux_kernel, feature = "net"))]
57pub(crate) const ETH_P_CAN: c_int = linux_raw_sys::if_ether::ETH_P_CAN as _;
58#[cfg(all(linux_kernel, feature = "net"))]
59pub(crate) const ETH_P_CANXL: c_int = linux_raw_sys::if_ether::ETH_P_CANXL as _;
60#[cfg(all(linux_kernel, feature = "net"))]
61pub(crate) const ETH_P_XDSA: c_int = linux_raw_sys::if_ether::ETH_P_XDSA as _;
62#[cfg(all(linux_kernel, feature = "net"))]
63pub(crate) const ETH_P_MAP: c_int = linux_raw_sys::if_ether::ETH_P_MAP as _;
64#[cfg(all(linux_kernel, feature = "net"))]
65pub(crate) const ETH_P_MCTP: c_int = linux_raw_sys::if_ether::ETH_P_MCTP as _;
66
67#[cfg(all(
68 linux_kernel,
69 any(
70 target_arch = "mips",
add651ee 71 target_arch = "mips32r6",
fe692bf9 72 target_arch = "mips64",
add651ee 73 target_arch = "mips64r6",
fe692bf9
FG
74 target_arch = "sparc",
75 target_arch = "sparc64"
76 )
77))]
78pub(crate) const SIGEMT: c_int = linux_raw_sys::general::SIGEMT as _;
79
80// TODO: Upstream these.
81#[cfg(all(linux_kernel, feature = "termios"))]
82pub(crate) const IUCLC: tcflag_t = linux_raw_sys::general::IUCLC as _;
83#[cfg(all(linux_kernel, feature = "termios"))]
84pub(crate) const XCASE: tcflag_t = linux_raw_sys::general::XCASE as _;
85
781aab86
FG
86#[cfg(target_os = "aix")]
87pub(crate) const MSG_DONTWAIT: c_int = libc::MSG_NONBLOCK;
88
fe692bf9
FG
89// On PowerPC, the regular `termios` has the `termios2` fields and there is no
90// `termios2`. linux-raw-sys has aliases `termios2` to `termios` to cover this
91// difference, but we still need to manually import it since `libc` doesn't
92// have this.
93#[cfg(all(
94 linux_kernel,
95 feature = "termios",
96 any(target_arch = "powerpc", target_arch = "powerpc64")
97))]
98pub(crate) use {
99 linux_raw_sys::general::{termios2, CIBAUD},
100 linux_raw_sys::ioctl::{TCGETS2, TCSETS2, TCSETSF2, TCSETSW2},
101};
102
103// Automatically enable “large file” support (LFS) features.
104
105#[cfg(target_os = "vxworks")]
106pub(super) use libc::_Vx_ticks64_t as _Vx_ticks_t;
fe692bf9
FG
107#[cfg(linux_kernel)]
108pub(super) use libc::fallocate64 as fallocate;
109#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))]
110#[cfg(any(linux_like, target_os = "aix"))]
111pub(super) use libc::open64 as open;
112#[cfg(any(linux_kernel, target_os = "aix", target_os = "l4re"))]
113pub(super) use libc::posix_fallocate64 as posix_fallocate;
114#[cfg(any(all(linux_like, not(target_os = "android")), target_os = "aix"))]
115pub(super) use libc::{blkcnt64_t as blkcnt_t, rlim64_t as rlim_t};
781aab86
FG
116// TODO: AIX has `stat64x`, `fstat64x`, `lstat64x`, and `stat64xat`; add them
117// to the upstream libc crate and implement rustix's `statat` etc. with them.
add651ee
FG
118#[cfg(target_os = "aix")]
119pub(super) use libc::{
781aab86
FG
120 blksize64_t as blksize_t, fstat64 as fstat, fstatfs64 as fstatfs, fstatvfs64 as fstatvfs,
121 ftruncate64 as ftruncate, getrlimit64 as getrlimit, ino_t, lseek64 as lseek, mmap,
122 off64_t as off_t, openat, posix_fadvise64 as posix_fadvise, preadv, pwritev,
123 rlimit64 as rlimit, setrlimit64 as setrlimit, statfs64 as statfs, statvfs64 as statvfs,
124 RLIM_INFINITY,
add651ee
FG
125};
126#[cfg(linux_like)]
fe692bf9
FG
127pub(super) use libc::{
128 fstat64 as fstat, fstatat64 as fstatat, fstatfs64 as fstatfs, fstatvfs64 as fstatvfs,
129 ftruncate64 as ftruncate, getrlimit64 as getrlimit, ino64_t as ino_t, lseek64 as lseek,
130 mmap64 as mmap, off64_t as off_t, openat64 as openat, posix_fadvise64 as posix_fadvise,
131 rlimit64 as rlimit, setrlimit64 as setrlimit, statfs64 as statfs, statvfs64 as statvfs,
132 RLIM64_INFINITY as RLIM_INFINITY,
133};
134#[cfg(apple)]
135pub(super) use libc::{
136 host_info64_t as host_info_t, host_statistics64 as host_statistics,
137 vm_statistics64_t as vm_statistics_t,
138};
add651ee
FG
139#[cfg(not(all(
140 linux_kernel,
141 any(
142 target_pointer_width = "32",
143 target_arch = "mips64",
144 target_arch = "mips64r6"
145 )
146)))]
fe692bf9
FG
147#[cfg(any(linux_like, target_os = "aix"))]
148pub(super) use libc::{lstat64 as lstat, stat64 as stat};
149#[cfg(any(linux_kernel, target_os = "aix", target_os = "emscripten"))]
150pub(super) use libc::{pread64 as pread, pwrite64 as pwrite};
add651ee 151#[cfg(any(target_os = "linux", target_os = "emscripten"))]
fe692bf9
FG
152pub(super) use libc::{preadv64 as preadv, pwritev64 as pwritev};
153
154#[cfg(all(target_os = "linux", target_env = "gnu"))]
155pub(super) unsafe fn prlimit(
156 pid: libc::pid_t,
157 resource: libc::__rlimit_resource_t,
158 new_limit: *const libc::rlimit64,
159 old_limit: *mut libc::rlimit64,
160) -> libc::c_int {
161 // `prlimit64` wasn't supported in glibc until 2.13.
162 weak_or_syscall! {
163 fn prlimit64(
164 pid: libc::pid_t,
165 resource: libc::__rlimit_resource_t,
166 new_limit: *const libc::rlimit64,
167 old_limit: *mut libc::rlimit64
168 ) via SYS_prlimit64 -> libc::c_int
169 }
170
171 prlimit64(pid, resource, new_limit, old_limit)
172}
173
174#[cfg(all(target_os = "linux", target_env = "musl"))]
175pub(super) unsafe fn prlimit(
176 pid: libc::pid_t,
177 resource: libc::c_int,
178 new_limit: *const libc::rlimit64,
179 old_limit: *mut libc::rlimit64,
180) -> libc::c_int {
181 weak_or_syscall! {
182 fn prlimit64(
183 pid: libc::pid_t,
184 resource: libc::c_int,
185 new_limit: *const libc::rlimit64,
186 old_limit: *mut libc::rlimit64
187 ) via SYS_prlimit64 -> libc::c_int
188 }
189
190 prlimit64(pid, resource, new_limit, old_limit)
191}
192
193#[cfg(target_os = "android")]
194pub(super) unsafe fn prlimit(
195 pid: libc::pid_t,
196 resource: libc::c_int,
197 new_limit: *const libc::rlimit64,
198 old_limit: *mut libc::rlimit64,
199) -> libc::c_int {
200 weak_or_syscall! {
201 fn prlimit64(
202 pid: libc::pid_t,
203 resource: libc::c_int,
204 new_limit: *const libc::rlimit64,
205 old_limit: *mut libc::rlimit64
206 ) via SYS_prlimit64 -> libc::c_int
207 }
208
209 prlimit64(pid, resource, new_limit, old_limit)
210}
211
212// 64-bit offsets on 32-bit platforms are passed in endianness-specific
213// lo/hi pairs. See src/backend/linux_raw/conv.rs for details.
214#[cfg(all(linux_kernel, target_endian = "little", target_pointer_width = "32"))]
215fn lo(x: i64) -> usize {
216 (x >> 32) as usize
217}
218#[cfg(all(linux_kernel, target_endian = "little", target_pointer_width = "32"))]
219fn hi(x: i64) -> usize {
220 x as usize
221}
222#[cfg(all(linux_kernel, target_endian = "big", target_pointer_width = "32"))]
223fn lo(x: i64) -> usize {
224 x as usize
225}
226#[cfg(all(linux_kernel, target_endian = "big", target_pointer_width = "32"))]
227fn hi(x: i64) -> usize {
228 (x >> 32) as usize
229}
230
231#[cfg(target_os = "android")]
232mod readwrite_pv64 {
233 use super::*;
234
235 pub(in super::super) unsafe fn preadv64(
236 fd: libc::c_int,
237 iov: *const libc::iovec,
238 iovcnt: libc::c_int,
239 offset: libc::off64_t,
240 ) -> libc::ssize_t {
241 // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to
242 // test for it, and call back to `libc::syscall`. We don't use
243 // `weak_or_syscall` here because we need to pass the 64-bit offset
244 // specially.
245 weak! {
246 fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t) -> libc::ssize_t
247 }
248 if let Some(fun) = preadv64.get() {
249 fun(fd, iov, iovcnt, offset)
250 } else {
251 #[cfg(target_pointer_width = "32")]
252 {
253 syscall! {
254 fn preadv(
255 fd: libc::c_int,
256 iov: *const libc::iovec,
257 iovcnt: libc::c_int,
258 offset_hi: usize,
259 offset_lo: usize
260 ) via SYS_preadv -> libc::ssize_t
261 }
262 preadv(fd, iov, iovcnt, hi(offset), lo(offset))
263 }
264 #[cfg(target_pointer_width = "64")]
265 {
266 syscall! {
267 fn preadv(
268 fd: libc::c_int,
269 iov: *const libc::iovec,
270 iovcnt: libc::c_int,
271 offset: libc::off_t
272 ) via SYS_preadv -> libc::ssize_t
273 }
274 preadv(fd, iov, iovcnt, offset)
275 }
276 }
277 }
278 pub(in super::super) unsafe fn pwritev64(
279 fd: libc::c_int,
280 iov: *const libc::iovec,
281 iovcnt: libc::c_int,
282 offset: libc::off64_t,
283 ) -> libc::ssize_t {
284 // See the comments in `preadv64`.
285 weak! {
286 fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t) -> libc::ssize_t
287 }
288 if let Some(fun) = pwritev64.get() {
289 fun(fd, iov, iovcnt, offset)
290 } else {
291 #[cfg(target_pointer_width = "32")]
292 {
293 syscall! {
294 fn pwritev(
295 fd: libc::c_int,
296 iov: *const libc::iovec,
297 iovcnt: libc::c_int,
298 offset_hi: usize,
299 offset_lo: usize
300 ) via SYS_pwritev -> libc::ssize_t
301 }
302 pwritev(fd, iov, iovcnt, hi(offset), lo(offset))
303 }
304 #[cfg(target_pointer_width = "64")]
305 {
306 syscall! {
307 fn pwritev(
308 fd: libc::c_int,
309 iov: *const libc::iovec,
310 iovcnt: libc::c_int,
311 offset: libc::off_t
312 ) via SYS_pwritev -> libc::ssize_t
313 }
314 pwritev(fd, iov, iovcnt, offset)
315 }
316 }
317 }
318}
319#[cfg(target_os = "android")]
320pub(super) use readwrite_pv64::{preadv64 as preadv, pwritev64 as pwritev};
321
322// macOS added preadv and pwritev in version 11.0
323#[cfg(apple)]
324mod readwrite_pv {
325 weakcall! {
326 pub(in super::super) fn preadv(
327 fd: libc::c_int,
328 iov: *const libc::iovec,
329 iovcnt: libc::c_int,
330 offset: libc::off_t
331 ) -> libc::ssize_t
332 }
333 weakcall! {
334 pub(in super::super) fn pwritev(
335 fd: libc::c_int,
336 iov: *const libc::iovec,
337 iovcnt: libc::c_int, offset: libc::off_t
338 ) -> libc::ssize_t
339 }
340}
341#[cfg(apple)]
342pub(super) use readwrite_pv::{preadv, pwritev};
343
344// glibc added `preadv64v2` and `pwritev64v2` in version 2.26.
345#[cfg(all(target_os = "linux", target_env = "gnu"))]
346mod readwrite_pv64v2 {
347 use super::*;
348
349 pub(in super::super) unsafe fn preadv64v2(
350 fd: libc::c_int,
351 iov: *const libc::iovec,
352 iovcnt: libc::c_int,
353 offset: libc::off64_t,
354 flags: libc::c_int,
355 ) -> libc::ssize_t {
356 // Older glibc lacks `preadv64v2`, so use the `weak!` mechanism to
357 // test for it, and call back to `libc::syscall`. We don't use
358 // `weak_or_syscall` here because we need to pass the 64-bit offset
359 // specially.
360 weak! {
361 fn preadv64v2(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t, libc::c_int) -> libc::ssize_t
362 }
363 if let Some(fun) = preadv64v2.get() {
364 fun(fd, iov, iovcnt, offset, flags)
365 } else {
366 #[cfg(target_pointer_width = "32")]
367 {
368 syscall! {
369 fn preadv2(
370 fd: libc::c_int,
371 iov: *const libc::iovec,
372 iovcnt: libc::c_int,
373 offset_hi: usize,
374 offset_lo: usize,
375 flags: libc::c_int
376 ) via SYS_preadv2 -> libc::ssize_t
377 }
378 preadv2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
379 }
380 #[cfg(target_pointer_width = "64")]
381 {
382 syscall! {
383 fn preadv2(
384 fd: libc::c_int,
385 iov: *const libc::iovec,
386 iovcnt: libc::c_int,
387 offset: libc::off_t,
388 flags: libc::c_int
389 ) via SYS_preadv2 -> libc::ssize_t
390 }
391 preadv2(fd, iov, iovcnt, offset, flags)
392 }
393 }
394 }
395 pub(in super::super) unsafe fn pwritev64v2(
396 fd: libc::c_int,
397 iov: *const libc::iovec,
398 iovcnt: libc::c_int,
399 offset: libc::off64_t,
400 flags: libc::c_int,
401 ) -> libc::ssize_t {
402 // See the comments in `preadv64v2`.
403 weak! {
404 fn pwritev64v2(libc::c_int, *const libc::iovec, libc::c_int, libc::off64_t, libc::c_int) -> libc::ssize_t
405 }
406 if let Some(fun) = pwritev64v2.get() {
407 fun(fd, iov, iovcnt, offset, flags)
408 } else {
409 #[cfg(target_pointer_width = "32")]
410 {
411 syscall! {
412 fn pwritev2(
413 fd: libc::c_int,
414 iov: *const libc::iovec,
415 iovec: libc::c_int,
416 offset_hi: usize,
417 offset_lo: usize,
418 flags: libc::c_int
419 ) via SYS_pwritev2 -> libc::ssize_t
420 }
421 pwritev2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
422 }
423 #[cfg(target_pointer_width = "64")]
424 {
425 syscall! {
426 fn pwritev2(
427 fd: libc::c_int,
428 iov:*const libc::iovec,
429 iovcnt: libc::c_int,
430 offset: libc::off_t,
431 flags: libc::c_int
432 ) via SYS_pwritev2 -> libc::ssize_t
433 }
434 pwritev2(fd, iov, iovcnt, offset, flags)
435 }
436 }
437 }
438}
439#[cfg(all(target_os = "linux", target_env = "gnu"))]
440pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2};
441
442// On non-glibc, assume we don't have `pwritev2`/`preadv2` in libc and use
443// `c::syscall` instead.
444#[cfg(any(
445 target_os = "android",
446 all(target_os = "linux", not(target_env = "gnu")),
447))]
448mod readwrite_pv64v2 {
449 use super::*;
450
451 pub(in super::super) unsafe fn preadv64v2(
452 fd: libc::c_int,
453 iov: *const libc::iovec,
454 iovcnt: libc::c_int,
455 offset: libc::off64_t,
456 flags: libc::c_int,
457 ) -> libc::ssize_t {
458 #[cfg(target_pointer_width = "32")]
459 {
460 syscall! {
461 fn preadv2(
462 fd: libc::c_int,
463 iov: *const libc::iovec,
464 iovcnt: libc::c_int,
465 offset_hi: usize,
466 offset_lo: usize,
467 flags: libc::c_int
468 ) via SYS_preadv2 -> libc::ssize_t
469 }
470 preadv2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
471 }
472 #[cfg(target_pointer_width = "64")]
473 {
474 syscall! {
475 fn preadv2(
476 fd: libc::c_int,
477 iov: *const libc::iovec,
478 iovcnt: libc::c_int,
479 offset: libc::off_t,
480 flags: libc::c_int
481 ) via SYS_preadv2 -> libc::ssize_t
482 }
483 preadv2(fd, iov, iovcnt, offset, flags)
484 }
485 }
486 pub(in super::super) unsafe fn pwritev64v2(
487 fd: libc::c_int,
488 iov: *const libc::iovec,
489 iovcnt: libc::c_int,
490 offset: libc::off64_t,
491 flags: libc::c_int,
492 ) -> libc::ssize_t {
493 #[cfg(target_pointer_width = "32")]
494 {
495 syscall! {
496 fn pwritev2(
497 fd: libc::c_int,
498 iov: *const libc::iovec,
499 iovcnt: libc::c_int,
500 offset_hi: usize,
501 offset_lo: usize,
502 flags: libc::c_int
503 ) via SYS_pwritev2 -> libc::ssize_t
504 }
505 pwritev2(fd, iov, iovcnt, hi(offset), lo(offset), flags)
506 }
507 #[cfg(target_pointer_width = "64")]
508 {
509 syscall! {
510 fn pwritev2(
511 fd: libc::c_int,
512 iov:*const libc::iovec,
513 iovcnt: libc::c_int,
514 offset: libc::off_t,
515 flags: libc::c_int
516 ) via SYS_pwritev2 -> libc::ssize_t
517 }
518 pwritev2(fd, iov, iovcnt, offset, flags)
519 }
520 }
521}
522#[cfg(any(
523 target_os = "android",
524 all(target_os = "linux", not(target_env = "gnu")),
525))]
526pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2};