diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/rustix/src/backend/linux_raw | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw')
72 files changed, 2589 insertions, 3129 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs index 4783747ac..7c26e23a4 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs @@ -19,4 +19,4 @@ #[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")] mod target_arch; -pub(in crate::backend) use self::target_arch::*; +pub(in crate::backend) use target_arch::*; diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs index 8e115148d..62947cb04 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs @@ -113,7 +113,7 @@ pub(in crate::backend) unsafe fn indirect_syscall4( ) -> RetReg<R0> { let r0; // a3 should go in esi, but `asm!` won't let us use it as an operand. - // temporarily swap it into place, and then swap it back afterward. + // Temporarily swap it into place, and then swap it back afterward. // // We hard-code the callee operand to use edi instead of `in(reg)` because // even though we can't name esi as an operand, the compiler can use esi to diff --git a/vendor/rustix/src/backend/linux_raw/arch/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/mod.rs index e13f675fd..cc93fc2c4 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/arch/mod.rs @@ -1,8 +1,8 @@ //! Architecture-specific syscall code. //! //! `rustix` has inline assembly sequences using `asm!`, but that requires -//! nightly Rust, so it also has out-of-line ("outline") assembly sequences -//! in .s files. And 32-bit x86 is special (see comments below). +//! Rust 1.59, so it also has out-of-line ("outline") assembly sequences in .s +//! files. And 32-bit x86 is special (see comments below). //! //! This module also has a `choose` submodule which chooses a scheme and is //! what most of the `rustix` syscalls use. @@ -133,6 +133,87 @@ macro_rules! syscall { }; } +// Macro to invoke a syscall that always uses direct assembly, rather than the +// vDSO. Useful when still finding the vDSO. +#[allow(unused_macros)] +macro_rules! syscall_always_asm { + ($nr:ident) => { + $crate::backend::arch::asm::syscall0($crate::backend::reg::nr(linux_raw_sys::general::$nr)) + }; + + ($nr:ident, $a0:expr) => { + $crate::backend::arch::asm::syscall1( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr) => { + $crate::backend::arch::asm::syscall2( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { + $crate::backend::arch::asm::syscall3( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => { + $crate::backend::arch::asm::syscall4( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + $a3.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr) => { + $crate::backend::arch::asm::syscall5( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + $a3.into(), + $a4.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr) => { + $crate::backend::arch::asm::syscall6( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + $a3.into(), + $a4.into(), + $a5.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr) => { + $crate::backend::arch::asm::syscall7( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + $a3.into(), + $a4.into(), + $a5.into(), + $a6.into(), + ) + }; +} + +/// Like `syscall`, but adds the `readonly` attribute to the inline asm, which +/// indicates that the syscall does not mutate any memory. macro_rules! syscall_readonly { ($nr:ident) => { $crate::backend::arch::choose::syscall0_readonly($crate::backend::reg::nr( @@ -211,6 +292,7 @@ macro_rules! syscall_readonly { }; } +/// Like `syscall`, but indicates that the syscall does not return. #[cfg(feature = "runtime")] macro_rules! syscall_noreturn { ($nr:ident, $a0:expr) => { diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s deleted file mode 100644 index 1fad2fa6d..000000000 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s +++ /dev/null @@ -1,119 +0,0 @@ -// Assembly code for making aarch64 syscalls. -// -// aarch64 syscall argument register ordering is the same as the aarch64 -// userspace argument register ordering except that the syscall number -// (nr) is passed in w8. -// -// outline.rs takes care of reordering the nr argument to the end for us, -// so we only need to move nr into w8. -// -// arm64-ilp32 is not yet supported. - - .file "aarch64.s" - .arch armv8-a - - .section .text.rustix_syscall0_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall0_nr_last - .hidden rustix_syscall0_nr_last - .type rustix_syscall0_nr_last, @function -rustix_syscall0_nr_last: - .cfi_startproc - mov w8, w0 - svc #0 - ret - .cfi_endproc - .size rustix_syscall0_nr_last, .-rustix_syscall0_nr_last - - .section .text.rustix_syscall1_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall1_nr_last - .hidden rustix_syscall1_nr_last - .type rustix_syscall1_nr_last, @function -rustix_syscall1_nr_last: - .cfi_startproc - mov w8, w1 - svc #0 - ret - .cfi_endproc - .size rustix_syscall1_nr_last, .-rustix_syscall1_nr_last - - .section .text.rustix_syscall1_noreturn_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall1_noreturn_nr_last - .hidden rustix_syscall1_noreturn_nr_last - .type rustix_syscall1_noreturn_nr_last, @function -rustix_syscall1_noreturn_nr_last: - .cfi_startproc - mov w8, w1 - svc #0 - brk #0x1 - .cfi_endproc - .size rustix_syscall1_noreturn_nr_last, .-rustix_syscall1_noreturn_nr_last - - .section .text.rustix_syscall2_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall2_nr_last - .hidden rustix_syscall2_nr_last - .type rustix_syscall2_nr_last, @function -rustix_syscall2_nr_last: - .cfi_startproc - mov w8, w2 - svc #0 - ret - .cfi_endproc - .size rustix_syscall2_nr_last, .-rustix_syscall2_nr_last - - .section .text.rustix_syscall3_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall3_nr_last - .hidden rustix_syscall3_nr_last - .type rustix_syscall3_nr_last, @function -rustix_syscall3_nr_last: - .cfi_startproc - mov w8, w3 - svc #0 - ret - .cfi_endproc - .size rustix_syscall3_nr_last, .-rustix_syscall3_nr_last - - .section .text.rustix_syscall4_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall4_nr_last - .hidden rustix_syscall4_nr_last - .type rustix_syscall4_nr_last, @function -rustix_syscall4_nr_last: - .cfi_startproc - mov w8, w4 - svc #0 - ret - .cfi_endproc - .size rustix_syscall4_nr_last, .-rustix_syscall4_nr_last - - .section .text.rustix_syscall5_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall5_nr_last - .hidden rustix_syscall5_nr_last - .type rustix_syscall5_nr_last, @function -rustix_syscall5_nr_last: - .cfi_startproc - mov w8, w5 - svc #0 - ret - .cfi_endproc - .size rustix_syscall5_nr_last, .-rustix_syscall5_nr_last - - .section .text.rustix_syscall6_nr_last,"ax",@progbits - .p2align 2 - .weak rustix_syscall6_nr_last - .hidden rustix_syscall6_nr_last - .type rustix_syscall6_nr_last, @function -rustix_syscall6_nr_last: - .cfi_startproc - mov w8, w6 - svc #0 - ret - .cfi_endproc - .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/arm.s b/vendor/rustix/src/backend/linux_raw/arch/outline/arm.s deleted file mode 100644 index 7001686f1..000000000 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/arm.s +++ /dev/null @@ -1,135 +0,0 @@ -// Assembly code for making arm syscalls. -// -// arm syscall argument register ordering is the similar to the arm -// userspace argument register ordering except that the syscall number -// (nr) is passed in r7. -// -// nr_last.rs takes care of reordering the nr argument to the end for us, -// so we only need to move nr into r7 and take care of r4 and r5 if needed. - - .file "arm.s" - .arch armv5t - - .section .text.rustix_syscall0_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall0_nr_last - .hidden rustix_syscall0_nr_last - .type rustix_syscall0_nr_last, %function -rustix_syscall0_nr_last: - .fnstart - .cantunwind - push {r7, lr} - mov r7, r0 - svc #0 - pop {r7, pc} - .fnend - .size rustix_syscall0_nr_last, .-rustix_syscall0_nr_last - - .section .text.rustix_syscall1_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall1_nr_last - .hidden rustix_syscall1_nr_last - .type rustix_syscall1_nr_last, %function -rustix_syscall1_nr_last: - .fnstart - .cantunwind - push {r7, lr} - mov r7, r1 - svc #0 - pop {r7, pc} - .fnend - .size rustix_syscall1_nr_last, .-rustix_syscall1_nr_last - - .section .text.rustix_syscall1_noreturn_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall1_noreturn_nr_last - .hidden rustix_syscall1_noreturn_nr_last - .type rustix_syscall1_noreturn_nr_last, %function -rustix_syscall1_noreturn_nr_last: - .fnstart - .cantunwind - // Don't save r7 and lr; this is noreturn, so we'll never restore them. - mov r7, r1 - svc #0 - udf #16 // Trap instruction - .fnend - .size rustix_syscall1_noreturn_nr_last, .-rustix_syscall1_noreturn_nr_last - - .section .text.rustix_syscall2_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall2_nr_last - .hidden rustix_syscall2_nr_last - .type rustix_syscall2_nr_last, %function -rustix_syscall2_nr_last: - .fnstart - .cantunwind - push {r7, lr} - mov r7, r2 - svc #0 - pop {r7, pc} - .fnend - .size rustix_syscall2_nr_last, .-rustix_syscall2_nr_last - - .section .text.rustix_syscall3_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall3_nr_last - .hidden rustix_syscall3_nr_last - .type rustix_syscall3_nr_last, %function -rustix_syscall3_nr_last: - .fnstart - .cantunwind - push {r7, lr} - mov r7, r3 - svc #0 - pop {r7, pc} - .fnend - .size rustix_syscall3_nr_last, .-rustix_syscall3_nr_last - - .section .text.rustix_syscall4_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall4_nr_last - .hidden rustix_syscall4_nr_last - .type rustix_syscall4_nr_last, %function -rustix_syscall4_nr_last: - .fnstart - .cantunwind - push {r7, lr} - ldr r7, [sp, #8] - svc #0 - pop {r7, pc} - .fnend - .size rustix_syscall4_nr_last, .-rustix_syscall4_nr_last - - .section .text.rustix_syscall5_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall5_nr_last - .hidden rustix_syscall5_nr_last - .type rustix_syscall5_nr_last, %function -rustix_syscall5_nr_last: - .fnstart - .cantunwind - push {r4, r7, r11, lr} - ldr r7, [sp, #20] - ldr r4, [sp, #16] - svc #0 - pop {r4, r7, r11, pc} - .fnend - .size rustix_syscall5_nr_last, .-rustix_syscall5_nr_last - - .section .text.rustix_syscall6_nr_last,"ax",%progbits - .p2align 4 - .weak rustix_syscall6_nr_last - .hidden rustix_syscall6_nr_last - .type rustix_syscall6_nr_last, %function -rustix_syscall6_nr_last: - .fnstart - .cantunwind - push {r4, r5, r7, lr} - add r7, sp, #16 - ldm r7, {r4, r5, r7} - svc #0 - pop {r4, r5, r7, pc} - .fnend - .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - - .section .note.GNU-stack,"",%progbits diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/mips.s b/vendor/rustix/src/backend/linux_raw/arch/outline/mips.s index ab1bbfa2d..b016ae124 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/mips.s +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/mips.s @@ -186,8 +186,6 @@ rustix_syscall6_nr_last: .end rustix_syscall6_nr_last .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - .section .note.GNU-stack,"",@progbits - .section .text.rustix_syscall7_nr_last,"ax",@progbits .p2align 2 .weak rustix_syscall7_nr_last diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s index 3c5e76e36..a6473990e 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s @@ -7,7 +7,7 @@ # outline.rs takes care of reordering the nr argument to the end for us, # so we only need to move nr into v0. - .file "mips.s" + .file "mips64.s" .section .mdebug.abi64 .previous .abicalls diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs index 5e6f5e1f5..202a2cce9 100644 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs @@ -5,32 +5,23 @@ //! they match with the kernel convention as closely as possible, to minimize //! the amount of out-of-line code we need. //! -//! This is needed in order to support our MSRV of 1.48, which doesn't support -//! inline asm. When using newer Rust versions, inline asm code is used instead -//! and these outline libraries are unused. +//! This is needed because as of our MSRV of 1.63, inline asm and naked +//! functions are experimental. #[cfg(target_arch = "x86")] mod x86; // For these architectures, pass the `nr` argument last. #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", target_arch = "mips", target_arch = "mips64", target_arch = "powerpc64", - target_arch = "riscv64", - target_arch = "x86_64", ))] mod nr_last; #[cfg(any( - target_arch = "arm", - target_arch = "aarch64", target_arch = "mips", target_arch = "mips64", target_arch = "powerpc64", - target_arch = "riscv64", - target_arch = "x86_64", ))] pub(in crate::backend) use nr_last::*; #[cfg(target_arch = "x86")] diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/riscv64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/riscv64.s deleted file mode 100644 index 28d692f7c..000000000 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/riscv64.s +++ /dev/null @@ -1,116 +0,0 @@ -# Assembly code for making riscv64 syscalls. -# -# riscv64 syscall argument register ordering is the same as the riscv64 -# userspace argument register ordering except that the syscall number -# (nr) is passed in a7. -# -# nr_last.rs takes care of reordering the nr argument to the end for us, -# so we only need to move nr into a7. - - .file "riscv64.s" - - .section .text.rustix_syscall0_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall0_nr_last - .hidden rustix_syscall0_nr_last - .type rustix_syscall0_nr_last, @function -rustix_syscall0_nr_last: - .cfi_startproc - mv a7, a0 - ecall - ret - .cfi_endproc - .size rustix_syscall0_nr_last, .-rustix_syscall0_nr_last - - .section .text.rustix_syscall1_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall1_nr_last - .hidden rustix_syscall1_nr_last - .type rustix_syscall1_nr_last, @function -rustix_syscall1_nr_last: - .cfi_startproc - mv a7, a1 - ecall - ret - .cfi_endproc - .size rustix_syscall1_nr_last, .-rustix_syscall1_nr_last - - .section .text.rustix_syscall1_noreturn_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall1_noreturn_nr_last - .hidden rustix_syscall1_noreturn_nr_last - .type rustix_syscall1_noreturn_nr_last, @function -rustix_syscall1_noreturn_nr_last: - .cfi_startproc - mv a7, a1 - ecall - unimp - .cfi_endproc - .size rustix_syscall1_noreturn_nr_last, .-rustix_syscall1_noreturn_nr_last - - .section .text.rustix_syscall2_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall2_nr_last - .hidden rustix_syscall2_nr_last - .type rustix_syscall2_nr_last, @function -rustix_syscall2_nr_last: - .cfi_startproc - mv a7, a2 - ecall - ret - .cfi_endproc - .size rustix_syscall2_nr_last, .-rustix_syscall2_nr_last - - .section .text.rustix_syscall3_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall3_nr_last - .hidden rustix_syscall3_nr_last - .type rustix_syscall3_nr_last, @function -rustix_syscall3_nr_last: - .cfi_startproc - mv a7, a3 - ecall - ret - .cfi_endproc - .size rustix_syscall3_nr_last, .-rustix_syscall3_nr_last - - .section .text.rustix_syscall4_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall4_nr_last - .hidden rustix_syscall4_nr_last - .type rustix_syscall4_nr_last, @function -rustix_syscall4_nr_last: - .cfi_startproc - mv a7, a4 - ecall - ret - .cfi_endproc - .size rustix_syscall4_nr_last, .-rustix_syscall4_nr_last - - .section .text.rustix_syscall5_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall5_nr_last - .hidden rustix_syscall5_nr_last - .type rustix_syscall5_nr_last, @function -rustix_syscall5_nr_last: - .cfi_startproc - mv a7, a5 - ecall - ret - .cfi_endproc - .size rustix_syscall5_nr_last, .-rustix_syscall5_nr_last - - .section .text.rustix_syscall6_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall6_nr_last - .hidden rustix_syscall6_nr_last - .type rustix_syscall6_nr_last, @function -rustix_syscall6_nr_last: - .cfi_startproc - mv a7, a6 - ecall - ret - .cfi_endproc - .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/x86_64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/x86_64.s deleted file mode 100644 index 2beda323b..000000000 --- a/vendor/rustix/src/backend/linux_raw/arch/outline/x86_64.s +++ /dev/null @@ -1,122 +0,0 @@ -// Assembly code for making x86-64 syscalls. -// -// x86-64 syscall argument register ordering is the same as the x86-64 -// userspace argument register ordering except that a3 is passed in r10 -// instead of rcx, and the syscall number (nr) is passed in eax. -// -// outline.rs takes care of reordering the nr argument to the end for us, -// so we only need to move nr into eax and move rcx into r10 as needed. -// -// x32 is not yet supported. - - .file "x86_64.s" - .intel_syntax noprefix - - .section .text.rustix_syscall0_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall0_nr_last - .hidden rustix_syscall0_nr_last - .type rustix_syscall0_nr_last, @function -rustix_syscall0_nr_last: - .cfi_startproc - mov eax,edi - syscall - ret - .cfi_endproc - .size rustix_syscall0_nr_last, .-rustix_syscall0_nr_last - - .section .text.rustix_syscall1_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall1_nr_last - .hidden rustix_syscall1_nr_last - .type rustix_syscall1_nr_last, @function -rustix_syscall1_nr_last: - .cfi_startproc - mov eax,esi - syscall - ret - .cfi_endproc - .size rustix_syscall1_nr_last, .-rustix_syscall1_nr_last - - .section .text.rustix_syscall1_noreturn_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall1_noreturn_nr_last - .hidden rustix_syscall1_noreturn_nr_last - .type rustix_syscall1_noreturn_nr_last, @function -rustix_syscall1_noreturn_nr_last: - .cfi_startproc - mov eax,esi - syscall - ud2 - .cfi_endproc - .size rustix_syscall1_noreturn_nr_last, .-rustix_syscall1_noreturn_nr_last - - .section .text.rustix_syscall2_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall2_nr_last - .hidden rustix_syscall2_nr_last - .type rustix_syscall2_nr_last, @function -rustix_syscall2_nr_last: - .cfi_startproc - mov eax,edx - syscall - ret - .cfi_endproc - .size rustix_syscall2_nr_last, .-rustix_syscall2_nr_last - - .section .text.rustix_syscall3_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall3_nr_last - .hidden rustix_syscall3_nr_last - .type rustix_syscall3_nr_last, @function -rustix_syscall3_nr_last: - .cfi_startproc - mov eax,ecx - syscall - ret - .cfi_endproc - .size rustix_syscall3_nr_last, .-rustix_syscall3_nr_last - - .section .text.rustix_syscall4_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall4_nr_last - .hidden rustix_syscall4_nr_last - .type rustix_syscall4_nr_last, @function -rustix_syscall4_nr_last: - .cfi_startproc - mov eax,r8d - mov r10,rcx - syscall - ret - .cfi_endproc - .size rustix_syscall4_nr_last, .-rustix_syscall4_nr_last - - .section .text.rustix_syscall5_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall5_nr_last - .hidden rustix_syscall5_nr_last - .type rustix_syscall5_nr_last, @function -rustix_syscall5_nr_last: - .cfi_startproc - mov eax,r9d - mov r10,rcx - syscall - ret - .cfi_endproc - .size rustix_syscall5_nr_last, .-rustix_syscall5_nr_last - - .section .text.rustix_syscall6_nr_last,"ax",@progbits - .p2align 4 - .weak rustix_syscall6_nr_last - .hidden rustix_syscall6_nr_last - .type rustix_syscall6_nr_last, @function -rustix_syscall6_nr_last: - .cfi_startproc - mov eax,DWORD PTR [rsp+0x8] - mov r10,rcx - syscall - ret - .cfi_endproc - .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/backend/linux_raw/c.rs b/vendor/rustix/src/backend/linux_raw/c.rs index 89fee82f9..8e77c82d7 100644 --- a/vendor/rustix/src/backend/linux_raw/c.rs +++ b/vendor/rustix/src/backend/linux_raw/c.rs @@ -4,30 +4,180 @@ //! types that are convenient to have defined. #![allow(unused_imports)] +#![allow(non_camel_case_types)] +pub type size_t = usize; pub(crate) use linux_raw_sys::ctypes::*; pub(crate) use linux_raw_sys::errno::EINVAL; +// Import the kernel's `uid_t` and `gid_t` if they're 32-bit. +#[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] +pub(crate) use linux_raw_sys::general::{__kernel_gid_t as gid_t, __kernel_uid_t as uid_t}; pub(crate) use linux_raw_sys::general::{ - AF_DECnet, __kernel_sa_family_t as sa_family_t, __kernel_sockaddr_storage as sockaddr_storage, - in6_addr, in_addr, iovec, ip_mreq, ipv6_mreq, linger, siginfo_t, sockaddr, sockaddr_in, - sockaddr_in6, sockaddr_un, socklen_t, AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, - AF_BLUETOOTH, AF_BRIDGE, AF_CAN, AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, - AF_ISDN, AF_IUCV, AF_KEY, AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, - AF_PPPOX, AF_RDS, AF_ROSE, AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, - AF_WANPIPE, AF_X25, CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, - CLD_TRAPPED, IPPROTO_AH, IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, - IPPROTO_ENCAP, IPPROTO_ESP, IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, - IPPROTO_ICMPV6, IPPROTO_IDP, IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, - IPPROTO_MPLS, IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, - IPPROTO_ROUTING, IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, - IPPROTO_UDPLITE, IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_LOOP, - IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, - IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, - MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, O_CLOEXEC, - O_NONBLOCK, O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PID, P_PIDFD, SHUT_RD, SHUT_RDWR, SHUT_WR, - SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, - SO_ERROR, SO_KEEPALIVE, SO_LINGER, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, - SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD, SO_TYPE, TCP_NODELAY, + __kernel_pid_t as pid_t, __kernel_time64_t as time_t, __kernel_timespec as timespec, iovec, + O_CLOEXEC, O_NOCTTY, O_NONBLOCK, O_RDWR, }; -pub(crate) use linux_raw_sys::general::{NFS_SUPER_MAGIC, PROC_SUPER_MAGIC, UTIME_NOW, UTIME_OMIT}; -pub(crate) use linux_raw_sys::general::{XATTR_CREATE, XATTR_REPLACE}; + +#[cfg(feature = "event")] +#[cfg(test)] +pub(crate) use linux_raw_sys::general::epoll_event; + +#[cfg(any( + feature = "fs", + all( + not(feature = "use-libc-auxv"), + not(target_vendor = "mustang"), + any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86", + ) + ) +))] +pub(crate) use linux_raw_sys::general::{ + AT_FDCWD, NFS_SUPER_MAGIC, O_LARGEFILE, PROC_SUPER_MAGIC, UTIME_NOW, UTIME_OMIT, XATTR_CREATE, + XATTR_REPLACE, +}; + +#[cfg(feature = "io_uring")] +pub(crate) use linux_raw_sys::{general::open_how, io_uring::*}; + +#[cfg(feature = "net")] +pub(crate) use linux_raw_sys::{ + cmsg_macros::*, + general::{O_CLOEXEC as SOCK_CLOEXEC, O_NONBLOCK as SOCK_NONBLOCK}, + if_ether::*, + net::{ + AF_DECnet, __kernel_sa_family_t as sa_family_t, + __kernel_sockaddr_storage as sockaddr_storage, cmsghdr, in6_addr, in_addr, ip_mreq, + ipv6_mreq, linger, msghdr, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, + AF_APPLETALK, AF_ASH, AF_ATMPVC, AF_ATMSVC, AF_AX25, AF_BLUETOOTH, AF_BRIDGE, AF_CAN, + AF_ECONET, AF_IEEE802154, AF_INET, AF_INET6, AF_IPX, AF_IRDA, AF_ISDN, AF_IUCV, AF_KEY, + AF_LLC, AF_NETBEUI, AF_NETLINK, AF_NETROM, AF_PACKET, AF_PHONET, AF_PPPOX, AF_RDS, AF_ROSE, + AF_RXRPC, AF_SECURITY, AF_SNA, AF_TIPC, AF_UNIX, AF_UNSPEC, AF_WANPIPE, AF_X25, IPPROTO_AH, + IPPROTO_BEETPH, IPPROTO_COMP, IPPROTO_DCCP, IPPROTO_EGP, IPPROTO_ENCAP, IPPROTO_ESP, + IPPROTO_ETHERNET, IPPROTO_FRAGMENT, IPPROTO_GRE, IPPROTO_ICMP, IPPROTO_ICMPV6, IPPROTO_IDP, + IPPROTO_IGMP, IPPROTO_IP, IPPROTO_IPIP, IPPROTO_IPV6, IPPROTO_MH, IPPROTO_MPLS, + IPPROTO_MPTCP, IPPROTO_MTP, IPPROTO_PIM, IPPROTO_PUP, IPPROTO_RAW, IPPROTO_ROUTING, + IPPROTO_RSVP, IPPROTO_SCTP, IPPROTO_TCP, IPPROTO_TP, IPPROTO_UDP, IPPROTO_UDPLITE, + IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP, IPV6_MULTICAST_HOPS, IPV6_MULTICAST_LOOP, + IPV6_UNICAST_HOPS, IPV6_V6ONLY, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP, IP_MULTICAST_LOOP, + IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, + MSG_EOR, MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, + SCM_CREDENTIALS, SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, + SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_LINGER, + SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD, + SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD, + SO_TYPE, TCP_NODELAY, + }, + netlink::*, +}; + +#[cfg(any(feature = "process", feature = "runtime"))] +pub(crate) use linux_raw_sys::general::siginfo_t; + +#[cfg(feature = "process")] +pub(crate) use linux_raw_sys::general::{ + CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, + O_NONBLOCK as PIDFD_NONBLOCK, P_ALL, P_PID, P_PIDFD, +}; + +#[cfg(feature = "termios")] +pub(crate) use linux_raw_sys::{ + general::{ + cc_t, speed_t, tcflag_t, termios, termios2, winsize, B0, B1000000, B110, B115200, B1152000, + B1200, B134, B150, B1500000, B1800, B19200, B200, B2000000, B230400, B2400, B2500000, B300, + B3000000, B3500000, B38400, B4000000, B460800, B4800, B50, B500000, B57600, B576000, B600, + B75, B921600, B9600, BOTHER, BRKINT, BS0, BS1, BSDLY, CBAUD, CBAUDEX, CIBAUD, CLOCAL, + CMSPAR, CR0, CR1, CR2, CR3, CRDLY, CREAD, CRTSCTS, CS5, CS6, CS7, CS8, CSIZE, CSTOPB, ECHO, + ECHOCTL, ECHOE, ECHOK, ECHOKE, ECHONL, ECHOPRT, EXTA, EXTB, EXTPROC, FF0, FF1, FFDLY, + FLUSHO, HUPCL, IBSHIFT, ICANON, ICRNL, IEXTEN, IGNBRK, IGNCR, IGNPAR, IMAXBEL, INLCR, + INPCK, ISIG, ISTRIP, IUCLC, IUTF8, IXANY, IXOFF, IXON, NCCS, NL0, NL1, NLDLY, NOFLSH, + OCRNL, OFDEL, OFILL, OLCUC, ONLCR, ONLRET, ONOCR, OPOST, PARENB, PARMRK, PARODD, PENDIN, + TAB0, TAB1, TAB2, TAB3, TABDLY, TCIFLUSH, TCIOFF, TCIOFLUSH, TCION, TCOFLUSH, TCOOFF, + TCOON, TCSADRAIN, TCSAFLUSH, TCSANOW, TOSTOP, VDISCARD, VEOF, VEOL, VEOL2, VERASE, VINTR, + VKILL, VLNEXT, VMIN, VQUIT, VREPRINT, VSTART, VSTOP, VSUSP, VSWTC, VT0, VT1, VTDLY, VTIME, + VWERASE, XCASE, XTABS, + }, + ioctl::{TCGETS2, TCSETS2, TCSETSF2, TCSETSW2}, +}; + +// On MIPS, `TCSANOW` et al have `TCSETS` added to them, so we need it to +// subtract it out. +#[cfg(all(feature = "termios", any(target_arch = "mips", target_arch = "mips64")))] +pub(crate) use linux_raw_sys::ioctl::TCSETS; + +// Define our own `uid_t` and `gid_t` if the kernel's versions are not 32-bit. +#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] +pub(crate) type uid_t = u32; +#[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] +pub(crate) type gid_t = u32; + +// Bindgen infers `u32` for many of these macro types which meant to be +// used with `c_int` in the C APIs, so cast them to `c_int`. + +// Convert the signal constants from `u32` to `c_int`. +pub(crate) const SIGHUP: c_int = linux_raw_sys::general::SIGHUP as _; +pub(crate) const SIGINT: c_int = linux_raw_sys::general::SIGINT as _; +pub(crate) const SIGQUIT: c_int = linux_raw_sys::general::SIGQUIT as _; +pub(crate) const SIGILL: c_int = linux_raw_sys::general::SIGILL as _; +pub(crate) const SIGTRAP: c_int = linux_raw_sys::general::SIGTRAP as _; +pub(crate) const SIGABRT: c_int = linux_raw_sys::general::SIGABRT as _; +pub(crate) const SIGBUS: c_int = linux_raw_sys::general::SIGBUS as _; +pub(crate) const SIGFPE: c_int = linux_raw_sys::general::SIGFPE as _; +pub(crate) const SIGKILL: c_int = linux_raw_sys::general::SIGKILL as _; +pub(crate) const SIGUSR1: c_int = linux_raw_sys::general::SIGUSR1 as _; +pub(crate) const SIGSEGV: c_int = linux_raw_sys::general::SIGSEGV as _; +pub(crate) const SIGUSR2: c_int = linux_raw_sys::general::SIGUSR2 as _; +pub(crate) const SIGPIPE: c_int = linux_raw_sys::general::SIGPIPE as _; +pub(crate) const SIGALRM: c_int = linux_raw_sys::general::SIGALRM as _; +pub(crate) const SIGTERM: c_int = linux_raw_sys::general::SIGTERM as _; +#[cfg(not(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc", + target_arch = "sparc64" +)))] +pub(crate) const SIGSTKFLT: c_int = linux_raw_sys::general::SIGSTKFLT as _; +pub(crate) const SIGCHLD: c_int = linux_raw_sys::general::SIGCHLD as _; +pub(crate) const SIGCONT: c_int = linux_raw_sys::general::SIGCONT as _; +pub(crate) const SIGSTOP: c_int = linux_raw_sys::general::SIGSTOP as _; +pub(crate) const SIGTSTP: c_int = linux_raw_sys::general::SIGTSTP as _; +pub(crate) const SIGTTIN: c_int = linux_raw_sys::general::SIGTTIN as _; +pub(crate) const SIGTTOU: c_int = linux_raw_sys::general::SIGTTOU as _; +pub(crate) const SIGURG: c_int = linux_raw_sys::general::SIGURG as _; +pub(crate) const SIGXCPU: c_int = linux_raw_sys::general::SIGXCPU as _; +pub(crate) const SIGXFSZ: c_int = linux_raw_sys::general::SIGXFSZ as _; +pub(crate) const SIGVTALRM: c_int = linux_raw_sys::general::SIGVTALRM as _; +pub(crate) const SIGPROF: c_int = linux_raw_sys::general::SIGPROF as _; +pub(crate) const SIGWINCH: c_int = linux_raw_sys::general::SIGWINCH as _; +pub(crate) const SIGIO: c_int = linux_raw_sys::general::SIGIO as _; +pub(crate) const SIGPWR: c_int = linux_raw_sys::general::SIGPWR as _; +pub(crate) const SIGSYS: c_int = linux_raw_sys::general::SIGSYS as _; +#[cfg(any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc", + target_arch = "sparc64" +))] +pub(crate) const SIGEMT: c_int = linux_raw_sys::general::SIGEMT as _; + +#[cfg(feature = "stdio")] +pub(crate) const STDIN_FILENO: c_int = linux_raw_sys::general::STDIN_FILENO as _; +#[cfg(feature = "stdio")] +pub(crate) const STDOUT_FILENO: c_int = linux_raw_sys::general::STDOUT_FILENO as _; +#[cfg(feature = "stdio")] +pub(crate) const STDERR_FILENO: c_int = linux_raw_sys::general::STDERR_FILENO as _; + +pub(crate) const PIPE_BUF: usize = linux_raw_sys::general::PIPE_BUF as _; + +pub(crate) const CLOCK_MONOTONIC: c_int = linux_raw_sys::general::CLOCK_MONOTONIC as _; +pub(crate) const CLOCK_REALTIME: c_int = linux_raw_sys::general::CLOCK_REALTIME as _; +pub(crate) const CLOCK_MONOTONIC_RAW: c_int = linux_raw_sys::general::CLOCK_MONOTONIC_RAW as _; +pub(crate) const CLOCK_MONOTONIC_COARSE: c_int = + linux_raw_sys::general::CLOCK_MONOTONIC_COARSE as _; +pub(crate) const CLOCK_REALTIME_COARSE: c_int = linux_raw_sys::general::CLOCK_REALTIME_COARSE as _; +pub(crate) const CLOCK_THREAD_CPUTIME_ID: c_int = + linux_raw_sys::general::CLOCK_THREAD_CPUTIME_ID as _; +pub(crate) const CLOCK_PROCESS_CPUTIME_ID: c_int = + linux_raw_sys::general::CLOCK_PROCESS_CPUTIME_ID as _; diff --git a/vendor/rustix/src/backend/linux_raw/conv.rs b/vendor/rustix/src/backend/linux_raw/conv.rs index f02b5c046..05d040204 100644 --- a/vendor/rustix/src/backend/linux_raw/conv.rs +++ b/vendor/rustix/src/backend/linux_raw/conv.rs @@ -20,22 +20,27 @@ use super::io::errno::try_decode_error; #[cfg(target_pointer_width = "64")] use super::io::errno::try_decode_u64; #[cfg(not(debug_assertions))] -use super::io::errno::{decode_c_uint_infallible, decode_usize_infallible}; +use super::io::errno::{ + decode_c_int_infallible, decode_c_uint_infallible, decode_usize_infallible, +}; use super::io::errno::{ try_decode_c_int, try_decode_c_uint, try_decode_raw_fd, try_decode_usize, try_decode_void, try_decode_void_star, }; use super::reg::{raw_arg, ArgNumber, ArgReg, RetReg, R0}; -#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] -use super::time::types::ClockId; #[cfg(feature = "time")] use super::time::types::TimerfdClockId; +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +use crate::clockid::ClockId; use crate::fd::OwnedFd; use crate::ffi::CStr; -#[cfg(feature = "fs")] -use crate::fs::{FileType, Mode, OFlags}; use crate::io; -use crate::process::{Pid, Resource, Signal}; +#[cfg(any(feature = "process", feature = "runtime", feature = "termios"))] +use crate::pid::Pid; +#[cfg(feature = "process")] +use crate::process::Resource; +#[cfg(any(feature = "process", feature = "runtime"))] +use crate::signal::Signal; use crate::utils::{as_mut_ptr, as_ptr}; use core::mem::MaybeUninit; use core::ptr::null_mut; @@ -44,10 +49,7 @@ use linux_raw_sys::general::__kernel_clockid_t; #[cfg(target_pointer_width = "64")] use linux_raw_sys::general::__kernel_loff_t; #[cfg(feature = "net")] -use linux_raw_sys::general::socklen_t; -#[cfg(target_pointer_width = "32")] -#[cfg(feature = "fs")] -use linux_raw_sys::general::O_LARGEFILE; +use linux_raw_sys::net::socklen_t; /// Convert `SYS_*` constants for socketcall. #[cfg(target_arch = "x86")] @@ -143,9 +145,9 @@ impl<'a, Num: ArgNumber> From<Option<&'a CStr>> for ArgReg<'a, Num> { impl<'a, Num: ArgNumber> From<BorrowedFd<'a>> for ArgReg<'a, Num> { #[inline] fn from(fd: BorrowedFd<'a>) -> Self { - // SAFETY: `BorrowedFd` ensures that the file descriptor is valid, and the - // lifetime parameter on the resulting `ArgReg` ensures that the result is - // bounded by the `BorrowedFd`'s lifetime. + // SAFETY: `BorrowedFd` ensures that the file descriptor is valid, and + // the lifetime parameter on the resulting `ArgReg` ensures that the + // result is bounded by the `BorrowedFd`'s lifetime. unsafe { raw_fd(fd.as_raw_fd()) } } } @@ -160,7 +162,7 @@ impl<'a, Num: ArgNumber> From<BorrowedFd<'a>> for ArgReg<'a, Num> { pub(super) unsafe fn raw_fd<'a, Num: ArgNumber>(fd: RawFd) -> ArgReg<'a, Num> { // Use `no_fd` when passing `-1` is intended. #[cfg(feature = "fs")] - debug_assert!(fd == crate::fs::cwd().as_raw_fd() || fd >= 0); + debug_assert!(fd == crate::fs::CWD.as_raw_fd() || fd >= 0); // Don't pass the `io_uring_register_files_skip` sentry value this way. #[cfg(feature = "io_uring")] @@ -294,116 +296,235 @@ pub(super) fn socklen_t<'a, Num: ArgNumber>(i: socklen_t) -> ArgReg<'a, Num> { pass_usize(i as usize) } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<Mode> for ArgReg<'a, Num> { - #[inline] - fn from(mode: Mode) -> Self { - pass_usize(mode.bits() as usize) +#[cfg(any( + feature = "fs", + all( + not(feature = "use-libc-auxv"), + not(target_vendor = "mustang"), + any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86", + ) + ) +))] +pub(crate) mod fs { + use super::*; + use crate::fs::{FileType, Mode, OFlags}; + #[cfg(target_pointer_width = "32")] + use linux_raw_sys::general::O_LARGEFILE; + + impl<'a, Num: ArgNumber> From<Mode> for ArgReg<'a, Num> { + #[inline] + fn from(mode: Mode) -> Self { + pass_usize(mode.bits() as usize) + } } -} -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<(Mode, FileType)> for ArgReg<'a, Num> { - #[inline] - fn from(pair: (Mode, FileType)) -> Self { - pass_usize(pair.0.as_raw_mode() as usize | pair.1.as_raw_mode() as usize) + impl<'a, Num: ArgNumber> From<(Mode, FileType)> for ArgReg<'a, Num> { + #[inline] + fn from(pair: (Mode, FileType)) -> Self { + pass_usize(pair.0.as_raw_mode() as usize | pair.1.as_raw_mode() as usize) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::AtFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::AtFlags) -> Self { + c_uint(flags.bits()) + } } -} -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::AtFlags> for ArgReg<'a, Num> { + impl<'a, Num: ArgNumber> From<crate::fs::XattrFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::XattrFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::inotify::CreateFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::inotify::CreateFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::inotify::WatchFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::inotify::WatchFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::MemfdFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::MemfdFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::RenameFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::RenameFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::StatxFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::StatxFlags) -> Self { + c_uint(flags.bits()) + } + } + + #[cfg(target_pointer_width = "32")] #[inline] - fn from(flags: crate::fs::AtFlags) -> Self { - c_uint(flags.bits()) + fn oflags_bits(oflags: OFlags) -> c::c_uint { + let mut bits = oflags.bits(); + // Add `O_LARGEFILE`, unless `O_PATH` is set, as Linux returns `EINVAL` + // when both are set. + if !oflags.contains(OFlags::PATH) { + bits |= O_LARGEFILE; + } + bits } -} -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::XattrFlags> for ArgReg<'a, Num> { + #[cfg(target_pointer_width = "64")] #[inline] - fn from(flags: crate::fs::XattrFlags) -> Self { - c_uint(flags.bits()) + const fn oflags_bits(oflags: OFlags) -> c::c_uint { + oflags.bits() } -} -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::inotify::CreateFlags> for ArgReg<'a, Num> { + impl<'a, Num: ArgNumber> From<OFlags> for ArgReg<'a, Num> { + #[inline] + fn from(oflags: OFlags) -> Self { + pass_usize(oflags_bits(oflags) as usize) + } + } + + /// Convert an `OFlags` into a `u64` for use in the `open_how` struct. #[inline] - fn from(flags: crate::fs::inotify::CreateFlags) -> Self { - c_uint(flags.bits()) + pub(crate) fn oflags_for_open_how(oflags: OFlags) -> u64 { + u64::from(oflags_bits(oflags)) + } + + impl<'a, Num: ArgNumber> From<crate::fs::FallocateFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::FallocateFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::Advice> for ArgReg<'a, Num> { + #[inline] + fn from(advice: crate::fs::Advice) -> Self { + c_uint(advice as c::c_uint) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::SealFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::SealFlags) -> Self { + c_uint(flags.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::fs::Access> for ArgReg<'a, Num> { + #[inline] + fn from(access: crate::fs::Access) -> Self { + c_uint(access.bits()) + } + } + + impl<'a, Num: ArgNumber> From<crate::backend::fs::types::MountFlagsArg> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::fs::types::MountFlagsArg) -> Self { + c_uint(flags.0) + } + } + + impl<'a, Num: ArgNumber> From<crate::backend::fs::types::UnmountFlags> for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::fs::types::UnmountFlags) -> Self { + c_uint(flags.bits()) + } } } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::inotify::WatchFlags> for ArgReg<'a, Num> { +impl<'a, Num: ArgNumber> From<crate::io::FdFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::fs::inotify::WatchFlags) -> Self { + fn from(flags: crate::io::FdFlags) -> Self { c_uint(flags.bits()) } } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::MemfdFlags> for ArgReg<'a, Num> { +#[cfg(feature = "pipe")] +impl<'a, Num: ArgNumber> From<crate::pipe::PipeFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::fs::MemfdFlags) -> Self { + fn from(flags: crate::pipe::PipeFlags) -> Self { c_uint(flags.bits()) } } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::RenameFlags> for ArgReg<'a, Num> { +#[cfg(feature = "pipe")] +impl<'a, Num: ArgNumber> From<crate::pipe::SpliceFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::fs::RenameFlags) -> Self { + fn from(flags: crate::pipe::SpliceFlags) -> Self { c_uint(flags.bits()) } } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::StatxFlags> for ArgReg<'a, Num> { +impl<'a, Num: ArgNumber> From<crate::io::DupFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::fs::StatxFlags) -> Self { + fn from(flags: crate::io::DupFlags) -> Self { c_uint(flags.bits()) } } -impl<'a, Num: ArgNumber> From<crate::io::FdFlags> for ArgReg<'a, Num> { +impl<'a, Num: ArgNumber> From<crate::io::ReadWriteFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::io::FdFlags) -> Self { + fn from(flags: crate::io::ReadWriteFlags) -> Self { c_uint(flags.bits()) } } -impl<'a, Num: ArgNumber> From<crate::io::PipeFlags> for ArgReg<'a, Num> { +#[cfg(feature = "process")] +impl<'a, Num: ArgNumber> From<crate::process::PidfdFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::io::PipeFlags) -> Self { + fn from(flags: crate::process::PidfdFlags) -> Self { c_uint(flags.bits()) } } -impl<'a, Num: ArgNumber> From<crate::io::DupFlags> for ArgReg<'a, Num> { +#[cfg(feature = "pty")] +impl<'a, Num: ArgNumber> From<crate::pty::OpenptFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::io::DupFlags) -> Self { + fn from(flags: crate::pty::OpenptFlags) -> Self { c_uint(flags.bits()) } } -impl<'a, Num: ArgNumber> From<crate::io::ReadWriteFlags> for ArgReg<'a, Num> { +#[cfg(feature = "thread")] +impl<'a, Num: ArgNumber> From<crate::thread::UnshareFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::io::ReadWriteFlags) -> Self { + fn from(flags: crate::thread::UnshareFlags) -> Self { c_uint(flags.bits()) } } -impl<'a, Num: ArgNumber> From<crate::io::EventfdFlags> for ArgReg<'a, Num> { +#[cfg(feature = "event")] +impl<'a, Num: ArgNumber> From<crate::event::EventfdFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::io::EventfdFlags) -> Self { + fn from(flags: crate::event::EventfdFlags) -> Self { c_uint(flags.bits()) } } -impl<'a, Num: ArgNumber> From<crate::io::epoll::CreateFlags> for ArgReg<'a, Num> { +#[cfg(feature = "event")] +impl<'a, Num: ArgNumber> From<crate::event::epoll::CreateFlags> for ArgReg<'a, Num> { #[inline] - fn from(flags: crate::io::epoll::CreateFlags) -> Self { + fn from(flags: crate::event::epoll::CreateFlags) -> Self { c_uint(flags.bits()) } } @@ -464,6 +585,7 @@ impl<'a, Num: ArgNumber> From<crate::backend::mm::types::UserfaultfdFlags> for A } } +#[cfg(feature = "process")] impl<'a, Num: ArgNumber> From<crate::backend::process::types::MembarrierCommand> for ArgReg<'a, Num> { @@ -473,6 +595,7 @@ impl<'a, Num: ArgNumber> From<crate::backend::process::types::MembarrierCommand> } } +#[cfg(feature = "process")] impl<'a, Num: ArgNumber> From<crate::process::Cpuid> for ArgReg<'a, Num> { #[inline] fn from(cpuid: crate::process::Cpuid) -> Self { @@ -489,54 +612,11 @@ pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> ArgReg<'a, Num> { #[cfg(target_pointer_width = "32")] #[inline] pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> io::Result<ArgReg<'a, Num>> { - use core::convert::TryInto; Ok(pass_usize(dev.try_into().map_err(|_err| io::Errno::INVAL)?)) } -#[cfg(target_pointer_width = "32")] -#[cfg(feature = "fs")] -#[inline] -fn oflags_bits(oflags: OFlags) -> c::c_uint { - let mut bits = oflags.bits(); - // Add `O_LARGEFILE`, unless `O_PATH` is set, as Linux returns `EINVAL` - // when both are set. - if !oflags.contains(OFlags::PATH) { - bits |= O_LARGEFILE; - } - bits -} - -#[cfg(target_pointer_width = "64")] -#[cfg(feature = "fs")] -#[inline] -const fn oflags_bits(oflags: OFlags) -> c::c_uint { - oflags.bits() -} - -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<OFlags> for ArgReg<'a, Num> { - #[inline] - fn from(oflags: OFlags) -> Self { - pass_usize(oflags_bits(oflags) as usize) - } -} - -/// Convert an `OFlags` into a `u64` for use in the `open_how` struct. -#[cfg(feature = "fs")] -#[inline] -pub(super) fn oflags_for_open_how(oflags: OFlags) -> u64 { - u64::from(oflags_bits(oflags)) -} - -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::FallocateFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::FallocateFlags) -> Self { - c_uint(flags.bits()) - } -} - /// Convert a `Resource` into a syscall argument. +#[cfg(feature = "process")] impl<'a, Num: ArgNumber> From<Resource> for ArgReg<'a, Num> { #[inline] fn from(resource: Resource) -> Self { @@ -544,6 +624,7 @@ impl<'a, Num: ArgNumber> From<Resource> for ArgReg<'a, Num> { } } +#[cfg(any(feature = "process", feature = "runtime", feature = "termios"))] impl<'a, Num: ArgNumber> From<Pid> for ArgReg<'a, Num> { #[inline] fn from(pid: Pid) -> Self { @@ -551,11 +632,13 @@ impl<'a, Num: ArgNumber> From<Pid> for ArgReg<'a, Num> { } } +#[cfg(feature = "process")] #[inline] pub(super) fn negative_pid<'a, Num: ArgNumber>(pid: Pid) -> ArgReg<'a, Num> { pass_usize(pid.as_raw_nonzero().get().wrapping_neg() as usize) } +#[cfg(any(feature = "process", feature = "runtime"))] impl<'a, Num: ArgNumber> From<Signal> for ArgReg<'a, Num> { #[inline] fn from(sig: Signal) -> Self { @@ -563,22 +646,6 @@ impl<'a, Num: ArgNumber> From<Signal> for ArgReg<'a, Num> { } } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::Advice> for ArgReg<'a, Num> { - #[inline] - fn from(advice: crate::fs::Advice) -> Self { - c_uint(advice as c::c_uint) - } -} - -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::SealFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::SealFlags) -> Self { - c_uint(flags.bits()) - } -} - #[cfg(feature = "io_uring")] impl<'a, Num: ArgNumber> From<crate::io_uring::IoringEnterFlags> for ArgReg<'a, Num> { #[inline] @@ -663,14 +730,6 @@ impl<'a, Num: ArgNumber> From<(crate::thread::FutexOperation, crate::thread::Fut } } -#[cfg(feature = "fs")] -impl<'a, Num: ArgNumber> From<crate::fs::Access> for ArgReg<'a, Num> { - #[inline] - fn from(access: crate::fs::Access) -> Self { - c_uint(access.bits()) - } -} - #[cfg(feature = "net")] impl<'a, Num: ArgNumber> From<crate::net::SocketType> for ArgReg<'a, Num> { #[inline] @@ -680,10 +739,13 @@ impl<'a, Num: ArgNumber> From<crate::net::SocketType> for ArgReg<'a, Num> { } #[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<crate::net::Protocol> for ArgReg<'a, Num> { +impl<'a, Num: ArgNumber> From<Option<crate::net::Protocol>> for ArgReg<'a, Num> { #[inline] - fn from(protocol: crate::net::Protocol) -> Self { - c_uint(protocol.0) + fn from(protocol: Option<crate::net::Protocol>) -> Self { + c_uint(match protocol { + Some(p) => p.0.get(), + None => 0, + }) } } @@ -701,34 +763,18 @@ impl<'a, Num: ArgNumber, T> From<&'a mut [MaybeUninit<T>]> for ArgReg<'a, Num> { } } -#[cfg(feature = "fs")] -#[cfg(any(target_os = "android", target_os = "linux"))] -impl<'a, Num: ArgNumber> From<crate::backend::fs::types::MountFlagsArg> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::fs::types::MountFlagsArg) -> Self { - c_uint(flags.0) - } -} - -#[cfg(feature = "fs")] -#[cfg(any(target_os = "android", target_os = "linux"))] -impl<'a, Num: ArgNumber> From<crate::backend::fs::types::UnmountFlags> for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::backend::fs::types::UnmountFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From<crate::process::Uid> for ArgReg<'a, Num> { +#[cfg(any(feature = "process", feature = "thread"))] +impl<'a, Num: ArgNumber> From<crate::ugid::Uid> for ArgReg<'a, Num> { #[inline] - fn from(t: crate::process::Uid) -> Self { + fn from(t: crate::ugid::Uid) -> Self { c_uint(t.as_raw()) } } -impl<'a, Num: ArgNumber> From<crate::process::Gid> for ArgReg<'a, Num> { +#[cfg(any(feature = "process", feature = "thread"))] +impl<'a, Num: ArgNumber> From<crate::ugid::Gid> for ArgReg<'a, Num> { #[inline] - fn from(t: crate::process::Gid) -> Self { + fn from(t: crate::ugid::Gid) -> Self { c_uint(t.as_raw()) } } @@ -830,6 +876,25 @@ pub(super) unsafe fn ret_usize_infallible(raw: RetReg<R0>) -> usize { } } +/// Convert a `c_int` returned from a syscall that effectively always +/// returns a `c_int`. +/// +/// # Safety +/// +/// This function must only be used with return values from infallible +/// syscalls. +#[inline] +pub(super) unsafe fn ret_c_int_infallible(raw: RetReg<R0>) -> c::c_int { + #[cfg(debug_assertions)] + { + try_decode_c_int(raw).unwrap() + } + #[cfg(not(debug_assertions))] + { + decode_c_int_infallible(raw) + } +} + /// Convert a `c_uint` returned from a syscall that effectively always /// returns a `c_uint`. /// diff --git a/vendor/rustix/src/backend/linux_raw/elf.rs b/vendor/rustix/src/backend/linux_raw/elf.rs index 87fb5fa0f..7797f4e21 100644 --- a/vendor/rustix/src/backend/linux_raw/elf.rs +++ b/vendor/rustix/src/backend/linux_raw/elf.rs @@ -1,4 +1,4 @@ -//! The ELF ABI. +//! The ELF ABI. 🧝 #![allow(non_snake_case)] #![cfg_attr( diff --git a/vendor/rustix/src/backend/linux_raw/io/epoll.rs b/vendor/rustix/src/backend/linux_raw/event/epoll.rs index 3fc6462a2..6577feb51 100644 --- a/vendor/rustix/src/backend/linux_raw/io/epoll.rs +++ b/vendor/rustix/src/backend/linux_raw/event/epoll.rs @@ -7,45 +7,50 @@ //! # Examples //! //! ```no_run -//! # #![cfg_attr(io_lifetimes_use_std, feature(io_safety))] //! # #[cfg(feature = "net")] //! # fn main() -> std::io::Result<()> { -//! use io_lifetimes::AsFd; -//! use rustix::io::{epoll, ioctl_fionbio, read, write}; +//! use rustix::event::epoll; +//! use rustix::fd::AsFd; +//! use rustix::io::{ioctl_fionbio, read, write}; //! use rustix::net::{ -//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4, -//! SocketType, +//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, SocketAddrV4, SocketType, //! }; //! use std::collections::HashMap; //! use std::os::unix::io::AsRawFd; //! //! // Create a socket and listen on it. -//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; +//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, None)?; //! bind_v4(&listen_sock, &SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0))?; //! listen(&listen_sock, 1)?; //! //! // Create an epoll object. Using `Owning` here means the epoll object will //! // take ownership of the file descriptors registered with it. -//! let epoll = epoll::epoll_create(epoll::CreateFlags::CLOEXEC)?; +//! let epoll = epoll::create(epoll::CreateFlags::CLOEXEC)?; //! //! // Register the socket with the epoll object. -//! epoll::epoll_add(&epoll, &listen_sock, 1, epoll::EventFlags::IN)?; +//! epoll::add( +//! &epoll, +//! &listen_sock, +//! epoll::EventData::new_u64(1), +//! epoll::EventFlags::IN, +//! )?; //! //! // Keep track of the sockets we've opened. -//! let mut next_id = 2; +//! let mut next_id = epoll::EventData::new_u64(2); //! let mut sockets = HashMap::new(); //! //! // Process events. //! let mut event_list = epoll::EventVec::with_capacity(4); //! loop { -//! epoll::epoll_wait(&epoll, &mut event_list, -1)?; -//! for (_event_flags, target) in &event_list { -//! if target == 1 { +//! epoll::wait(&epoll, &mut event_list, -1)?; +//! for event in &event_list { +//! let target = event.data; +//! if target.u64() == 1 { //! // Accept a new connection, set it to non-blocking, and //! // register to be notified when it's ready to write to. //! let conn_sock = accept(&listen_sock)?; //! ioctl_fionbio(&conn_sock, true)?; -//! epoll::epoll_add( +//! epoll::add( //! &epoll, //! &conn_sock, //! next_id, @@ -54,12 +59,12 @@ //! //! // Keep track of the socket. //! sockets.insert(next_id, conn_sock); -//! next_id += 1; +//! next_id = epoll::EventData::new_u64(next_id.u64() + 1); //! } else { //! // Write a message to the stream and then unregister it. //! let target = sockets.remove(&target).unwrap(); //! write(&target, b"hello\n")?; -//! let _ = epoll::epoll_del(&epoll, &target)?; +//! let _ = epoll::delete(&epoll, &target)?; //! } //! } //! } @@ -70,15 +75,20 @@ #![allow(unsafe_code)] -use super::super::c; -use crate::backend::io::syscalls; +use crate::backend::c; +use crate::backend::event::syscalls; use crate::fd::{AsFd, AsRawFd, OwnedFd}; use crate::io; use alloc::vec::Vec; use bitflags::bitflags; +use core::ffi::c_void; +use core::hash::{Hash, Hasher}; +use core::slice; bitflags! { - /// `EPOLL_*` for use with [`Epoll::new`]. + /// `EPOLL_*` for use with [`new`]. + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct CreateFlags: c::c_uint { /// `EPOLL_CLOEXEC` const CLOEXEC = linux_raw_sys::general::EPOLL_CLOEXEC; @@ -86,8 +96,9 @@ bitflags! { } bitflags! { - /// `EPOLL*` for use with [`Epoll::add`]. - #[derive(Default)] + /// `EPOLL*` for use with [`add`]. + #[repr(transparent)] + #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct EventFlags: u32 { /// `EPOLLIN` const IN = linux_raw_sys::general::EPOLLIN as u32; @@ -136,33 +147,34 @@ bitflags! { } } -/// `epoll_create1(flags)`—Creates a new `Epoll`. +/// `epoll_create1(flags)`—Creates a new epoll object. /// /// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file /// descriptor from being implicitly passed across `exec` boundaries. #[inline] #[doc(alias = "epoll_create1")] -pub fn epoll_create(flags: CreateFlags) -> io::Result<OwnedFd> { +pub fn create(flags: CreateFlags) -> io::Result<OwnedFd> { syscalls::epoll_create(flags) } /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an -/// `Epoll`. +/// epoll object. /// /// This registers interest in any of the events set in `events` occurring /// on the file descriptor associated with `data`. /// -/// Note that if `epoll_del` is not called on the I/O source passed into -/// this function before the I/O source is `close`d, then the `epoll` will -/// act as if the I/O source is still registered with it. This can lead to -/// spurious events being returned from `epoll_wait`. If a file descriptor -/// is an `Arc<dyn SystemResource>`, then `epoll` can be thought to maintain -/// a `Weak<dyn SystemResource>` to the file descriptor. +/// If [`delete`] is not called on the I/O source passed into this function +/// before the I/O source is `close`d, then the `epoll` will act as if the I/O +/// source is still registered with it. This can lead to spurious events being +/// returned from [`wait`]. If a file descriptor is an +/// `Arc<dyn SystemResource>`, then `epoll` can be thought to maintain a +/// `Weak<dyn SystemResource>` to the file descriptor. #[doc(alias = "epoll_ctl")] -pub fn epoll_add( +#[inline] +pub fn add( epoll: impl AsFd, source: impl AsFd, - data: u64, + data: EventData, event_flags: EventFlags, ) -> io::Result<()> { // SAFETY: We're calling `epoll_ctl` via FFI and we know how it @@ -171,8 +183,8 @@ pub fn epoll_add( syscalls::epoll_add( epoll.as_fd(), source.as_fd().as_raw_fd(), - &linux_raw_sys::general::epoll_event { - events: event_flags.bits(), + &Event { + flags: event_flags, data, }, ) @@ -180,14 +192,15 @@ pub fn epoll_add( } /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in -/// this `Epoll`. +/// a given epoll object. /// /// This sets the events of interest with `target` to `events`. #[doc(alias = "epoll_ctl")] -pub fn epoll_mod( +#[inline] +pub fn modify( epoll: impl AsFd, source: impl AsFd, - data: u64, + data: EventData, event_flags: EventFlags, ) -> io::Result<()> { // SAFETY: We're calling `epoll_ctl` via FFI and we know how it @@ -197,8 +210,8 @@ pub fn epoll_mod( syscalls::epoll_mod( epoll.as_fd(), raw_fd, - &linux_raw_sys::general::epoll_event { - events: event_flags.bits(), + &Event { + flags: event_flags, data, }, ) @@ -206,11 +219,10 @@ pub fn epoll_mod( } /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in -/// this `Epoll`. -/// -/// This also returns the owning `Data`. +/// a given epoll object. #[doc(alias = "epoll_ctl")] -pub fn epoll_del(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { +#[inline] +pub fn delete(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { // SAFETY: We're calling `epoll_ctl` via FFI and we know how it // behaves. unsafe { @@ -224,11 +236,8 @@ pub fn epoll_del(epoll: impl AsFd, source: impl AsFd) -> io::Result<()> { /// /// For each event of interest, an element is written to `events`. On /// success, this returns the number of written elements. -pub fn epoll_wait( - epoll: impl AsFd, - event_list: &mut EventVec, - timeout: c::c_int, -) -> io::Result<()> { +#[inline] +pub fn wait(epoll: impl AsFd, event_list: &mut EventVec, timeout: c::c_int) -> io::Result<()> { // SAFETY: We're calling `epoll_wait` via FFI and we know how it // behaves. unsafe { @@ -247,27 +256,112 @@ pub fn epoll_wait( /// An iterator over the `Event`s in an `EventVec`. pub struct Iter<'a> { - iter: core::slice::Iter<'a, Event>, + /// Use `Copied` to copy the struct, since `Event` is `packed` on some + /// platforms, and it's common for users to directly destructure it, + /// which would lead to errors about forming references to packed fields. + iter: core::iter::Copied<slice::Iter<'a, Event>>, } impl<'a> Iterator for Iter<'a> { - type Item = (EventFlags, u64); + type Item = Event; + #[inline] fn next(&mut self) -> Option<Self::Item> { - self.iter - .next() - .map(|event| (event.event_flags, event.data)) + self.iter.next() } } /// A record of an event that occurred. #[repr(C)] #[cfg_attr(target_arch = "x86_64", repr(packed))] -struct Event { - // Match the layout of `linux_raw_sys::general::epoll_event`. We just use a - // `u64` instead of the full union. - event_flags: EventFlags, - data: u64, +#[derive(Copy, Clone, Eq, PartialEq, Hash)] +pub struct Event { + /// Which specific event(s) occurred. + pub flags: EventFlags, + /// User data. + pub data: EventData, +} + +/// Data assocated with an [`Event`]. This can either be a 64-bit integer value +/// or a pointer which preserves pointer provenance. +#[repr(C)] +#[derive(Copy, Clone)] +pub union EventData { + /// A 64-bit integer value. + as_u64: u64, + + /// A `*mut c_void` which preserves pointer provenance, extended to be + /// 64-bit so that if we read the value as a `u64` union field, we don't + /// get uninitialized memory. + sixty_four_bit_pointer: SixtyFourBitPointer, +} + +impl EventData { + /// Construct a new value containing a `u64`. + #[inline] + pub const fn new_u64(value: u64) -> Self { + Self { as_u64: value } + } + + /// Construct a new value containing a `*mut c_void`. + #[inline] + pub const fn new_ptr(value: *mut c_void) -> Self { + Self { + sixty_four_bit_pointer: SixtyFourBitPointer { + pointer: value, + #[cfg(target_pointer_width = "32")] + _padding: 0, + }, + } + } + + /// Return the value as a `u64`. + /// + /// If the stored value was a pointer, the pointer is zero-extended to + /// a `u64`. + #[inline] + pub fn u64(self) -> u64 { + unsafe { self.as_u64 } + } + + /// Return the value as a `*mut c_void`. + /// + /// If the stored value was a `u64`, the least-significant bits of the + /// `u64` are returned as a pointer value. + #[inline] + pub fn ptr(self) -> *mut c_void { + unsafe { self.sixty_four_bit_pointer.pointer } + } +} + +impl PartialEq for EventData { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.u64() == other.u64() + } +} + +impl Eq for EventData {} + +impl Hash for EventData { + #[inline] + fn hash<H: Hasher>(&self, state: &mut H) { + self.u64().hash(state) + } +} + +#[repr(C)] +#[derive(Copy, Clone)] +struct SixtyFourBitPointer { + #[cfg(target_endian = "big")] + #[cfg(target_pointer_width = "32")] + _padding: u32, + + pointer: *mut c_void, + + #[cfg(target_endian = "little")] + #[cfg(target_pointer_width = "32")] + _padding: u32, } /// A vector of `Event`s, plus context for interpreting them. @@ -276,6 +370,20 @@ pub struct EventVec { } impl EventVec { + /// Constructs an `EventVec` from raw pointer, length, and capacity. + /// + /// # Safety + /// + /// This function calls [`Vec::from_raw_parts`] with its arguments. + /// + /// [`Vec::from_raw_parts`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.from_raw_parts + #[inline] + pub unsafe fn from_raw_parts(ptr: *mut Event, len: usize, capacity: usize) -> Self { + Self { + events: Vec::from_raw_parts(ptr, len, capacity), + } + } + /// Constructs an `EventVec` with memory for `capacity` `Event`s. #[inline] pub fn with_capacity(capacity: usize) -> Self { @@ -318,7 +426,7 @@ impl EventVec { #[inline] pub fn iter(&self) -> Iter<'_> { Iter { - iter: self.events.iter(), + iter: self.events.iter().copied(), } } @@ -337,10 +445,18 @@ impl EventVec { impl<'a> IntoIterator for &'a EventVec { type IntoIter = Iter<'a>; - type Item = (EventFlags, u64); + type Item = Event; #[inline] fn into_iter(self) -> Self::IntoIter { self.iter() } } + +#[test] +fn test_epoll_layouts() { + check_renamed_type!(Event, epoll_event); + check_renamed_type!(Event, epoll_event); + check_renamed_struct_renamed_field!(Event, epoll_event, flags, events); + check_renamed_struct_renamed_field!(Event, epoll_event, data, data); +} diff --git a/vendor/rustix/src/backend/linux_raw/event/mod.rs b/vendor/rustix/src/backend/linux_raw/event/mod.rs new file mode 100644 index 000000000..605de2538 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/event/mod.rs @@ -0,0 +1,4 @@ +pub mod epoll; +pub(crate) mod poll_fd; +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/io/poll_fd.rs b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs index 252358331..906efe0ef 100644 --- a/vendor/rustix/src/backend/linux_raw/io/poll_fd.rs +++ b/vendor/rustix/src/backend/linux_raw/event/poll_fd.rs @@ -5,6 +5,8 @@ bitflags! { /// `POLL*` flags for use with [`poll`]. /// /// [`poll`]: crate::io::poll + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct PollFlags: u16 { /// `POLLIN` const IN = linux_raw_sys::general::POLLIN as u16; @@ -33,7 +35,7 @@ bitflags! { /// `struct pollfd`—File descriptor and flags for use with [`poll`]. /// -/// [`poll`]: crate::io::poll +/// [`poll`]: crate::event::poll #[doc(alias = "pollfd")] #[repr(C)] #[derive(Debug, Clone)] diff --git a/vendor/rustix/src/backend/linux_raw/event/syscalls.rs b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs new file mode 100644 index 000000000..6d6b35d75 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/event/syscalls.rs @@ -0,0 +1,131 @@ +//! linux_raw syscalls supporting `rustix::event`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::{ + by_ref, c_int, c_uint, pass_usize, raw_fd, ret, ret_owned_fd, ret_usize, slice_mut, zero, +}; +use crate::event::{epoll, EventfdFlags, PollFd}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use linux_raw_sys::general::{EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD}; +#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] +use { + crate::backend::conv::{opt_ref, size_of}, + linux_raw_sys::general::{__kernel_timespec, kernel_sigset_t}, +}; + +#[inline] +pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> { + let (fds_addr_mut, fds_len) = slice_mut(fds); + + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + unsafe { + let timeout = if timeout >= 0 { + Some(__kernel_timespec { + tv_sec: (timeout as i64) / 1000, + tv_nsec: (timeout as i64) % 1000 * 1_000_000, + }) + } else { + None + }; + ret_usize(syscall!( + __NR_ppoll, + fds_addr_mut, + fds_len, + opt_ref(timeout.as_ref()), + zero(), + size_of::<kernel_sigset_t, _>() + )) + } + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + unsafe { + ret_usize(syscall!(__NR_poll, fds_addr_mut, fds_len, c_int(timeout))) + } +} + +#[inline] +pub(crate) fn epoll_create(flags: epoll::CreateFlags) -> io::Result<OwnedFd> { + unsafe { ret_owned_fd(syscall_readonly!(__NR_epoll_create1, flags)) } +} + +#[inline] +pub(crate) unsafe fn epoll_add( + epfd: BorrowedFd<'_>, + fd: c::c_int, + event: &epoll::Event, +) -> io::Result<()> { + ret(syscall_readonly!( + __NR_epoll_ctl, + epfd, + c_uint(EPOLL_CTL_ADD), + raw_fd(fd), + by_ref(event) + )) +} + +#[inline] +pub(crate) unsafe fn epoll_mod( + epfd: BorrowedFd<'_>, + fd: c::c_int, + event: &epoll::Event, +) -> io::Result<()> { + ret(syscall_readonly!( + __NR_epoll_ctl, + epfd, + c_uint(EPOLL_CTL_MOD), + raw_fd(fd), + by_ref(event) + )) +} + +#[inline] +pub(crate) unsafe fn epoll_del(epfd: BorrowedFd<'_>, fd: c::c_int) -> io::Result<()> { + ret(syscall_readonly!( + __NR_epoll_ctl, + epfd, + c_uint(EPOLL_CTL_DEL), + raw_fd(fd), + zero() + )) +} + +#[inline] +pub(crate) fn epoll_wait( + epfd: BorrowedFd<'_>, + events: *mut epoll::Event, + num_events: usize, + timeout: c::c_int, +) -> io::Result<usize> { + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + unsafe { + ret_usize(syscall!( + __NR_epoll_wait, + epfd, + events, + pass_usize(num_events), + c_int(timeout) + )) + } + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + unsafe { + ret_usize(syscall!( + __NR_epoll_pwait, + epfd, + events, + pass_usize(num_events), + c_int(timeout), + zero() + )) + } +} + +#[inline] +pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { + unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } +} diff --git a/vendor/rustix/src/backend/linux_raw/event/types.rs b/vendor/rustix/src/backend/linux_raw/event/types.rs new file mode 100644 index 000000000..e6273959c --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/event/types.rs @@ -0,0 +1,18 @@ +use crate::backend::c; +use bitflags::bitflags; + +bitflags! { + /// `EFD_*` flags for use with [`eventfd`]. + /// + /// [`eventfd`]: crate::io::eventfd + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct EventfdFlags: c::c_uint { + /// `EFD_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::EFD_CLOEXEC; + /// `EFD_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::EFD_NONBLOCK; + /// `EFD_SEMAPHORE` + const SEMAPHORE = linux_raw_sys::general::EFD_SEMAPHORE; + } +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/dir.rs b/vendor/rustix/src/backend/linux_raw/fs/dir.rs index cfa347d03..4df589af5 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/dir.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/dir.rs @@ -4,6 +4,7 @@ use crate::fs::{ fcntl_getfl, fstat, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, Stat, StatFs, StatVfs, }; use crate::io; +#[cfg(feature = "process")] use crate::process::fchdir; use crate::utils::as_ptr; use alloc::borrow::ToOwned; @@ -100,8 +101,7 @@ impl Dir { .iter() .position(|x| *x == b'\0') .unwrap(); - let name = - CStr::from_bytes_with_nul(&self.buf[name_start..name_start + name_len + 1]).unwrap(); + let name = CStr::from_bytes_with_nul(&self.buf[name_start..][..=name_len]).unwrap(); let name = name.to_owned(); assert!(name.as_bytes().len() <= self.buf.len() - name_start); @@ -175,6 +175,8 @@ impl Dir { } /// `fchdir(self)` + #[cfg(feature = "process")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "process")))] #[inline] pub fn chdir(&self) -> io::Result<()> { fchdir(&self.fd) diff --git a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs index a3c274741..cb9d87b82 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/inotify.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/inotify.rs @@ -1,6 +1,6 @@ //! inotify support for working with inotifies -use super::super::c; +use crate::backend::c; use crate::backend::fs::syscalls; use crate::fd::{BorrowedFd, OwnedFd}; use crate::io; @@ -10,6 +10,8 @@ bitflags! { /// `IN_*` for use with [`inotify_init`]. /// /// [`inotify_init`]: crate::fs::inotify::inotify_init + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct CreateFlags: c::c_uint { /// `IN_CLOEXEC` const CLOEXEC = linux_raw_sys::general::IN_CLOEXEC; @@ -22,7 +24,8 @@ bitflags! { /// `IN*` for use with [`inotify_add_watch`]. /// /// [`inotify_add_watch`]: crate::fs::inotify::inotify_add_watch - #[derive(Default)] + #[repr(transparent)] + #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct WatchFlags: c::c_uint { /// `IN_ACCESS` const ACCESS = linux_raw_sys::general::IN_ACCESS; @@ -76,6 +79,7 @@ bitflags! { /// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file /// descriptor from being implicitly passed across `exec` boundaries. #[doc(alias = "inotify_init1")] +#[inline] pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> { syscalls::inotify_init1(flags) } @@ -89,6 +93,7 @@ pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> { /// different paths to this method may result in it returning /// the same watch descriptor. An application should keep track of this /// externally to avoid logic errors. +#[inline] pub fn inotify_add_watch<P: crate::path::Arg>( inot: BorrowedFd<'_>, path: P, @@ -103,6 +108,7 @@ pub fn inotify_add_watch<P: crate::path::Arg>( /// The watch descriptor provided should have previously been returned /// by [`inotify_add_watch`] and not previously have been removed. #[doc(alias = "inotify_rm_watch")] +#[inline] pub fn inotify_remove_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> { syscalls::inotify_rm_watch(inot, wd) } diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs index d0d855cc1..78a2088b2 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs @@ -4,16 +4,16 @@ //! //! See the `rustix::backend` module documentation for details. #![allow(unsafe_code)] -#![allow(dead_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; -use super::super::conv::{ - by_ref, c_int, c_uint, dev_t, oflags_for_open_how, opt_mut, pass_usize, raw_fd, ret, ret_c_int, - ret_c_uint, ret_infallible, ret_owned_fd, ret_usize, size_of, slice, slice_mut, zero, +use crate::backend::c; +use crate::backend::conv::fs::oflags_for_open_how; +use crate::backend::conv::{ + by_ref, c_int, c_uint, dev_t, opt_mut, pass_usize, raw_fd, ret, ret_c_int, ret_c_uint, + ret_infallible, ret_owned_fd, ret_usize, size_of, slice, slice_mut, zero, }; #[cfg(target_pointer_width = "64")] -use super::super::conv::{loff_t, loff_t_from_u64, ret_u64}; +use crate::backend::conv::{loff_t, loff_t_from_u64, ret_u64}; #[cfg(any( target_arch = "aarch64", target_arch = "riscv64", @@ -23,98 +23,77 @@ use super::super::conv::{loff_t, loff_t_from_u64, ret_u64}; use crate::fd::AsFd; use crate::fd::{BorrowedFd, OwnedFd}; use crate::ffi::CStr; +#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] +use crate::fs::CWD; use crate::fs::{ - inotify, Access, Advice, AtFlags, FallocateFlags, FileType, FlockOperation, MemfdFlags, Mode, - OFlags, RenameFlags, ResolveFlags, SealFlags, Stat, StatFs, StatVfs, StatVfsMountFlags, - StatxFlags, Timestamps, XattrFlags, + inotify, Access, Advice, AtFlags, FallocateFlags, FileType, FlockOperation, Gid, MemfdFlags, + Mode, OFlags, RenameFlags, ResolveFlags, SealFlags, SeekFrom, Stat, StatFs, StatVfs, + StatVfsMountFlags, StatxFlags, Timestamps, Uid, XattrFlags, }; -use crate::io::{self, SeekFrom}; -use crate::process::{Gid, Uid}; -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -use core::convert::TryInto; -use core::mem::MaybeUninit; +use crate::io; +use core::mem::{transmute, zeroed, MaybeUninit}; #[cfg(target_arch = "mips64")] use linux_raw_sys::general::stat as linux_stat64; use linux_raw_sys::general::{ __kernel_fsid_t, __kernel_timespec, open_how, statx, AT_EACCESS, AT_FDCWD, AT_REMOVEDIR, - AT_SYMLINK_NOFOLLOW, F_ADD_SEALS, F_GETFL, F_GETLEASE, F_GETOWN, F_GETPIPE_SZ, F_GETSIG, - F_GET_SEALS, F_SETFL, F_SETPIPE_SZ, SEEK_CUR, SEEK_DATA, SEEK_END, SEEK_HOLE, SEEK_SET, - STATX__RESERVED, + AT_SYMLINK_NOFOLLOW, F_ADD_SEALS, F_GETFL, F_GET_SEALS, F_SETFL, SEEK_CUR, SEEK_DATA, SEEK_END, + SEEK_HOLE, SEEK_SET, STATX__RESERVED, }; +use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, EXT4_IOC_RESIZE_FS, FICLONE}; #[cfg(target_pointer_width = "32")] use { - super::super::conv::{hi, lo, slice_just_addr}, + crate::backend::conv::{hi, lo, slice_just_addr}, linux_raw_sys::general::stat64 as linux_stat64, linux_raw_sys::general::timespec as __kernel_old_timespec, }; #[inline] -pub(crate) fn open(filename: &CStr, flags: OFlags, mode: Mode) -> io::Result<OwnedFd> { +pub(crate) fn open(path: &CStr, flags: OFlags, mode: Mode) -> io::Result<OwnedFd> { + // Always enable support for large files. + let flags = flags | OFlags::from_bits_retain(c::O_LARGEFILE); + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] { - openat(crate::fs::cwd().as_fd(), filename, flags, mode) + openat(CWD.as_fd(), path, flags, mode) } - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "aarch64", target_arch = "riscv64")), - ))] + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] unsafe { - ret_owned_fd(syscall_readonly!(__NR_open, filename, flags, mode)) - } - #[cfg(all( - target_pointer_width = "64", - not(any(target_arch = "aarch64", target_arch = "riscv64")), - ))] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_open, filename, flags, mode)) + ret_owned_fd(syscall_readonly!(__NR_open, path, flags, mode)) } } #[inline] pub(crate) fn openat( dirfd: BorrowedFd<'_>, - filename: &CStr, + path: &CStr, flags: OFlags, mode: Mode, ) -> io::Result<OwnedFd> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_openat, dirfd, filename, flags, mode)) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_openat, dirfd, filename, flags, mode)) - } + // Always enable support for large files. + let flags = flags | OFlags::from_bits_retain(c::O_LARGEFILE); + + unsafe { ret_owned_fd(syscall_readonly!(__NR_openat, dirfd, path, flags, mode)) } } #[inline] pub(crate) fn openat2( dirfd: BorrowedFd<'_>, - pathname: &CStr, - flags: OFlags, + path: &CStr, + mut flags: OFlags, mode: Mode, resolve: ResolveFlags, ) -> io::Result<OwnedFd> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_openat2, - dirfd, - pathname, - by_ref(&open_how { - flags: oflags_for_open_how(flags), - mode: u64::from(mode.bits()), - resolve: resolve.bits(), - }), - size_of::<open_how, _>() - )) + // Enable support for large files, but not with `O_PATH` because + // `openat2` doesn't like those flags together. + if !flags.contains(OFlags::PATH) { + flags |= OFlags::from_bits_retain(c::O_LARGEFILE); } - #[cfg(target_pointer_width = "64")] + unsafe { ret_owned_fd(syscall_readonly!( __NR_openat2, dirfd, - pathname, + path, by_ref(&open_how { flags: oflags_for_open_how(flags), mode: u64::from(mode.bits()), @@ -126,12 +105,12 @@ pub(crate) fn openat2( } #[inline] -pub(crate) fn chmod(filename: &CStr, mode: Mode) -> io::Result<()> { +pub(crate) fn chmod(path: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_fchmodat, raw_fd(AT_FDCWD), - filename, + path, mode )) } @@ -140,7 +119,7 @@ pub(crate) fn chmod(filename: &CStr, mode: Mode) -> io::Result<()> { #[inline] pub(crate) fn chmodat( dirfd: BorrowedFd<'_>, - filename: &CStr, + path: &CStr, mode: Mode, flags: AtFlags, ) -> io::Result<()> { @@ -150,7 +129,7 @@ pub(crate) fn chmodat( if !flags.is_empty() { return Err(io::Errno::INVAL); } - unsafe { ret(syscall_readonly!(__NR_fchmodat, dirfd, filename, mode)) } + unsafe { ret(syscall_readonly!(__NR_fchmodat, dirfd, path, mode)) } } #[inline] @@ -161,17 +140,17 @@ pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { #[inline] pub(crate) fn chownat( dirfd: BorrowedFd<'_>, - filename: &CStr, + path: &CStr, owner: Option<Uid>, group: Option<Gid>, flags: AtFlags, ) -> io::Result<()> { unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); + let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); ret(syscall_readonly!( __NR_fchownat, dirfd, - filename, + path, c_uint(ow), c_uint(gr), flags @@ -182,7 +161,7 @@ pub(crate) fn chownat( #[inline] pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); + let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); ret(syscall_readonly!(__NR_fchown, fd, c_uint(ow), c_uint(gr))) } } @@ -190,7 +169,7 @@ pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) #[inline] pub(crate) fn mknodat( dirfd: BorrowedFd<'_>, - filename: &CStr, + path: &CStr, file_type: FileType, mode: Mode, dev: u64, @@ -200,7 +179,7 @@ pub(crate) fn mknodat( ret(syscall_readonly!( __NR_mknodat, dirfd, - filename, + path, (mode, file_type), dev_t(dev)? )) @@ -210,7 +189,7 @@ pub(crate) fn mknodat( ret(syscall_readonly!( __NR_mknodat, dirfd, - filename, + path, (mode, file_type), dev_t(dev) )) @@ -442,9 +421,15 @@ pub(crate) fn sync() { #[inline] pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> { + // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use + // `statx`. + // + // And, some old platforms don't support `statx`, and some fail with a + // confusing error code, so we call `crate::fs::statx` to handle that. If + // `statx` isn't available, fall back to the buggy system call. #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { - match statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { + match crate::fs::statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { Ok(x) => statx_to_stat(x), Err(io::Errno::NOSYS) => fstat_old(fd), Err(err) => Err(err), @@ -477,17 +462,18 @@ fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { } #[inline] -pub(crate) fn stat(filename: &CStr) -> io::Result<Stat> { +pub(crate) fn stat(path: &CStr) -> io::Result<Stat> { + // See the comments in `fstat` about using `crate::fs::statx` here. #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { - match statx( - crate::fs::cwd().as_fd(), - filename, + match crate::fs::statx( + crate::fs::CWD.as_fd(), + path, AtFlags::empty(), StatxFlags::BASIC_STATS, ) { Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => stat_old(filename), + Err(io::Errno::NOSYS) => stat_old(path), Err(err) => Err(err), } } @@ -498,7 +484,7 @@ pub(crate) fn stat(filename: &CStr) -> io::Result<Stat> { ret(syscall!( __NR_newfstatat, raw_fd(AT_FDCWD), - filename, + path, &mut result, c_uint(0) ))?; @@ -507,7 +493,7 @@ pub(crate) fn stat(filename: &CStr) -> io::Result<Stat> { } #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn stat_old(filename: &CStr) -> io::Result<Stat> { +fn stat_old(path: &CStr) -> io::Result<Stat> { let mut result = MaybeUninit::<linux_stat64>::uninit(); #[cfg(target_arch = "mips64")] @@ -515,7 +501,7 @@ fn stat_old(filename: &CStr) -> io::Result<Stat> { ret(syscall!( __NR_newfstatat, raw_fd(AT_FDCWD), - filename, + path, &mut result, c_uint(0) ))?; @@ -527,7 +513,7 @@ fn stat_old(filename: &CStr) -> io::Result<Stat> { ret(syscall!( __NR_fstatat64, raw_fd(AT_FDCWD), - filename, + path, &mut result, c_uint(0) ))?; @@ -536,12 +522,13 @@ fn stat_old(filename: &CStr) -> io::Result<Stat> { } #[inline] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result<Stat> { +pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { + // See the comments in `fstat` about using `crate::fs::statx` here. #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { - match statx(dirfd, filename, flags, StatxFlags::BASIC_STATS) { + match crate::fs::statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(dirfd, filename, flags), + Err(io::Errno::NOSYS) => statat_old(dirfd, path, flags), Err(err) => Err(err), } } @@ -549,58 +536,41 @@ pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] unsafe { let mut result = MaybeUninit::<Stat>::uninit(); - ret(syscall!( - __NR_newfstatat, - dirfd, - filename, - &mut result, - flags - ))?; + ret(syscall!(__NR_newfstatat, dirfd, path, &mut result, flags))?; Ok(result.assume_init()) } } #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn statat_old(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result<Stat> { +fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { let mut result = MaybeUninit::<linux_stat64>::uninit(); #[cfg(target_arch = "mips64")] unsafe { - ret(syscall!( - __NR_newfstatat, - dirfd, - filename, - &mut result, - flags - ))?; + ret(syscall!(__NR_newfstatat, dirfd, path, &mut result, flags))?; stat_to_stat(result.assume_init()) } #[cfg(target_pointer_width = "32")] unsafe { - ret(syscall!( - __NR_fstatat64, - dirfd, - filename, - &mut result, - flags - ))?; + ret(syscall!(__NR_fstatat64, dirfd, path, &mut result, flags))?; stat_to_stat(result.assume_init()) } } #[inline] -pub(crate) fn lstat(filename: &CStr) -> io::Result<Stat> { +pub(crate) fn lstat(path: &CStr) -> io::Result<Stat> { + // See the comments in `fstat` about using `crate::fs::statx` here. #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] { - match statx( - crate::fs::cwd().as_fd(), - filename, + match crate::fs::statx( + crate::fs::CWD.as_fd(), + path, AtFlags::SYMLINK_NOFOLLOW, StatxFlags::BASIC_STATS, ) { Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => lstat_old(filename), + Err(io::Errno::NOSYS) => lstat_old(path), Err(err) => Err(err), } } @@ -611,7 +581,7 @@ pub(crate) fn lstat(filename: &CStr) -> io::Result<Stat> { ret(syscall!( __NR_newfstatat, raw_fd(AT_FDCWD), - filename, + path, &mut result, c_uint(AT_SYMLINK_NOFOLLOW) ))?; @@ -620,7 +590,7 @@ pub(crate) fn lstat(filename: &CStr) -> io::Result<Stat> { } #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn lstat_old(filename: &CStr) -> io::Result<Stat> { +fn lstat_old(path: &CStr) -> io::Result<Stat> { let mut result = MaybeUninit::<linux_stat64>::uninit(); #[cfg(target_arch = "mips64")] @@ -628,7 +598,7 @@ fn lstat_old(filename: &CStr) -> io::Result<Stat> { ret(syscall!( __NR_newfstatat, raw_fd(AT_FDCWD), - filename, + path, &mut result, c_uint(AT_SYMLINK_NOFOLLOW) ))?; @@ -640,7 +610,7 @@ fn lstat_old(filename: &CStr) -> io::Result<Stat> { ret(syscall!( __NR_fstatat64, raw_fd(AT_FDCWD), - filename, + path, &mut result, c_uint(AT_SYMLINK_NOFOLLOW) ))?; @@ -750,7 +720,7 @@ fn stat_to_stat(s: linux_raw_sys::general::stat) -> io::Result<Stat> { #[inline] pub(crate) fn statx( dirfd: BorrowedFd<'_>, - pathname: &CStr, + path: &CStr, flags: AtFlags, mask: StatxFlags, ) -> io::Result<statx> { @@ -777,7 +747,7 @@ pub(crate) fn statx( ret(syscall!( __NR_statx, dirfd, - pathname, + path, flags, mask, &mut statx_buf @@ -837,13 +807,13 @@ pub(crate) fn fstatvfs(fd: BorrowedFd<'_>) -> io::Result<StatVfs> { } #[inline] -pub(crate) fn statfs(filename: &CStr) -> io::Result<StatFs> { +pub(crate) fn statfs(path: &CStr) -> io::Result<StatFs> { #[cfg(target_pointer_width = "32")] unsafe { let mut result = MaybeUninit::<StatFs>::uninit(); ret(syscall!( __NR_statfs64, - filename, + path, size_of::<StatFs, _>(), &mut result ))?; @@ -852,16 +822,16 @@ pub(crate) fn statfs(filename: &CStr) -> io::Result<StatFs> { #[cfg(target_pointer_width = "64")] unsafe { let mut result = MaybeUninit::<StatFs>::uninit(); - ret(syscall!(__NR_statfs, filename, &mut result))?; + ret(syscall!(__NR_statfs, path, &mut result))?; Ok(result.assume_init()) } } #[inline] -pub(crate) fn statvfs(filename: &CStr) -> io::Result<StatVfs> { +pub(crate) fn statvfs(path: &CStr) -> io::Result<StatVfs> { // Linux doesn't have a `statvfs` syscall; we have to do `statfs` and // translate the fields as best we can. - let statfs = statfs(filename)?; + let statfs = statfs(path)?; Ok(statfs_to_statvfs(statfs)) } @@ -883,8 +853,8 @@ fn statfs_to_statvfs(statfs: StatFs) -> StatVfs { f_files: statfs.f_files as u64, f_ffree: statfs.f_ffree as u64, f_favail: statfs.f_ffree as u64, - f_fsid: f_fsid_val0 as u32 as u64 | ((f_fsid_val1 as u32 as u64) << 32), - f_flag: unsafe { StatVfsMountFlags::from_bits_unchecked(statfs.f_flags as u64) }, + f_fsid: u64::from(f_fsid_val0 as u32) | u64::from(f_fsid_val1 as u32) << 32, + f_flag: StatVfsMountFlags::from_bits_retain(statfs.f_flags as u64), f_namemax: statfs.f_namelen as u64, } } @@ -904,7 +874,11 @@ pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { } #[inline] -pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result<usize> { +pub(crate) fn readlinkat( + dirfd: BorrowedFd<'_>, + path: &CStr, + buf: &mut [MaybeUninit<u8>], +) -> io::Result<usize> { let (buf_addr_mut, buf_len) = slice_mut(buf); unsafe { ret_usize(syscall!( @@ -922,17 +896,19 @@ pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result<OFlags> { #[cfg(target_pointer_width = "32")] unsafe { ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFL))) - .map(OFlags::from_bits_truncate) + .map(OFlags::from_bits_retain) } #[cfg(target_pointer_width = "64")] unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFL))) - .map(OFlags::from_bits_truncate) + ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFL))).map(OFlags::from_bits_retain) } } #[inline] pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { + // Always enable support for large files. + let flags = flags | OFlags::from_bits_retain(c::O_LARGEFILE); + #[cfg(target_pointer_width = "32")] unsafe { ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFL), flags)) @@ -944,86 +920,16 @@ pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { } #[inline] -pub(crate) fn fcntl_getlease(fd: BorrowedFd<'_>) -> io::Result<c::c_int> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETLEASE))) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETLEASE))) - } -} - -#[inline] -pub(crate) fn fcntl_getown(fd: BorrowedFd<'_>) -> io::Result<c::c_int> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETOWN))) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETOWN))) - } -} - -#[inline] -pub(crate) fn fcntl_getsig(fd: BorrowedFd<'_>) -> io::Result<c::c_int> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETSIG))) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_int(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETSIG))) - } -} - -#[inline] -pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETPIPE_SZ))) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETPIPE_SZ))) - } -} - -#[inline] -pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: c::c_int) -> io::Result<usize> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(F_SETPIPE_SZ), - c_int(size) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(F_SETPIPE_SZ), - c_int(size) - )) - } -} - -#[inline] pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result<SealFlags> { #[cfg(target_pointer_width = "32")] unsafe { ret_c_int(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GET_SEALS))) - .map(|seals| SealFlags::from_bits_unchecked(seals as u32)) + .map(|seals| SealFlags::from_bits_retain(seals as u32)) } #[cfg(target_pointer_width = "64")] unsafe { ret_c_int(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GET_SEALS))) - .map(|seals| SealFlags::from_bits_unchecked(seals as u32)) + .map(|seals| SealFlags::from_bits_retain(seals as u32)) } } @@ -1077,7 +983,7 @@ pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::R l_start: 0, l_len: 0, - ..core::mem::zeroed() + ..zeroed() }; #[cfg(target_pointer_width = "32")] @@ -1102,15 +1008,15 @@ pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::R } #[inline] -pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { +pub(crate) fn rename(old_path: &CStr, new_path: &CStr) -> io::Result<()> { #[cfg(target_arch = "riscv64")] unsafe { ret(syscall_readonly!( __NR_renameat2, raw_fd(AT_FDCWD), - oldname, + old_path, raw_fd(AT_FDCWD), - newname, + new_path, c_uint(0) )) } @@ -1119,9 +1025,9 @@ pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { ret(syscall_readonly!( __NR_renameat, raw_fd(AT_FDCWD), - oldname, + old_path, raw_fd(AT_FDCWD), - newname + new_path )) } } @@ -1129,18 +1035,18 @@ pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { #[inline] pub(crate) fn renameat( old_dirfd: BorrowedFd<'_>, - oldname: &CStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - newname: &CStr, + new_path: &CStr, ) -> io::Result<()> { #[cfg(target_arch = "riscv64")] unsafe { ret(syscall_readonly!( __NR_renameat2, old_dirfd, - oldname, + old_path, new_dirfd, - newname, + new_path, c_uint(0) )) } @@ -1149,9 +1055,9 @@ pub(crate) fn renameat( ret(syscall_readonly!( __NR_renameat, old_dirfd, - oldname, + old_path, new_dirfd, - newname + new_path )) } } @@ -1159,61 +1065,61 @@ pub(crate) fn renameat( #[inline] pub(crate) fn renameat2( old_dirfd: BorrowedFd<'_>, - oldname: &CStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - newname: &CStr, + new_path: &CStr, flags: RenameFlags, ) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_renameat2, old_dirfd, - oldname, + old_path, new_dirfd, - newname, + new_path, flags )) } } #[inline] -pub(crate) fn unlink(pathname: &CStr) -> io::Result<()> { +pub(crate) fn unlink(path: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_unlinkat, raw_fd(AT_FDCWD), - pathname, + path, c_uint(0) )) } } #[inline] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, pathname: &CStr, flags: AtFlags) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_unlinkat, dirfd, pathname, flags)) } +pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_unlinkat, dirfd, path, flags)) } } #[inline] -pub(crate) fn rmdir(pathname: &CStr) -> io::Result<()> { +pub(crate) fn rmdir(path: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_unlinkat, raw_fd(AT_FDCWD), - pathname, + path, c_uint(AT_REMOVEDIR) )) } } #[inline] -pub(crate) fn link(oldname: &CStr, newname: &CStr) -> io::Result<()> { +pub(crate) fn link(old_path: &CStr, new_path: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_linkat, raw_fd(AT_FDCWD), - oldname, + old_path, raw_fd(AT_FDCWD), - newname, + new_path, c_uint(0) )) } @@ -1222,55 +1128,55 @@ pub(crate) fn link(oldname: &CStr, newname: &CStr) -> io::Result<()> { #[inline] pub(crate) fn linkat( old_dirfd: BorrowedFd<'_>, - oldname: &CStr, + old_path: &CStr, new_dirfd: BorrowedFd<'_>, - newname: &CStr, + new_path: &CStr, flags: AtFlags, ) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_linkat, old_dirfd, - oldname, + old_path, new_dirfd, - newname, + new_path, flags )) } } #[inline] -pub(crate) fn symlink(oldname: &CStr, newname: &CStr) -> io::Result<()> { +pub(crate) fn symlink(old_path: &CStr, new_path: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_symlinkat, - oldname, + old_path, raw_fd(AT_FDCWD), - newname + new_path )) } } #[inline] -pub(crate) fn symlinkat(oldname: &CStr, dirfd: BorrowedFd<'_>, newname: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_symlinkat, oldname, dirfd, newname)) } +pub(crate) fn symlinkat(old_path: &CStr, dirfd: BorrowedFd<'_>, new_path: &CStr) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_symlinkat, old_path, dirfd, new_path)) } } #[inline] -pub(crate) fn mkdir(pathname: &CStr, mode: Mode) -> io::Result<()> { +pub(crate) fn mkdir(path: &CStr, mode: Mode) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_mkdirat, raw_fd(AT_FDCWD), - pathname, + path, mode )) } } #[inline] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, pathname: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_mkdirat, dirfd, pathname, mode)) } +pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_mkdirat, dirfd, path, mode)) } } #[inline] @@ -1293,33 +1199,35 @@ pub(crate) fn getdents_uninit( #[inline] pub(crate) fn utimensat( dirfd: BorrowedFd<'_>, - pathname: &CStr, + path: &CStr, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { - _utimensat(dirfd, Some(pathname), times, flags) + _utimensat(dirfd, Some(path), times, flags) } #[inline] fn _utimensat( dirfd: BorrowedFd<'_>, - pathname: Option<&CStr>, + path: Option<&CStr>, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { // Assert that `Timestamps` has the expected layout. - let _ = unsafe { core::mem::transmute::<Timestamps, [__kernel_timespec; 2]>(times.clone()) }; + let _ = unsafe { transmute::<Timestamps, [__kernel_timespec; 2]>(times.clone()) }; + // `utimensat_time64` was introduced in Linux 5.1. The old `utimensat` + // syscall is not y2038-compatible on 32-bit architectures. #[cfg(target_pointer_width = "32")] unsafe { match ret(syscall_readonly!( __NR_utimensat_time64, dirfd, - pathname, + path, by_ref(times), flags )) { - Err(io::Errno::NOSYS) => _utimensat_old(dirfd, pathname, times, flags), + Err(io::Errno::NOSYS) => _utimensat_old(dirfd, path, times, flags), otherwise => otherwise, } } @@ -1328,7 +1236,7 @@ fn _utimensat( ret(syscall_readonly!( __NR_utimensat, dirfd, - pathname, + path, by_ref(times), flags )) @@ -1338,7 +1246,7 @@ fn _utimensat( #[cfg(target_pointer_width = "32")] unsafe fn _utimensat_old( dirfd: BorrowedFd<'_>, - pathname: Option<&CStr>, + path: Option<&CStr>, times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { @@ -1375,7 +1283,7 @@ unsafe fn _utimensat_old( ret(syscall_readonly!( __NR_utimensat, dirfd, - pathname, + path, old_times_addr, flags )) @@ -1386,6 +1294,19 @@ pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> _utimensat(fd, None, times, AtFlags::empty()) } +#[inline] +pub(crate) fn access(path: &CStr, access: Access) -> io::Result<()> { + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + { + accessat_noflags(CWD.as_fd(), path, access) + } + + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + unsafe { + ret(syscall_readonly!(__NR_access, path, access)) + } +} + pub(crate) fn accessat( dirfd: BorrowedFd<'_>, path: &CStr, @@ -1400,36 +1321,47 @@ pub(crate) fn accessat( } // Linux's `faccessat` syscall doesn't have a flags argument, so if we have - // any flags, use the newer `faccessat2` which does. Unless we're on - // Android where using newer system calls can cause seccomp to abort the - // process. + // any flags, use the newer `faccessat2` introduced in Linux 5.8 which + // does. Unless we're on Android where using newer system calls can cause + // seccomp to abort the process. #[cfg(not(target_os = "android"))] if !flags.is_empty() { - return unsafe { - ret(syscall_readonly!( + unsafe { + match ret(syscall_readonly!( __NR_faccessat2, dirfd, path, access, flags - )) - }; + )) { + Ok(()) => return Ok(()), + Err(io::Errno::NOSYS) => {} + Err(other) => return Err(other), + } + } } // Linux's `faccessat` doesn't have a flags parameter. If we have // `AT_EACCESS` and we're not setuid or setgid, we can emulate it. if flags.is_empty() || (flags.bits() == AT_EACCESS - && crate::process::getuid() == crate::process::geteuid() - && crate::process::getgid() == crate::process::getegid()) + && crate::backend::ugid::syscalls::getuid() + == crate::backend::ugid::syscalls::geteuid() + && crate::backend::ugid::syscalls::getgid() + == crate::backend::ugid::syscalls::getegid()) { - return unsafe { ret(syscall_readonly!(__NR_faccessat, dirfd, path, access)) }; + return accessat_noflags(dirfd, path, access); } Err(io::Errno::NOSYS) } #[inline] +fn accessat_noflags(dirfd: BorrowedFd<'_>, path: &CStr, access: Access) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_faccessat, dirfd, path, access)) } +} + +#[inline] pub(crate) fn copy_file_range( fd_in: BorrowedFd<'_>, off_in: Option<&mut u64>, @@ -1485,7 +1417,6 @@ pub(crate) fn sendfile( } #[inline] -#[cfg(any(target_os = "android", target_os = "linux"))] pub(crate) fn mount( source: Option<&CStr>, target: &CStr, @@ -1506,7 +1437,6 @@ pub(crate) fn mount( } #[inline] -#[cfg(any(target_os = "android", target_os = "linux"))] pub(crate) fn unmount(target: &CStr, flags: super::types::UnmountFlags) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_umount2, target, flags)) } } @@ -1652,15 +1582,50 @@ pub(crate) fn flistxattr(fd: BorrowedFd<'_>, list: &mut [c::c_char]) -> io::Resu #[inline] pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> { - unsafe { ret(syscall!(__NR_removexattr, path, name)) } + unsafe { ret(syscall_readonly!(__NR_removexattr, path, name)) } } #[inline] pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> { - unsafe { ret(syscall!(__NR_lremovexattr, path, name)) } + unsafe { ret(syscall_readonly!(__NR_lremovexattr, path, name)) } } #[inline] pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> { - unsafe { ret(syscall!(__NR_fremovexattr, fd, name)) } + unsafe { ret(syscall_readonly!(__NR_fremovexattr, fd, name)) } +} + +#[inline] +pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result<u32> { + let mut result = MaybeUninit::<c::c_uint>::uninit(); + unsafe { + ret(syscall!(__NR_ioctl, fd, c_uint(BLKSSZGET), &mut result))?; + Ok(result.assume_init() as u32) + } +} + +#[inline] +pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> { + let mut result = MaybeUninit::<c::c_uint>::uninit(); + unsafe { + ret(syscall!(__NR_ioctl, fd, c_uint(BLKPBSZGET), &mut result))?; + Ok(result.assume_init() as u32) + } +} + +#[inline] +pub(crate) fn ioctl_ficlone(fd: BorrowedFd<'_>, src_fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(FICLONE), src_fd)) } +} + +#[inline] +pub(crate) fn ext4_ioc_resize_fs(fd: BorrowedFd<'_>, blocks: u64) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(EXT4_IOC_RESIZE_FS), + by_ref(&blocks) + )) + } } diff --git a/vendor/rustix/src/backend/linux_raw/fs/types.rs b/vendor/rustix/src/backend/linux_raw/fs/types.rs index 68bb9ed46..df61cf721 100644 --- a/vendor/rustix/src/backend/linux_raw/fs/types.rs +++ b/vendor/rustix/src/backend/linux_raw/fs/types.rs @@ -1,10 +1,12 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; bitflags! { /// `*_OK` constants for use with [`accessat`]. /// /// [`accessat`]: fn.accessat.html + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct Access: c::c_uint { /// `R_OK` const READ_OK = linux_raw_sys::general::R_OK; @@ -26,22 +28,27 @@ bitflags! { /// /// [`openat`]: crate::fs::openat /// [`statat`]: crate::fs::statat + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct AtFlags: c::c_uint { + /// `AT_SYMLINK_NOFOLLOW` + const SYMLINK_NOFOLLOW = linux_raw_sys::general::AT_SYMLINK_NOFOLLOW; + + /// `AT_EACCESS` + const EACCESS = linux_raw_sys::general::AT_EACCESS; + /// `AT_REMOVEDIR` const REMOVEDIR = linux_raw_sys::general::AT_REMOVEDIR; /// `AT_SYMLINK_FOLLOW` const SYMLINK_FOLLOW = linux_raw_sys::general::AT_SYMLINK_FOLLOW; - /// `AT_SYMLINK_NOFOLLOW` - const SYMLINK_NOFOLLOW = linux_raw_sys::general::AT_SYMLINK_NOFOLLOW; + /// `AT_NO_AUTOMOUNT` + const NO_AUTOMOUNT = linux_raw_sys::general::AT_NO_AUTOMOUNT; /// `AT_EMPTY_PATH` const EMPTY_PATH = linux_raw_sys::general::AT_EMPTY_PATH; - /// `AT_EACCESS` - const EACCESS = linux_raw_sys::general::AT_EACCESS; - /// `AT_STATX_SYNC_AS_STAT` const STATX_SYNC_AS_STAT = linux_raw_sys::general::AT_STATX_SYNC_AS_STAT; @@ -59,6 +66,8 @@ bitflags! { /// [`openat`]: crate::fs::openat /// [`chmodat`]: crate::fs::chmodat /// [`fchmod`]: crate::fs::fchmod + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct Mode: RawMode { /// `S_IRWXU` const RWXU = linux_raw_sys::general::S_IRWXU; @@ -136,7 +145,7 @@ impl From<RawMode> for Mode { } impl From<Mode> for RawMode { - /// Support conversions from `Mode to raw mode values. + /// Support conversions from `Mode` to raw mode values. /// /// ``` /// use rustix::fs::{Mode, RawMode}; @@ -152,6 +161,8 @@ bitflags! { /// `O_*` constants for use with [`openat`]. /// /// [`openat`]: crate::fs::openat + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct OFlags: c::c_uint { /// `O_ACCMODE` const ACCMODE = linux_raw_sys::general::O_ACCMODE; @@ -234,7 +245,8 @@ bitflags! { /// `RESOLVE_*` constants for use with [`openat2`]. /// /// [`openat2`]: crate::fs::openat2 - #[derive(Default)] + #[repr(transparent)] + #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ResolveFlags: u64 { /// `RESOLVE_NO_XDEV` const NO_XDEV = linux_raw_sys::general::RESOLVE_NO_XDEV as u64; @@ -260,6 +272,8 @@ bitflags! { /// `RENAME_*` constants for use with [`renameat_with`]. /// /// [`renameat_with`]: crate::fs::renameat_with + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct RenameFlags: c::c_uint { /// `RENAME_EXCHANGE` const EXCHANGE = linux_raw_sys::general::RENAME_EXCHANGE; @@ -382,6 +396,8 @@ bitflags! { /// `MFD_*` constants for use with [`memfd_create`]. /// /// [`memfd_create`]: crate::fs::memfd_create + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MemfdFlags: c::c_uint { /// `MFD_CLOEXEC` const CLOEXEC = linux_raw_sys::general::MFD_CLOEXEC; @@ -425,6 +441,8 @@ bitflags! { /// /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct SealFlags: u32 { /// `F_SEAL_SEAL`. const SEAL = linux_raw_sys::general::F_SEAL_SEAL; @@ -443,6 +461,8 @@ bitflags! { /// `STATX_*` constants for use with [`statx`]. /// /// [`statx`]: crate::fs::statx + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct StatxFlags: u32 { /// `STATX_TYPE` const TYPE = linux_raw_sys::general::STATX_TYPE; @@ -486,6 +506,9 @@ bitflags! { /// `STATX_MNT_ID` (since Linux 5.8) const MNT_ID = linux_raw_sys::general::STATX_MNT_ID; + /// `STATX_DIOALIGN` (since Linux 6.1) + const DIOALIGN = linux_raw_sys::general::STATX_DIOALIGN; + /// `STATX_ALL` const ALL = linux_raw_sys::general::STATX_ALL; } @@ -495,6 +518,8 @@ bitflags! { /// `FALLOC_FL_*` constants for use with [`fallocate`]. /// /// [`fallocate`]: crate::fs::fallocate + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FallocateFlags: u32 { /// `FALLOC_FL_KEEP_SIZE` const KEEP_SIZE = linux_raw_sys::general::FALLOC_FL_KEEP_SIZE; @@ -515,6 +540,8 @@ bitflags! { bitflags! { /// `ST_*` constants for use with [`StatVfs`]. + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct StatVfsMountFlags: u64 { /// `ST_MANDLOCK` const MANDLOCK = linux_raw_sys::general::MS_MANDLOCK as u64; @@ -668,11 +695,12 @@ pub type FsWord = linux_raw_sys::general::__fsword_t; #[cfg(target_arch = "mips64")] pub type FsWord = i64; -#[cfg(any(target_os = "android", target_os = "linux"))] bitflags! { /// `MS_*` constants for use with [`mount`]. /// /// [`mount`]: crate::fs::mount + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountFlags: c::c_uint { /// `MS_BIND` const BIND = linux_raw_sys::general::MS_BIND; @@ -725,11 +753,12 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] bitflags! { /// `MS_*` constants for use with [`change_mount`]. /// /// [`change_mount`]: crate::fs::mount::change_mount + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MountPropagationFlags: c::c_uint { /// `MS_SHARED` const SHARED = linux_raw_sys::general::MS_SHARED; @@ -744,22 +773,24 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] bitflags! { + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub(crate) struct InternalMountFlags: c::c_uint { const REMOUNT = linux_raw_sys::general::MS_REMOUNT; const MOVE = linux_raw_sys::general::MS_MOVE; } } -#[cfg(any(target_os = "android", target_os = "linux"))] +#[repr(transparent)] pub(crate) struct MountFlagsArg(pub(crate) c::c_uint); -#[cfg(any(target_os = "android", target_os = "linux"))] bitflags! { /// `MNT_*` constants for use with [`unmount`]. /// /// [`unmount`]: crate::fs::mount::unmount + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct UnmountFlags: c::c_uint { /// `MNT_FORCE` const FORCE = linux_raw_sys::general::MNT_FORCE; diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs index 9db14d06e..af057e2da 100644 --- a/vendor/rustix/src/backend/linux_raw/io/errno.rs +++ b/vendor/rustix/src/backend/linux_raw/io/errno.rs @@ -10,7 +10,7 @@ #![allow(unsafe_code)] #![cfg_attr(not(rustc_attrs), allow(unused_unsafe))] -use super::super::c; +use crate::backend::c; use crate::backend::fd::RawFd; use crate::backend::reg::{RetNumber, RetReg}; use crate::io; @@ -62,12 +62,12 @@ impl Errno { /// Convert from a C `errno` value (which is positive) to an `Errno`. const fn from_errno(raw: u32) -> Self { - // We store error values in negated form, so that we don't have to negate - // them after every syscall. + // We store error values in negated form, so that we don't have to + // negate them after every syscall. let encoded = raw.wrapping_neg() as u16; // TODO: Use Range::contains, once that's `const`. - const_assert!(encoded >= 0xf001); + assert!(encoded >= 0xf001); // SAFETY: Linux syscalls return negated error values in the range // `-4095..0`, which we just asserted. @@ -239,6 +239,13 @@ pub(in crate::backend) fn decode_usize_infallible<Num: RetNumber>(raw: RetReg<Nu /// Return the contained `c_int` value. #[cfg(not(debug_assertions))] #[inline] +pub(in crate::backend) fn decode_c_int_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_int { + raw.decode_c_int() +} + +/// Return the contained `c_uint` value. +#[cfg(not(debug_assertions))] +#[inline] pub(in crate::backend) fn decode_c_uint_infallible<Num: RetNumber>(raw: RetReg<Num>) -> c::c_uint { raw.decode_c_uint() } diff --git a/vendor/rustix/src/backend/linux_raw/io/io_slice.rs b/vendor/rustix/src/backend/linux_raw/io/io_slice.rs deleted file mode 100644 index fc8e64698..000000000 --- a/vendor/rustix/src/backend/linux_raw/io/io_slice.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/sys/unix/io.rs -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. - -#![allow(unsafe_code)] -use super::super::c; -use core::marker::PhantomData; -use core::slice; -use linux_raw_sys::general::__kernel_size_t; - -/// <https://doc.rust-lang.org/nightly/std/io/struct.IoSlice.html> -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: c::iovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSlice.html#method.new> - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - IoSlice { - vec: c::iovec { - iov_base: buf.as_ptr() as *mut u8 as *mut c::c_void, - iov_len: buf.len() as _, - }, - _p: PhantomData, - } - } - - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSlice.html#method.advance> - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n as _ { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.iov_len -= n as __kernel_size_t; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSlice.html#method.as_slice> - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) } - } -} - -/// <https://doc.rust-lang.org/nightly/std/io/struct.IoSliceMut.html> -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: c::iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSliceMut.html#method.new> - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - IoSliceMut { - vec: c::iovec { - iov_base: buf.as_mut_ptr() as *mut c::c_void, - iov_len: buf.len() as _, - }, - _p: PhantomData, - } - } - - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSliceMut.html#method.advance> - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n as _ { - panic!("advancing IoSliceMut beyond its length"); - } - - unsafe { - self.vec.iov_len -= n as __kernel_size_t; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSliceMut.html#method.as_slice> - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) } - } - - /// <https://doc.rust-lang.org/nightly/std/io/struct.IoSliceMut.html#method.as_slice_mut> - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { - slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len as usize) - } - } -} diff --git a/vendor/rustix/src/backend/linux_raw/io/mod.rs b/vendor/rustix/src/backend/linux_raw/io/mod.rs index f5c2bf3c0..9477b9b95 100644 --- a/vendor/rustix/src/backend/linux_raw/io/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/io/mod.rs @@ -1,7 +1,3 @@ -pub mod epoll; pub(crate) mod errno; -#[cfg(not(feature = "std"))] -pub(crate) mod io_slice; -pub(crate) mod poll_fd; pub(crate) mod syscalls; pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs index c76fb0635..45e0dd647 100644 --- a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs @@ -6,38 +6,30 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; #[cfg(target_pointer_width = "64")] -use super::super::conv::loff_t_from_u64; -use super::super::conv::{ - by_ref, c_int, c_uint, opt_mut, pass_usize, raw_fd, ret, ret_c_uint, ret_discarded_fd, - ret_owned_fd, ret_usize, slice, slice_mut, zero, +use crate::backend::conv::loff_t_from_u64; +#[cfg(all( + target_pointer_width = "32", + any(target_arch = "arm", target_arch = "mips", target_arch = "power"), +))] +use crate::backend::conv::zero; +use crate::backend::conv::{ + by_ref, c_uint, raw_fd, ret, ret_c_uint, ret_discarded_fd, ret_owned_fd, ret_usize, slice, + slice_mut, }; #[cfg(target_pointer_width = "32")] -use super::super::conv::{hi, lo}; +use crate::backend::conv::{hi, lo}; +use crate::backend::{c, MAX_IOV}; use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::io::SpliceFlags; -use crate::io::{ - self, epoll, DupFlags, EventfdFlags, FdFlags, IoSlice, IoSliceMut, IoSliceRaw, PipeFlags, - PollFd, ReadWriteFlags, -}; +use crate::io::{self, DupFlags, FdFlags, IoSlice, IoSliceMut, ReadWriteFlags}; #[cfg(all(feature = "fs", feature = "net"))] use crate::net::{RecvFlags, SendFlags}; use core::cmp; use core::mem::MaybeUninit; #[cfg(target_os = "espidf")] use linux_raw_sys::general::F_DUPFD; -use linux_raw_sys::general::{ - epoll_event, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, F_DUPFD_CLOEXEC, F_GETFD, F_SETFD, - UIO_MAXIOV, -}; -use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, FICLONE, FIONBIO, FIONREAD, TIOCEXCL, TIOCNXCL}; -#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] -use { - super::super::conv::{opt_ref, size_of}, - linux_raw_sys::general::{__kernel_timespec, kernel_sigset_t}, -}; +use linux_raw_sys::general::{F_DUPFD_CLOEXEC, F_GETFD, F_SETFD}; +use linux_raw_sys::ioctl::{FIONBIO, FIONREAD}; #[inline] pub(crate) fn read(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> { @@ -94,7 +86,7 @@ pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], pos: u64) -> io::Result< #[inline] pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); unsafe { ret_usize(syscall!(__NR_readv, fd, bufs_addr, bufs_len)) } } @@ -105,7 +97,7 @@ pub(crate) fn preadv( bufs: &mut [IoSliceMut<'_>], pos: u64, ) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); #[cfg(target_pointer_width = "32")] unsafe { @@ -137,7 +129,7 @@ pub(crate) fn preadv2( pos: u64, flags: ReadWriteFlags, ) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); #[cfg(target_pointer_width = "32")] unsafe { @@ -219,14 +211,14 @@ pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], pos: u64) -> io::Result<usi #[inline] pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); unsafe { ret_usize(syscall_readonly!(__NR_writev, fd, bufs_addr, bufs_len)) } } #[inline] pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>], pos: u64) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); #[cfg(target_pointer_width = "32")] unsafe { @@ -258,7 +250,7 @@ pub(crate) fn pwritev2( pos: u64, flags: ReadWriteFlags, ) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); #[cfg(target_pointer_width = "32")] unsafe { @@ -285,12 +277,6 @@ pub(crate) fn pwritev2( } } -/// The maximum number of buffers that can be passed into a vectored I/O system -/// call on the current platform. -const fn max_iov() -> usize { - UIO_MAXIOV as usize -} - #[inline] pub(crate) unsafe fn close(fd: RawFd) { // See the documentation for [`io::close`] for why errors are ignored. @@ -298,11 +284,6 @@ pub(crate) unsafe fn close(fd: RawFd) { } #[inline] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } -} - -#[inline] pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result<u64> { unsafe { let mut result = MaybeUninit::<c::c_int>::uninit(); @@ -324,39 +305,6 @@ pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { } } -#[inline] -pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TIOCEXCL))) } -} - -#[inline] -pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TIOCNXCL))) } -} - -#[inline] -pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result<u32> { - let mut result = MaybeUninit::<c::c_uint>::uninit(); - unsafe { - ret(syscall!(__NR_ioctl, fd, c_uint(BLKSSZGET), &mut result))?; - Ok(result.assume_init() as u32) - } -} - -#[inline] -pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result<u32> { - let mut result = MaybeUninit::<c::c_uint>::uninit(); - unsafe { - ret(syscall!(__NR_ioctl, fd, c_uint(BLKPBSZGET), &mut result))?; - Ok(result.assume_init() as u32) - } -} - -#[inline] -pub(crate) fn ioctl_ficlone(fd: BorrowedFd<'_>, src_fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(FICLONE), src_fd)) } -} - #[cfg(all(feature = "fs", feature = "net"))] pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { let (mut read, mut write) = crate::fs::fd::_is_file_read_write(fd)?; @@ -369,8 +317,11 @@ pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { // TODO: This code would benefit from having a better way to read into // uninitialized memory. let mut buf = [0]; - match super::super::net::syscalls::recv(fd, &mut buf, RecvFlags::PEEK | RecvFlags::DONTWAIT) - { + match crate::backend::net::syscalls::recv( + fd, + &mut buf, + RecvFlags::PEEK | RecvFlags::DONTWAIT, + ) { Ok(0) => read = false, Err(err) => { #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` @@ -387,7 +338,7 @@ pub(crate) fn is_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { // Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates // the write side is shut down. #[allow(unreachable_patterns)] // `EAGAIN` equals `EWOULDBLOCK` - match super::super::net::syscalls::send(fd, &[], SendFlags::DONTWAIT) { + match crate::backend::net::syscalls::send(fd, &[], SendFlags::DONTWAIT) { // TODO or-patterns when we don't need 1.51 Err(io::Errno::AGAIN) => (), Err(io::Errno::WOULDBLOCK) => (), @@ -431,12 +382,12 @@ pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result<FdFlags> { #[cfg(target_pointer_width = "32")] unsafe { ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFD))) - .map(FdFlags::from_bits_truncate) + .map(FdFlags::from_bits_retain) } #[cfg(target_pointer_width = "64")] unsafe { ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFD))) - .map(FdFlags::from_bits_truncate) + .map(FdFlags::from_bits_retain) } } @@ -496,186 +447,3 @@ pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result< )) } } - -#[inline] -pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!(__NR_pipe2, &mut result, flags))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[inline] -pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { - // aarch64 and risc64 omit `__NR_pipe`. On mips, `__NR_pipe` uses a special - // calling convention, but using it is not worth complicating our syscall - // wrapping infrastructure at this time. - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips", - target_arch = "mips64", - target_arch = "riscv64", - ))] - { - pipe_with(PipeFlags::empty()) - } - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips", - target_arch = "mips64", - target_arch = "riscv64", - )))] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!(__NR_pipe, &mut result))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[inline] -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result<usize> { - let (fds_addr_mut, fds_len) = slice_mut(fds); - - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - unsafe { - let timeout = if timeout >= 0 { - Some(__kernel_timespec { - tv_sec: (timeout as i64) / 1000, - tv_nsec: (timeout as i64) % 1000 * 1_000_000, - }) - } else { - None - }; - ret_usize(syscall!( - __NR_ppoll, - fds_addr_mut, - fds_len, - opt_ref(timeout.as_ref()), - zero(), - size_of::<kernel_sigset_t, _>() - )) - } - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - ret_usize(syscall!(__NR_poll, fds_addr_mut, fds_len, c_int(timeout))) - } -} - -#[inline] -pub(crate) fn epoll_create(flags: epoll::CreateFlags) -> io::Result<OwnedFd> { - unsafe { ret_owned_fd(syscall_readonly!(__NR_epoll_create1, flags)) } -} - -#[inline] -pub(crate) unsafe fn epoll_add( - epfd: BorrowedFd<'_>, - fd: c::c_int, - event: &epoll_event, -) -> io::Result<()> { - ret(syscall_readonly!( - __NR_epoll_ctl, - epfd, - c_uint(EPOLL_CTL_ADD), - raw_fd(fd), - by_ref(event) - )) -} - -#[inline] -pub(crate) unsafe fn epoll_mod( - epfd: BorrowedFd<'_>, - fd: c::c_int, - event: &epoll_event, -) -> io::Result<()> { - ret(syscall_readonly!( - __NR_epoll_ctl, - epfd, - c_uint(EPOLL_CTL_MOD), - raw_fd(fd), - by_ref(event) - )) -} - -#[inline] -pub(crate) unsafe fn epoll_del(epfd: BorrowedFd<'_>, fd: c::c_int) -> io::Result<()> { - ret(syscall_readonly!( - __NR_epoll_ctl, - epfd, - c_uint(EPOLL_CTL_DEL), - raw_fd(fd), - zero() - )) -} - -#[inline] -pub(crate) fn epoll_wait( - epfd: BorrowedFd<'_>, - events: *mut epoll_event, - num_events: usize, - timeout: c::c_int, -) -> io::Result<usize> { - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - ret_usize(syscall!( - __NR_epoll_wait, - epfd, - events, - pass_usize(num_events), - c_int(timeout) - )) - } - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - unsafe { - ret_usize(syscall!( - __NR_epoll_pwait, - epfd, - events, - pass_usize(num_events), - c_int(timeout), - zero() - )) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub fn splice( - fd_in: BorrowedFd, - off_in: Option<&mut u64>, - fd_out: BorrowedFd, - off_out: Option<&mut u64>, - len: usize, - flags: SpliceFlags, -) -> io::Result<usize> { - unsafe { - ret_usize(syscall!( - __NR_splice, - fd_in, - opt_mut(off_in), - fd_out, - opt_mut(off_out), - pass_usize(len), - c_uint(flags.bits()) - )) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub unsafe fn vmsplice( - fd: BorrowedFd, - bufs: &[IoSliceRaw], - flags: SpliceFlags, -) -> io::Result<usize> { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); - ret_usize(syscall!( - __NR_vmsplice, - fd, - bufs_addr, - bufs_len, - c_uint(flags.bits()) - )) -} diff --git a/vendor/rustix/src/backend/linux_raw/io/types.rs b/vendor/rustix/src/backend/linux_raw/io/types.rs index cb6c6acef..c06134440 100644 --- a/vendor/rustix/src/backend/linux_raw/io/types.rs +++ b/vendor/rustix/src/backend/linux_raw/io/types.rs @@ -1,12 +1,13 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; -use core::marker::PhantomData; bitflags! { /// `FD_*` constants for use with [`fcntl_getfd`] and [`fcntl_setfd`]. /// /// [`fcntl_getfd`]: crate::io::fcntl_getfd /// [`fcntl_setfd`]: crate::io::fcntl_setfd + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FdFlags: c::c_uint { /// `FD_CLOEXEC` const CLOEXEC = linux_raw_sys::general::FD_CLOEXEC; @@ -18,6 +19,8 @@ bitflags! { /// /// [`preadv2`]: crate::io::preadv2 /// [`pwritev2`]: crate::io::pwritev + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ReadWriteFlags: c::c_uint { /// `RWF_DSYNC` (since Linux 4.7) const DSYNC = linux_raw_sys::general::RWF_DSYNC; @@ -32,98 +35,14 @@ bitflags! { } } -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `SPLICE_F_*` constants for use with [`splice`] and [`vmsplice`]. - pub struct SpliceFlags: c::c_uint { - /// `SPLICE_F_MOVE` - const MOVE = linux_raw_sys::general::SPLICE_F_MOVE; - /// `SPLICE_F_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::SPLICE_F_NONBLOCK; - /// `SPLICE_F_MORE` - const MORE = linux_raw_sys::general::SPLICE_F_MORE; - /// `SPLICE_F_GIFT` - const GIFT = linux_raw_sys::general::SPLICE_F_GIFT; - } -} - bitflags! { /// `O_*` constants for use with [`dup2`]. /// /// [`dup2`]: crate::io::dup2 + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct DupFlags: c::c_uint { /// `O_CLOEXEC` const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; } } - -bitflags! { - /// `O_*` constants for use with [`pipe_with`]. - /// - /// [`pipe_with`]: crate::io::pipe_with - pub struct PipeFlags: c::c_uint { - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - /// `O_DIRECT` - const DIRECT = linux_raw_sys::general::O_DIRECT; - /// `O_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - } -} - -bitflags! { - /// `EFD_*` flags for use with [`eventfd`]. - /// - /// [`eventfd`]: crate::io::eventfd - pub struct EventfdFlags: c::c_uint { - /// `EFD_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::EFD_CLOEXEC; - /// `EFD_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::EFD_NONBLOCK; - /// `EFD_SEMAPHORE` - const SEMAPHORE = linux_raw_sys::general::EFD_SEMAPHORE; - } -} - -/// `PIPE_BUF`—The maximum size of a write to a pipe guaranteed to be atomic. -pub const PIPE_BUF: usize = linux_raw_sys::general::PIPE_BUF as usize; - -pub(crate) const AT_FDCWD: c::c_int = linux_raw_sys::general::AT_FDCWD; -pub(crate) const STDIN_FILENO: c::c_uint = linux_raw_sys::general::STDIN_FILENO; -pub(crate) const STDOUT_FILENO: c::c_uint = linux_raw_sys::general::STDOUT_FILENO; -pub(crate) const STDERR_FILENO: c::c_uint = linux_raw_sys::general::STDERR_FILENO; - -/// A buffer type used with `vmsplice`. -/// It is guaranteed to be ABI compatible with the iovec type on Unix platforms -/// and `WSABUF` on Windows. Unlike `IoSlice` and `IoSliceMut` it is -/// semantically like a raw pointer, and therefore can be shared or mutated as -/// needed. -#[repr(transparent)] -pub struct IoSliceRaw<'a> { - _buf: c::iovec, - _lifetime: PhantomData<&'a ()>, -} - -impl<'a> IoSliceRaw<'a> { - /// Creates a new `IoSlice` wrapping a byte slice. - pub fn from_slice(buf: &'a [u8]) -> Self { - IoSliceRaw { - _buf: c::iovec { - iov_base: buf.as_ptr() as *mut u8 as *mut c::c_void, - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } - } - - /// Creates a new `IoSlice` wrapping a mutable byte slice. - pub fn from_slice_mut(buf: &'a mut [u8]) -> Self { - IoSliceRaw { - _buf: c::iovec { - iov_base: buf.as_mut_ptr() as *mut c::c_void, - iov_len: buf.len() as _, - }, - _lifetime: PhantomData, - } - } -} diff --git a/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs index 16655fe77..90c82c129 100644 --- a/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs @@ -6,7 +6,7 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::conv::{by_mut, c_uint, pass_usize, ret_c_uint, ret_owned_fd}; +use crate::backend::conv::{by_mut, c_uint, pass_usize, ret_c_uint, ret_owned_fd}; use crate::fd::{BorrowedFd, OwnedFd}; use crate::io; use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterOp}; diff --git a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs index 8fa6a3ec3..b51f826a9 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs @@ -6,18 +6,16 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; -#[cfg(target_pointer_width = "64")] -use super::super::conv::loff_t_from_u64; -use super::super::conv::{c_uint, no_fd, pass_usize, ret, ret_owned_fd, ret_void_star}; use super::types::{ Advice, MapFlags, MlockFlags, MprotectFlags, MremapFlags, MsyncFlags, ProtFlags, UserfaultfdFlags, }; +use crate::backend::c; +#[cfg(target_pointer_width = "64")] +use crate::backend::conv::loff_t_from_u64; +use crate::backend::conv::{c_uint, no_fd, pass_usize, ret, ret_owned_fd, ret_void_star}; use crate::fd::{BorrowedFd, OwnedFd}; use crate::io; -#[cfg(target_pointer_width = "32")] -use core::convert::TryInto; use linux_raw_sys::general::MAP_ANONYMOUS; #[inline] diff --git a/vendor/rustix/src/backend/linux_raw/mm/types.rs b/vendor/rustix/src/backend/linux_raw/mm/types.rs index a34c41f4f..576f08a3d 100644 --- a/vendor/rustix/src/backend/linux_raw/mm/types.rs +++ b/vendor/rustix/src/backend/linux_raw/mm/types.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; bitflags! { @@ -7,6 +7,8 @@ bitflags! { /// For `PROT_NONE`, use `ProtFlags::empty()`. /// /// [`mmap`]: crate::io::mmap + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct ProtFlags: u32 { /// `PROT_READ` const READ = linux_raw_sys::general::PROT_READ; @@ -23,6 +25,8 @@ bitflags! { /// For `PROT_NONE`, use `MprotectFlags::empty()`. /// /// [`mprotect`]: crate::io::mprotect + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MprotectFlags: u32 { /// `PROT_READ` const READ = linux_raw_sys::general::PROT_READ; @@ -44,6 +48,8 @@ bitflags! { /// /// [`mmap`]: crate::io::mmap /// [`mmap_anonymous`]: crates::io::mmap_anonymous + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MapFlags: u32 { /// `MAP_SHARED` const SHARED = linux_raw_sys::general::MAP_SHARED; @@ -89,6 +95,8 @@ bitflags! { /// /// [`mremap`]: crate::io::mremap /// [`mremap_fixed`]: crate::io::mremap_fixed + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MremapFlags: u32 { /// `MREMAP_MAYMOVE` const MAYMOVE = linux_raw_sys::general::MREMAP_MAYMOVE; @@ -101,6 +109,8 @@ bitflags! { /// `MLOCK_*` flags for use with [`mlock_with`]. /// /// [`mlock_with`]: crate::io::mlock_with + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MlockFlags: u32 { /// `MLOCK_ONFAULT` const ONFAULT = linux_raw_sys::general::MLOCK_ONFAULT; @@ -111,6 +121,8 @@ bitflags! { /// `MS_*` flags for use with [`msync`]. /// /// [`msync`]: crate::io::msync + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct MsyncFlags: u32 { /// `MS_SYNC`—Requests an update and waits for it to complete. const SYNC = linux_raw_sys::general::MS_SYNC; @@ -128,6 +140,8 @@ bitflags! { /// `O_*` flags for use with [`userfaultfd`]. /// /// [`userfaultfd`]: crate::io::userfaultfd + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct UserfaultfdFlags: c::c_uint { /// `O_CLOEXEC` const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; @@ -195,6 +209,8 @@ pub enum Advice { LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ, /// `MADV_POPULATE_WRITE` (since Linux 5.14) LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE, + /// `MADV_DONTNEED_LOCKED` (since Linux 5.18) + LinuxDontneedLocked = linux_raw_sys::general::MADV_DONTNEED_LOCKED, } #[allow(non_upper_case_globals)] diff --git a/vendor/rustix/src/backend/linux_raw/mod.rs b/vendor/rustix/src/backend/linux_raw/mod.rs index e7e073e32..cd5805f88 100644 --- a/vendor/rustix/src/backend/linux_raw/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/mod.rs @@ -17,6 +17,12 @@ #[macro_use] mod arch; mod conv; +#[cfg(any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86" +))] mod elf; mod reg; #[cfg(any(feature = "time", target_arch = "x86"))] @@ -24,7 +30,21 @@ mod vdso; #[cfg(any(feature = "time", target_arch = "x86"))] mod vdso_wrappers; -#[cfg(feature = "fs")] +#[cfg(feature = "event")] +pub(crate) mod event; +#[cfg(any( + feature = "fs", + all( + not(feature = "use-libc-auxv"), + not(target_vendor = "mustang"), + any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86", + ) + ) +))] pub(crate) mod fs; pub(crate) mod io; #[cfg(feature = "io_uring")] @@ -40,28 +60,57 @@ pub(crate) mod net; target_arch = "x86", ))] pub(crate) mod param; +#[cfg(feature = "pipe")] +pub(crate) mod pipe; +#[cfg(feature = "process")] pub(crate) mod process; +#[cfg(feature = "pty")] +pub(crate) mod pty; #[cfg(feature = "rand")] pub(crate) mod rand; #[cfg(feature = "runtime")] pub(crate) mod runtime; +#[cfg(feature = "system")] +pub(crate) mod system; #[cfg(feature = "termios")] pub(crate) mod termios; #[cfg(feature = "thread")] pub(crate) mod thread; +#[cfg(feature = "time")] pub(crate) mod time; -#[cfg(feature = "std")] pub(crate) mod fd { - pub use io_lifetimes::*; - #[allow(unused_imports)] - pub(crate) use std::os::unix::io::RawFd as LibcFd; - pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; + pub use crate::maybe_polyfill::os::fd::{ + AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd, + }; } -#[cfg(not(feature = "std"))] -pub(crate) use crate::io::fd; - // The linux_raw backend doesn't use actual libc, so we define selected // libc-like definitions in a module called `c`. pub(crate) mod c; + +// Private modules used by multiple public modules. +#[cfg(any(feature = "procfs", feature = "process", feature = "runtime"))] +pub(crate) mod pid; +#[cfg(any(feature = "process", feature = "thread"))] +pub(crate) mod prctl; +#[cfg(any( + feature = "fs", + feature = "process", + feature = "thread", + all( + not(feature = "use-libc-auxv"), + not(target_vendor = "mustang"), + any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86", + ) + ) +))] +pub(crate) mod ugid; + +/// The maximum number of buffers that can be passed into a vectored I/O system +/// call on the current platform. +const MAX_IOV: usize = linux_raw_sys::general::UIO_MAXIOV as usize; diff --git a/vendor/rustix/src/backend/linux_raw/net/addr.rs b/vendor/rustix/src/backend/linux_raw/net/addr.rs index b69c6deca..4a203ed16 100644 --- a/vendor/rustix/src/backend/linux_raw/net/addr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/addr.rs @@ -1,15 +1,17 @@ -//! IPv4, IPv6, and Socket addresses. +//! Socket address utilities. //! //! # Safety //! -//! Linux's IPv6 type contains a union. +//! This file uses `CStr::from_bytes_with_nul_unchecked` on a string it knows +//! to be NUL-terminated. #![allow(unsafe_code)] -use super::super::c; +use crate::backend::c; use crate::ffi::CStr; use crate::{io, path}; -use core::convert::TryInto; -use core::{fmt, slice}; +use core::cmp::Ordering; +use core::fmt; +use core::hash::{Hash, Hasher}; /// `struct sockaddr_un` #[derive(Clone)] @@ -34,7 +36,7 @@ impl SocketAddrUnix { return Err(io::Errno::NAMETOOLONG); } for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = *b as c::c_char; + unix.sun_path[i] = *b; } let len = offsetof_sun_path() + bytes.len(); let len = len.try_into().unwrap(); @@ -45,19 +47,18 @@ impl SocketAddrUnix { #[inline] pub fn new_abstract_name(name: &[u8]) -> io::Result<Self> { let mut unix = Self::init(); - if 1 + name.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - unix.sun_path[0] = b'\0' as c::c_char; - for (i, b) in name.iter().enumerate() { - unix.sun_path[1 + i] = *b as c::c_char; + let id = &mut unix.sun_path[1..]; + if let Some(id) = id.get_mut(..name.len()) { + id.copy_from_slice(name); + let len = offsetof_sun_path() + 1 + name.len(); + let len = len.try_into().unwrap(); + Ok(Self { unix, len }) + } else { + Err(io::Errno::NAMETOOLONG) } - let len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) } - fn init() -> c::sockaddr_un { + const fn init() -> c::sockaddr_un { c::sockaddr_un { sun_family: c::AF_UNIX as _, sun_path: [0; 108], @@ -68,17 +69,12 @@ impl SocketAddrUnix { #[inline] pub fn path(&self) -> Option<&CStr> { let len = self.len(); - if len != 0 && self.unix.sun_path[0] != b'\0' as c::c_char { + if len != 0 && self.unix.sun_path[0] != b'\0' { let end = len as usize - offsetof_sun_path(); let bytes = &self.unix.sun_path[..end]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. And - // `from_bytes_with_nul_unchecked` since the string is NUL-terminated. - unsafe { - Some(CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts( - bytes.as_ptr().cast(), - bytes.len(), - ))) - } + // SAFETY: `from_bytes_with_nul_unchecked` since the string is + // NUL-terminated. + unsafe { Some(CStr::from_bytes_with_nul_unchecked(bytes)) } } else { None } @@ -88,11 +84,9 @@ impl SocketAddrUnix { #[inline] pub fn abstract_name(&self) -> Option<&[u8]> { let len = self.len(); - if len != 0 && self.unix.sun_path[0] == b'\0' as c::c_char { + if len != 0 && self.unix.sun_path[0] == b'\0' { let end = len as usize - offsetof_sun_path(); - let bytes = &self.unix.sun_path[1..end]; - // SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`. - unsafe { Some(slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len())) } + Some(&self.unix.sun_path[1..end]) } else { None } @@ -122,7 +116,7 @@ impl Eq for SocketAddrUnix {} impl PartialOrd for SocketAddrUnix { #[inline] - fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { let self_len = self.len() - offsetof_sun_path(); let other_len = other.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].partial_cmp(&other.unix.sun_path[..other_len]) @@ -131,16 +125,16 @@ impl PartialOrd for SocketAddrUnix { impl Ord for SocketAddrUnix { #[inline] - fn cmp(&self, other: &Self) -> core::cmp::Ordering { + fn cmp(&self, other: &Self) -> Ordering { let self_len = self.len() - offsetof_sun_path(); let other_len = other.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].cmp(&other.unix.sun_path[..other_len]) } } -impl core::hash::Hash for SocketAddrUnix { +impl Hash for SocketAddrUnix { #[inline] - fn hash<H: core::hash::Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { let self_len = self.len() - offsetof_sun_path(); self.unix.sun_path[..self_len].hash(state) } diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs index f2273db1b..2b6ab34ba 100644 --- a/vendor/rustix/src/backend/linux_raw/net/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/net/mod.rs @@ -1,6 +1,6 @@ pub(crate) mod addr; +pub(crate) mod msghdr; pub(crate) mod read_sockaddr; pub(crate) mod send_recv; pub(crate) mod syscalls; -pub(crate) mod types; pub(crate) mod write_sockaddr; diff --git a/vendor/rustix/src/backend/linux_raw/net/msghdr.rs b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs new file mode 100644 index 000000000..3c435bcfa --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/msghdr.rs @@ -0,0 +1,143 @@ +//! Utilities for dealing with message headers. +//! +//! These take closures rather than returning a `c::msghdr` directly because +//! the message headers may reference stack-local data. + +#![allow(unsafe_code)] + +use crate::backend::c; +use crate::backend::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; + +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6}; +use crate::utils::as_ptr; + +use core::mem::{size_of, zeroed, MaybeUninit}; +use core::ptr::null_mut; + +fn msg_iov_len(len: usize) -> c::size_t { + // This cast cannot overflow. + len as c::size_t +} + +pub(crate) fn msg_control_len(len: usize) -> c::size_t { + // Same as above. + len as c::size_t +} + +/// Create a message header intended to receive a datagram. +pub(crate) fn with_recv_msghdr<R>( + name: &mut MaybeUninit<c::sockaddr_storage>, + iov: &mut [IoSliceMut<'_>], + control: &mut RecvAncillaryBuffer<'_>, + f: impl FnOnce(&mut c::msghdr) -> io::Result<R>, +) -> io::Result<R> { + control.clear(); + + let namelen = size_of::<c::sockaddr_storage>() as c::c_int; + let mut msghdr = c::msghdr { + msg_name: name.as_mut_ptr().cast(), + msg_namelen: namelen, + msg_iov: iov.as_mut_ptr().cast(), + msg_iovlen: msg_iov_len(iov.len()), + msg_control: control.as_control_ptr().cast(), + msg_controllen: msg_control_len(control.control_len()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }; + + let res = f(&mut msghdr); + + // Reset the control length. + if res.is_ok() { + unsafe { + control.set_control_len(msghdr.msg_controllen.try_into().unwrap_or(usize::MAX)); + } + } + + res +} + +/// Create a message header intended to send without an address. +pub(crate) fn with_noaddr_msghdr<R>( + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + f(c::msghdr { + msg_name: null_mut(), + msg_namelen: 0, + msg_iov: iov.as_ptr() as _, + msg_iovlen: msg_iov_len(iov.len()), + msg_control: control.as_control_ptr().cast(), + msg_controllen: msg_control_len(control.control_len()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} + +/// Create a message header intended to send with an IPv4 address. +pub(crate) fn with_v4_msghdr<R>( + addr: &SocketAddrV4, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + let encoded = unsafe { encode_sockaddr_v4(addr) }; + + f(c::msghdr { + msg_name: as_ptr(&encoded) as _, + msg_namelen: size_of::<SocketAddrV4>() as _, + msg_iov: iov.as_ptr() as _, + msg_iovlen: msg_iov_len(iov.len()), + msg_control: control.as_control_ptr().cast(), + msg_controllen: msg_control_len(control.control_len()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} + +/// Create a message header intended to send with an IPv6 address. +pub(crate) fn with_v6_msghdr<R>( + addr: &SocketAddrV6, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + let encoded = unsafe { encode_sockaddr_v6(addr) }; + + f(c::msghdr { + msg_name: as_ptr(&encoded) as _, + msg_namelen: size_of::<SocketAddrV6>() as _, + msg_iov: iov.as_ptr() as _, + msg_iovlen: msg_iov_len(iov.len()), + msg_control: control.as_control_ptr().cast(), + msg_controllen: msg_control_len(control.control_len()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} + +/// Create a message header intended to send with a Unix address. +pub(crate) fn with_unix_msghdr<R>( + addr: &crate::net::SocketAddrUnix, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + f: impl FnOnce(c::msghdr) -> R, +) -> R { + f(c::msghdr { + msg_name: as_ptr(addr) as _, + msg_namelen: addr.addr_len() as _, + msg_iov: iov.as_ptr() as _, + msg_iovlen: msg_iov_len(iov.len()), + msg_control: control.as_control_ptr().cast(), + msg_controllen: msg_control_len(control.control_len()), + + // Zero-initialize any padding bytes. + ..unsafe { zeroed() } + }) +} diff --git a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs index b9bc09b96..f4b7d9914 100644 --- a/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs @@ -2,10 +2,9 @@ //! we can interpret the rest of a `sockaddr` produced by the kernel. #![allow(unsafe_code)] -use super::super::c; +use crate::backend::c; use crate::io; use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; -use alloc::vec::Vec; use core::mem::size_of; // This must match the header of `sockaddr`. @@ -24,9 +23,9 @@ unsafe fn read_ss_family(storage: *const c::sockaddr) -> u16 { // Assert that we know the layout of `sockaddr`. let _ = c::sockaddr { __storage: c::sockaddr_storage { - __bindgen_anon_1: linux_raw_sys::general::__kernel_sockaddr_storage__bindgen_ty_1 { + __bindgen_anon_1: linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1 { __bindgen_anon_1: - linux_raw_sys::general::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { + linux_raw_sys::net::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { ss_family: 0_u16, __data: [0; 126_usize], }, @@ -63,7 +62,7 @@ pub(crate) unsafe fn read_sockaddr( if len < size_of::<c::sockaddr_in>() { return Err(io::Errno::INVAL); } - let decode = *storage.cast::<c::sockaddr_in>(); + let decode = &*storage.cast::<c::sockaddr_in>(); Ok(SocketAddrAny::V4(SocketAddrV4::new( Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), u16::from_be(decode.sin_port), @@ -73,7 +72,7 @@ pub(crate) unsafe fn read_sockaddr( if len < size_of::<c::sockaddr_in6>() { return Err(io::Errno::INVAL); } - let decode = *storage.cast::<c::sockaddr_in6>(); + let decode = &*storage.cast::<c::sockaddr_in6>(); Ok(SocketAddrAny::V6(SocketAddrV6::new( Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), u16::from_be(decode.sin6_port), @@ -88,16 +87,22 @@ pub(crate) unsafe fn read_sockaddr( if len == offsetof_sun_path { Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..])?)) } else { - let decode = *storage.cast::<c::sockaddr_un>(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); + let decode = &*storage.cast::<c::sockaddr_un>(); + + // On Linux check for Linux's [abstract namespace]. + // + // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html + if decode.sun_path[0] == 0 { + return SocketAddrUnix::new_abstract_name( + &decode.sun_path[1..len - offsetof_sun_path], + ) + .map(SocketAddrAny::Unix); + } + + // Otherwise we expect a NUL-terminated filesystem path. + assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); Ok(SocketAddrAny::Unix(SocketAddrUnix::new( - decode.sun_path[..len - 1 - offsetof_sun_path] - .iter() - .map(|c| *c as u8) - .collect::<Vec<u8>>(), + &decode.sun_path[..len - 1 - offsetof_sun_path], )?)) } } @@ -133,7 +138,7 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) - match read_ss_family(storage).into() { c::AF_INET => { assert!(len >= size_of::<c::sockaddr_in>()); - let decode = *storage.cast::<c::sockaddr_in>(); + let decode = &*storage.cast::<c::sockaddr_in>(); SocketAddrAny::V4(SocketAddrV4::new( Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), u16::from_be(decode.sin_port), @@ -141,7 +146,7 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) - } c::AF_INET6 => { assert!(len >= size_of::<c::sockaddr_in6>()); - let decode = *storage.cast::<c::sockaddr_in6>(); + let decode = &*storage.cast::<c::sockaddr_in6>(); SocketAddrAny::V6(SocketAddrV6::new( Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), u16::from_be(decode.sin6_port), @@ -154,19 +159,24 @@ pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) - if len == offsetof_sun_path { SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) } else { - let decode = *storage.cast::<c::sockaddr_un>(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); + let decode = &*storage.cast::<c::sockaddr_un>(); + + // On Linux check for Linux's [abstract namespace]. + // + // [abstract namespace]: https://man7.org/linux/man-pages/man7/unix.7.html + if decode.sun_path[0] == 0 { + return SocketAddrAny::Unix( + SocketAddrUnix::new_abstract_name( + &decode.sun_path[1..len - offsetof_sun_path], + ) + .unwrap(), + ); + } + + // Otherwise we expect a NUL-terminated filesystem path. + assert_eq!(decode.sun_path[len - 1 - offsetof_sun_path], 0); SocketAddrAny::Unix( - SocketAddrUnix::new( - decode.sun_path[..len - 1 - offsetof_sun_path] - .iter() - .map(|c| *c as u8) - .collect::<Vec<u8>>(), - ) - .unwrap(), + SocketAddrUnix::new(&decode.sun_path[..len - 1 - offsetof_sun_path]).unwrap(), ) } } diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs index fb82eaef3..6e39a13aa 100644 --- a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs +++ b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs @@ -1,4 +1,4 @@ -use super::super::c; +use crate::backend::c; use bitflags::bitflags; bitflags! { @@ -6,6 +6,8 @@ bitflags! { /// /// [`send`]: crate::net::send /// [`sendto`]: crate::net::sendto + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct SendFlags: u32 { /// `MSG_CONFIRM` const CONFIRM = c::MSG_CONFIRM; @@ -29,6 +31,8 @@ bitflags! { /// /// [`recv`]: crate::net::recv /// [`recvfrom`]: crate::net::recvfrom + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct RecvFlags: u32 { /// `MSG_CMSG_CLOEXEC` const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs index 7fe9f0ef4..dca331783 100644 --- a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs @@ -6,29 +6,33 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; -use super::super::conv::{ - by_mut, by_ref, c_int, c_uint, ret, ret_owned_fd, ret_usize, size_of, slice, slice_mut, - socklen_t, zero, +use super::msghdr::{ + with_noaddr_msghdr, with_recv_msghdr, with_unix_msghdr, with_v4_msghdr, with_v6_msghdr, }; use super::read_sockaddr::{initialize_family_to_unspec, maybe_read_sockaddr_os, read_sockaddr_os}; use super::send_recv::{RecvFlags, SendFlags}; -use super::types::{AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; +use crate::backend::c; +use crate::backend::conv::{ + by_mut, by_ref, c_int, c_uint, ret, ret_owned_fd, ret_usize, size_of, slice, slice_mut, + socklen_t, zero, +}; use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use crate::net::{SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::net::{ + AddressFamily, Protocol, RecvAncillaryBuffer, RecvMsgReturn, SendAncillaryBuffer, Shutdown, + SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6, SocketFlags, SocketType, +}; use c::{sockaddr, sockaddr_in, sockaddr_in6, socklen_t}; -use core::convert::TryInto; use core::mem::MaybeUninit; #[cfg(target_arch = "x86")] use { - super::super::conv::{slice_just_addr, x86_sys}, - super::super::reg::{ArgReg, SocketArg}, - linux_raw_sys::general::{ + crate::backend::conv::{slice_just_addr, x86_sys}, + crate::backend::reg::{ArgReg, SocketArg}, + linux_raw_sys::net::{ SYS_ACCEPT, SYS_ACCEPT4, SYS_BIND, SYS_CONNECT, SYS_GETPEERNAME, SYS_GETSOCKNAME, - SYS_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_SEND, SYS_SENDTO, SYS_SETSOCKOPT, - SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, + SYS_GETSOCKOPT, SYS_LISTEN, SYS_RECV, SYS_RECVFROM, SYS_RECVMSG, SYS_SEND, SYS_SENDMSG, + SYS_SENDTO, SYS_SETSOCKOPT, SYS_SHUTDOWN, SYS_SOCKET, SYS_SOCKETPAIR, }, }; @@ -36,7 +40,7 @@ use { pub(crate) fn socket( family: AddressFamily, type_: SocketType, - protocol: Protocol, + protocol: Option<Protocol>, ) -> io::Result<OwnedFd> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -61,7 +65,7 @@ pub(crate) fn socket_with( family: AddressFamily, type_: SocketType, flags: SocketFlags, - protocol: Protocol, + protocol: Option<Protocol>, ) -> io::Result<OwnedFd> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -91,7 +95,7 @@ pub(crate) fn socketpair( family: AddressFamily, type_: SocketType, flags: SocketFlags, - protocol: Protocol, + protocol: Option<Protocol>, ) -> io::Result<(OwnedFd, OwnedFd)> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -240,6 +244,166 @@ pub(crate) fn acceptfrom_with( } #[inline] +pub(crate) fn recvmsg( + sockfd: BorrowedFd<'_>, + iov: &mut [IoSliceMut<'_>], + control: &mut RecvAncillaryBuffer<'_>, + msg_flags: RecvFlags, +) -> io::Result<RecvMsgReturn> { + let mut storage = MaybeUninit::<c::sockaddr_storage>::uninit(); + + with_recv_msghdr(&mut storage, iov, control, |msghdr| { + #[cfg(not(target_arch = "x86"))] + let result = + unsafe { ret_usize(syscall!(__NR_recvmsg, sockfd, by_mut(msghdr), msg_flags)) }; + + #[cfg(target_arch = "x86")] + let result = unsafe { + ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_RECVMSG), + slice_just_addr::<ArgReg<SocketArg>, _>(&[ + sockfd.into(), + by_mut(msghdr), + msg_flags.into(), + ]) + )) + }; + + result.map(|bytes| { + // Get the address of the sender, if any. + let addr = + unsafe { maybe_read_sockaddr_os(msghdr.msg_name as _, msghdr.msg_namelen as _) }; + + RecvMsgReturn { + bytes, + address: addr, + flags: RecvFlags::from_bits_retain(msghdr.msg_flags), + } + }) + }) +} + +#[inline] +pub(crate) fn sendmsg( + sockfd: BorrowedFd<'_>, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_noaddr_msghdr(iov, control, |msghdr| { + #[cfg(not(target_arch = "x86"))] + let result = + unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; + + #[cfg(target_arch = "x86")] + let result = unsafe { + ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_SENDMSG), + slice_just_addr::<ArgReg<SocketArg>, _>(&[ + sockfd.into(), + by_ref(&msghdr), + msg_flags.into() + ]) + )) + }; + + result + }) +} + +#[inline] +pub(crate) fn sendmsg_v4( + sockfd: BorrowedFd<'_>, + addr: &SocketAddrV4, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_v4_msghdr(addr, iov, control, |msghdr| { + #[cfg(not(target_arch = "x86"))] + let result = + unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; + + #[cfg(target_arch = "x86")] + let result = unsafe { + ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_SENDMSG), + slice_just_addr::<ArgReg<SocketArg>, _>(&[ + sockfd.into(), + by_ref(&msghdr), + msg_flags.into(), + ]) + )) + }; + + result + }) +} + +#[inline] +pub(crate) fn sendmsg_v6( + sockfd: BorrowedFd<'_>, + addr: &SocketAddrV6, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_v6_msghdr(addr, iov, control, |msghdr| { + #[cfg(not(target_arch = "x86"))] + let result = + unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; + + #[cfg(target_arch = "x86")] + let result = unsafe { + ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_SENDMSG), + slice_just_addr::<ArgReg<SocketArg>, _>(&[ + sockfd.into(), + by_ref(&msghdr), + msg_flags.into() + ]) + )) + }; + + result + }) +} + +#[inline] +pub(crate) fn sendmsg_unix( + sockfd: BorrowedFd<'_>, + addr: &SocketAddrUnix, + iov: &[IoSlice<'_>], + control: &mut SendAncillaryBuffer<'_, '_, '_>, + msg_flags: SendFlags, +) -> io::Result<usize> { + with_unix_msghdr(addr, iov, control, |msghdr| { + #[cfg(not(target_arch = "x86"))] + let result = + unsafe { ret_usize(syscall!(__NR_sendmsg, sockfd, by_ref(&msghdr), msg_flags)) }; + + #[cfg(target_arch = "x86")] + let result = unsafe { + ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_SENDMSG), + slice_just_addr::<ArgReg<SocketArg>, _>(&[ + sockfd.into(), + by_ref(&msghdr), + msg_flags.into() + ]) + )) + }; + + result + }) +} + +#[inline] pub(crate) fn shutdown(fd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { #[cfg(not(target_arch = "x86"))] unsafe { @@ -754,13 +918,9 @@ pub(crate) mod sockopt { use crate::net::sockopt::Timeout; use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; use c::{SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD}; - use core::convert::TryInto; use core::time::Duration; use linux_raw_sys::general::{__kernel_timespec, timeval}; - // TODO: With Rust 1.53 we can use `Duration::ZERO` instead. - const DURATION_ZERO: Duration = Duration::from_secs(0); - #[inline] fn getsockopt<T: Copy>(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result<T> { use super::*; @@ -910,12 +1070,7 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result<Option<Duration>> { let linger: c::linger = getsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER)?; - // TODO: With Rust 1.50, this could use `.then`. - Ok(if linger.l_onoff != 0 { - Some(Duration::from_secs(linger.l_linger as u64)) - } else { - None - }) + Ok((linger.l_onoff != 0).then(|| Duration::from_secs(linger.l_linger as u64))) } #[inline] @@ -1020,7 +1175,7 @@ pub(crate) mod sockopt { fn duration_to_linux(timeout: Option<Duration>) -> io::Result<__kernel_timespec> { Ok(match timeout { Some(timeout) => { - if timeout == DURATION_ZERO { + if timeout == Duration::ZERO { return Err(io::Errno::INVAL); } let mut timeout = __kernel_timespec { @@ -1043,7 +1198,7 @@ pub(crate) mod sockopt { fn duration_to_linux_old(timeout: Option<Duration>) -> io::Result<timeval> { Ok(match timeout { Some(timeout) => { - if timeout == DURATION_ZERO { + if timeout == Duration::ZERO { return Err(io::Errno::INVAL); } @@ -1186,14 +1341,14 @@ pub(crate) mod sockopt { setsockopt( fd, c::IPPROTO_IP as _, - c::IPV6_MULTICAST_LOOP, + c::IPV6_MULTICAST_HOPS, multicast_hops, ) } #[inline] pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result<u32> { - getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_LOOP) + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_HOPS) } #[inline] @@ -1244,7 +1399,7 @@ pub(crate) mod sockopt { #[inline] pub(crate) fn set_ipv6_unicast_hops(fd: BorrowedFd<'_>, hops: Option<u8>) -> io::Result<()> { let hops = match hops { - Some(hops) => hops as c::c_int, + Some(hops) => hops.into(), None => -1, }; setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_UNICAST_HOPS, hops) @@ -1286,7 +1441,7 @@ pub(crate) mod sockopt { #[inline] fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { c::in6_addr { - in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { u6_addr8: multiaddr.octets(), }, } diff --git a/vendor/rustix/src/backend/linux_raw/net/types.rs b/vendor/rustix/src/backend/linux_raw/net/types.rs deleted file mode 100644 index 3f0b571a5..000000000 --- a/vendor/rustix/src/backend/linux_raw/net/types.rs +++ /dev/null @@ -1,275 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -/// A type for holding raw integer socket types. -#[doc(hidden)] -pub type RawSocketType = u32; - -/// `SOCK_*` constants for use with [`socket`]. -/// -/// [`socket`]: crate::net::socket -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct SocketType(pub(crate) RawSocketType); - -#[rustfmt::skip] -impl SocketType { - /// `SOCK_STREAM` - pub const STREAM: Self = Self(c::SOCK_STREAM); - - /// `SOCK_DGRAM` - pub const DGRAM: Self = Self(c::SOCK_DGRAM); - - /// `SOCK_SEQPACKET` - pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET); - - /// `SOCK_RAW` - pub const RAW: Self = Self(c::SOCK_RAW); - - /// `SOCK_RDM` - pub const RDM: Self = Self(c::SOCK_RDM); - - /// Constructs a `SocketType` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawSocketType) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `SocketType`. - #[inline] - pub const fn as_raw(self) -> RawSocketType { - self.0 - } -} - -/// A type for holding raw integer address families. -#[doc(hidden)] -pub type RawAddressFamily = c::sa_family_t; - -/// `AF_*` constants. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct AddressFamily(pub(crate) RawAddressFamily); - -#[rustfmt::skip] -#[allow(non_upper_case_globals)] -impl AddressFamily { - /// `AF_UNSPEC` - pub const UNSPEC: Self = Self(c::AF_UNSPEC as _); - /// `AF_INET` - pub const INET: Self = Self(c::AF_INET as _); - /// `AF_INET6` - pub const INET6: Self = Self(c::AF_INET6 as _); - /// `AF_NETLINK` - pub const NETLINK: Self = Self(c::AF_NETLINK as _); - /// `AF_UNIX`, aka `AF_LOCAL` - #[doc(alias = "LOCAL")] - pub const UNIX: Self = Self(c::AF_UNIX as _); - /// `AF_AX25` - pub const AX25: Self = Self(c::AF_AX25 as _); - /// `AF_IPX` - pub const IPX: Self = Self(c::AF_IPX as _); - /// `AF_APPLETALK` - pub const APPLETALK: Self = Self(c::AF_APPLETALK as _); - /// `AF_NETROM` - pub const NETROM: Self = Self(c::AF_NETROM as _); - /// `AF_BRIDGE` - pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); - /// `AF_ATMPVC` - pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); - /// `AF_X25` - pub const X25: Self = Self(c::AF_X25 as _); - /// `AF_ROSE` - pub const ROSE: Self = Self(c::AF_ROSE as _); - /// `AF_DECnet` - pub const DECnet: Self = Self(c::AF_DECnet as _); - /// `AF_NETBEUI` - pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); - /// `AF_SECURITY` - pub const SECURITY: Self = Self(c::AF_SECURITY as _); - /// `AF_KEY` - pub const KEY: Self = Self(c::AF_KEY as _); - /// `AF_PACKET` - pub const PACKET: Self = Self(c::AF_PACKET as _); - /// `AF_ASH` - pub const ASH: Self = Self(c::AF_ASH as _); - /// `AF_ECONET` - pub const ECONET: Self = Self(c::AF_ECONET as _); - /// `AF_ATMSVC` - pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); - /// `AF_RDS` - pub const RDS: Self = Self(c::AF_RDS as _); - /// `AF_SNA` - pub const SNA: Self = Self(c::AF_SNA as _); - /// `AF_IRDA` - pub const IRDA: Self = Self(c::AF_IRDA as _); - /// `AF_PPPOX` - pub const PPPOX: Self = Self(c::AF_PPPOX as _); - /// `AF_WANPIPE` - pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); - /// `AF_LLC` - pub const LLC: Self = Self(c::AF_LLC as _); - /// `AF_CAN` - pub const CAN: Self = Self(c::AF_CAN as _); - /// `AF_TIPC` - pub const TIPC: Self = Self(c::AF_TIPC as _); - /// `AF_BLUETOOTH` - pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); - /// `AF_IUCV` - pub const IUCV: Self = Self(c::AF_IUCV as _); - /// `AF_RXRPC` - pub const RXRPC: Self = Self(c::AF_RXRPC as _); - /// `AF_ISDN` - pub const ISDN: Self = Self(c::AF_ISDN as _); - /// `AF_PHONET` - pub const PHONET: Self = Self(c::AF_PHONET as _); - /// `AF_IEEE802154` - pub const IEEE802154: Self = Self(c::AF_IEEE802154 as _); - - /// Constructs a `AddressFamily` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawAddressFamily) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `AddressFamily`. - #[inline] - pub const fn as_raw(self) -> RawAddressFamily { - self.0 - } -} - -/// A type for holding raw integer protocols. -#[doc(hidden)] -pub type RawProtocol = u32; - -/// `IPPROTO_*` constants for use with [`socket`] and [`socket_with`]. -/// -/// [`socket`]: crate::net::socket -/// [`socket_with`]: crate::net::socket_with -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(transparent)] -pub struct Protocol(pub(crate) RawProtocol); - -#[rustfmt::skip] -impl Protocol { - /// `IPPROTO_IP` - pub const IP: Self = Self(c::IPPROTO_IP as _); - /// `IPPROTO_ICMP` - pub const ICMP: Self = Self(c::IPPROTO_ICMP as _); - /// `IPPROTO_IGMP` - pub const IGMP: Self = Self(c::IPPROTO_IGMP as _); - /// `IPPROTO_IPIP` - pub const IPIP: Self = Self(c::IPPROTO_IPIP as _); - /// `IPPROTO_TCP` - pub const TCP: Self = Self(c::IPPROTO_TCP as _); - /// `IPPROTO_EGP` - pub const EGP: Self = Self(c::IPPROTO_EGP as _); - /// `IPPROTO_PUP` - pub const PUP: Self = Self(c::IPPROTO_PUP as _); - /// `IPPROTO_UDP` - pub const UDP: Self = Self(c::IPPROTO_UDP as _); - /// `IPPROTO_IDP` - pub const IDP: Self = Self(c::IPPROTO_IDP as _); - /// `IPPROTO_TP` - pub const TP: Self = Self(c::IPPROTO_TP as _); - /// `IPPROTO_DCCP` - pub const DCCP: Self = Self(c::IPPROTO_DCCP as _); - /// `IPPROTO_IPV6` - pub const IPV6: Self = Self(c::IPPROTO_IPV6 as _); - /// `IPPROTO_RSVP` - pub const RSVP: Self = Self(c::IPPROTO_RSVP as _); - /// `IPPROTO_GRE` - pub const GRE: Self = Self(c::IPPROTO_GRE as _); - /// `IPPROTO_ESP` - pub const ESP: Self = Self(c::IPPROTO_ESP as _); - /// `IPPROTO_AH` - pub const AH: Self = Self(c::IPPROTO_AH as _); - /// `IPPROTO_MTP` - pub const MTP: Self = Self(c::IPPROTO_MTP as _); - /// `IPPROTO_BEETPH` - pub const BEETPH: Self = Self(c::IPPROTO_BEETPH as _); - /// `IPPROTO_ENCAP` - pub const ENCAP: Self = Self(c::IPPROTO_ENCAP as _); - /// `IPPROTO_PIM` - pub const PIM: Self = Self(c::IPPROTO_PIM as _); - /// `IPPROTO_COMP` - pub const COMP: Self = Self(c::IPPROTO_COMP as _); - /// `IPPROTO_SCTP` - pub const SCTP: Self = Self(c::IPPROTO_SCTP as _); - /// `IPPROTO_UDPLITE` - pub const UDPLITE: Self = Self(c::IPPROTO_UDPLITE as _); - /// `IPPROTO_MPLS` - pub const MPLS: Self = Self(c::IPPROTO_MPLS as _); - /// `IPPROTO_ETHERNET` - pub const ETHERNET: Self = Self(c::IPPROTO_ETHERNET as _); - /// `IPPROTO_RAW` - pub const RAW: Self = Self(c::IPPROTO_RAW as _); - /// `IPPROTO_MPTCP` - pub const MPTCP: Self = Self(c::IPPROTO_MPTCP as _); - /// `IPPROTO_FRAGMENT` - pub const FRAGMENT: Self = Self(c::IPPROTO_FRAGMENT as _); - /// `IPPROTO_ICMPV6` - pub const ICMPV6: Self = Self(c::IPPROTO_ICMPV6 as _); - /// `IPPROTO_MH` - pub const MH: Self = Self(c::IPPROTO_MH as _); - /// `IPPROTO_ROUTING` - pub const ROUTING: Self = Self(c::IPPROTO_ROUTING as _); - - /// Constructs a `Protocol` from a raw integer. - #[inline] - pub const fn from_raw(raw: RawProtocol) -> Self { - Self(raw) - } - - /// Returns the raw integer for this `Protocol`. - #[inline] - pub const fn as_raw(self) -> RawProtocol { - self.0 - } -} - -/// `SHUT_*` constants for use with [`shutdown`]. -/// -/// [`shutdown`]: crate::net::shutdown -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Shutdown { - /// `SHUT_RD`—Disable further read operations. - Read = c::SHUT_RD, - /// `SHUT_WR`—Disable further write operations. - Write = c::SHUT_WR, - /// `SHUT_RDWR`—Disable further read and write operations. - ReadWrite = c::SHUT_RDWR, -} - -bitflags! { - /// `SOCK_*` constants for use with [`socket_with`], [`accept_with`] and - /// [`acceptfrom_with`]. - /// - /// [`socket_with`]: crate::net::socket_with - /// [`accept_with`]: crate::net::accept_with - /// [`acceptfrom_with`]: crate::net::acceptfrom_with - pub struct SocketFlags: c::c_uint { - /// `SOCK_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - - /// `SOCK_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - } -} - -/// Timeout identifier for use with [`set_socket_timeout`] and -/// [`get_socket_timeout`]. -/// -/// [`set_socket_timeout`]: crate::net::sockopt::set_socket_timeout. -/// [`get_socket_timeout`]: crate::net::sockopt::get_socket_timeout. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Timeout { - /// `SO_RCVTIMEO`—Timeout for receiving. - Recv = c::SO_RCVTIMEO_NEW, - - /// `SO_SNDTIMEO`—Timeout for sending. - Send = c::SO_SNDTIMEO_NEW, -} diff --git a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs index 17abd96a0..28da05cd0 100644 --- a/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs +++ b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs @@ -2,7 +2,7 @@ //! we can interpret the rest of a `sockaddr` produced by the kernel. #![allow(unsafe_code)] -use super::super::c; +use crate::backend::c; use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; use core::mem::size_of; @@ -40,7 +40,7 @@ pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { sin6_port: u16::to_be(v6.port()), sin6_flowinfo: u32::to_be(v6.flowinfo()), sin6_addr: c::in6_addr { - in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { + in6_u: linux_raw_sys::net::in6_addr__bindgen_ty_1 { u6_addr8: v6.ip().octets(), }, }, diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs index 741a0564f..bf8935a0d 100644 --- a/vendor/rustix/src/backend/linux_raw/param/auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/auxv.rs @@ -5,12 +5,11 @@ //! This uses raw pointers to locate and read the kernel-provided auxv array. #![allow(unsafe_code)] -use super::super::c; -use super::super::elf::*; +use crate::backend::c; +use crate::backend::elf::*; use crate::fd::OwnedFd; #[cfg(feature = "param")] use crate::ffi::CStr; -#[cfg(not(target_vendor = "mustang"))] use crate::fs::{Mode, OFlags}; use crate::utils::{as_ptr, check_raw_pointer}; use alloc::vec::Vec; @@ -32,7 +31,7 @@ pub(crate) fn page_size() -> usize { let mut page_size = PAGE_SIZE.load(Relaxed); if page_size == 0 { - init_from_proc_self_auxv(); + init_auxv(); page_size = PAGE_SIZE.load(Relaxed); } @@ -45,7 +44,7 @@ pub(crate) fn clock_ticks_per_second() -> u64 { let mut ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed); if ticks == 0 { - init_from_proc_self_auxv(); + init_auxv(); ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed); } @@ -59,7 +58,7 @@ pub(crate) fn linux_hwcap() -> (usize, usize) { let mut hwcap2 = HWCAP2.load(Relaxed); if hwcap == 0 || hwcap2 == 0 { - init_from_proc_self_auxv(); + init_auxv(); hwcap = HWCAP.load(Relaxed); hwcap2 = HWCAP2.load(Relaxed); } @@ -73,7 +72,7 @@ pub(crate) fn linux_execfn() -> &'static CStr { let mut execfn = EXECFN.load(Relaxed); if execfn.is_null() { - init_from_proc_self_auxv(); + init_auxv(); execfn = EXECFN.load(Relaxed); } @@ -89,7 +88,7 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) { let mut phnum = PHNUM.load(Relaxed); if phdr.is_null() || phnum == 0 { - init_from_proc_self_auxv(); + init_auxv(); phdr = PHDR.load(Relaxed); phnum = PHNUM.load(Relaxed); } @@ -114,7 +113,7 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { let mut ehdr = SYSINFO_EHDR.load(Relaxed); if ehdr.is_null() { - init_from_proc_self_auxv(); + init_auxv(); ehdr = SYSINFO_EHDR.load(Relaxed); } @@ -130,29 +129,61 @@ static PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(null_mut()); static PHNUM: AtomicUsize = AtomicUsize::new(0); static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(null_mut()); -/// On non-Mustang platforms, we read the aux vector from /proc/self/auxv. -#[cfg(not(target_vendor = "mustang"))] -fn init_from_proc_self_auxv() { +fn pr_get_auxv() -> crate::io::Result<Vec<u8>> { + use super::super::conv::{c_int, pass_usize, ret_usize}; + const PR_GET_AUXV: c::c_int = 0x41555856; + let mut buffer = alloc::vec![0u8; 512]; + let len = unsafe { + ret_usize(syscall_always_asm!( + __NR_prctl, + c_int(PR_GET_AUXV), + buffer.as_ptr(), + pass_usize(buffer.len()) + ))? + }; + if len <= buffer.len() { + buffer.truncate(len); + return Ok(buffer); + } + buffer.resize(len, 0); + let len = unsafe { + ret_usize(syscall_always_asm!( + __NR_prctl, + c_int(PR_GET_AUXV), + buffer.as_ptr(), + pass_usize(buffer.len()) + ))? + }; + assert_eq!(len, buffer.len()); + return Ok(buffer); +} + +/// On non-Mustang platforms, we read the aux vector via the `prctl` +/// `PR_GET_AUXV`, with a fallback to /proc/self/auxv for kernels that don't +/// support `PR_GET_AUXV`. +fn init_auxv() { + match pr_get_auxv() { + Ok(buffer) => { + // SAFETY: We assume the kernel returns a valid auxv. + unsafe { + init_from_auxp(buffer.as_ptr().cast()); + } + return; + } + Err(_) => { + // Fall back to /proc/self/auxv on error. + } + } + // Open "/proc/self/auxv", either because we trust "/proc", or because // we're running inside QEMU and `proc_self_auxv`'s extra checking foils // QEMU's emulation so we need to do a plain open to get the right // auxv records. - let file = crate::fs::openat( - crate::fs::cwd(), - "/proc/self/auxv", - OFlags::empty(), - Mode::empty(), - ) - .unwrap(); + let file = crate::fs::open("/proc/self/auxv", OFlags::RDONLY, Mode::empty()).unwrap(); let _ = init_from_auxv_file(file); } -#[cfg(target_vendor = "mustang")] -fn init_from_proc_self_auxv() { - panic!("mustang should have initialized the auxv values"); -} - /// Process auxv entries from the open file `auxv`. fn init_from_auxv_file(auxv: OwnedFd) -> Option<()> { let mut buffer = Vec::<u8>::with_capacity(512); @@ -276,7 +307,7 @@ unsafe fn check_vdso_base(base: *const Elf_Ehdr) -> Option<NonNull<Elf_Ehdr>> { // as an arbitrary system call which writes to a buffer and fails with // `EFAULT` if the buffer is not writable. { - use super::super::conv::{c_uint, ret}; + use crate::backend::conv::{c_uint, ret}; if ret(syscall!( __NR_clock_getres, c_uint(linux_raw_sys::general::CLOCK_MONOTONIC), diff --git a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs index a8e291ff6..d05a87e53 100644 --- a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs @@ -5,59 +5,124 @@ //! This uses raw pointers to locate and read the kernel-provided auxv array. #![allow(unsafe_code)] -use super::super::elf::*; +use crate::backend::c; +use crate::backend::elf::*; #[cfg(feature = "param")] use crate::ffi::CStr; +#[cfg(not(feature = "runtime"))] +use core::ptr::null; #[cfg(feature = "runtime")] use core::slice; -// `getauxval` wasn't supported in glibc until 2.16. -weak!(fn getauxval(libc::c_ulong) -> *mut libc::c_void); +// `getauxval` wasn't supported in glibc until 2.16. Also this lets us use +// `*mut` as the return type to preserve strict provenance. +#[cfg(not(feature = "runtime"))] +weak!(fn getauxval(c::c_ulong) -> *mut c::c_void); + +// With the "runtime" feature, go ahead and depend on `getauxval` existing +// so that we never fail. +#[cfg(feature = "runtime")] +extern "C" { + fn getauxval(type_: c::c_ulong) -> *mut c::c_void; +} + +const AT_PHDR: c::c_ulong = 3; +const AT_PHNUM: c::c_ulong = 5; +const AT_HWCAP: c::c_ulong = 16; +const AT_HWCAP2: c::c_ulong = 26; +const AT_EXECFN: c::c_ulong = 31; +const AT_SYSINFO_EHDR: c::c_ulong = 33; + +// Declare `sysconf` ourselves so that we don't depend on all of libc +// just for this. +extern "C" { + fn sysconf(name: c::c_int) -> c::c_long; +} + +#[cfg(target_os = "android")] +const _SC_PAGESIZE: c::c_int = 39; +#[cfg(target_os = "emscripten")] +const _SC_PAGESIZE: c::c_int = 30; +#[cfg(target_os = "linux")] +const _SC_PAGESIZE: c::c_int = 30; +#[cfg(target_os = "android")] +const _SC_CLK_TCK: c::c_int = 6; +#[cfg(target_os = "emscripten")] +const _SC_CLK_TCK: c::c_int = 2; +#[cfg(target_os = "linux")] +const _SC_CLK_TCK: c::c_int = 2; + +#[test] +fn test_abi() { + assert_eq!(self::_SC_PAGESIZE, ::libc::_SC_PAGESIZE); + assert_eq!(self::_SC_CLK_TCK, ::libc::_SC_CLK_TCK); + assert_eq!(self::AT_PHDR, ::libc::AT_PHDR); + assert_eq!(self::AT_PHNUM, ::libc::AT_PHNUM); + assert_eq!(self::AT_HWCAP, ::libc::AT_HWCAP); + assert_eq!(self::AT_HWCAP2, ::libc::AT_HWCAP2); + assert_eq!(self::AT_EXECFN, ::libc::AT_EXECFN); + assert_eq!(self::AT_SYSINFO_EHDR, ::libc::AT_SYSINFO_EHDR); +} #[cfg(feature = "param")] #[inline] pub(crate) fn page_size() -> usize { - unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } + unsafe { sysconf(_SC_PAGESIZE) as usize } } #[cfg(feature = "param")] #[inline] pub(crate) fn clock_ticks_per_second() -> u64 { - unsafe { libc::sysconf(libc::_SC_CLK_TCK) as u64 } + unsafe { sysconf(_SC_CLK_TCK) as u64 } } #[cfg(feature = "param")] #[inline] pub(crate) fn linux_hwcap() -> (usize, usize) { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { - let hwcap = libc_getauxval(libc::AT_HWCAP) as usize; - let hwcap2 = libc_getauxval(libc::AT_HWCAP2) as usize; + #[cfg(not(feature = "runtime"))] + unsafe { + if let Some(libc_getauxval) = getauxval.get() { + let hwcap = libc_getauxval(AT_HWCAP) as usize; + let hwcap2 = libc_getauxval(AT_HWCAP2) as usize; (hwcap, hwcap2) + } else { + (0, 0) } - } else { - (0, 0) + } + + #[cfg(feature = "runtime")] + unsafe { + let hwcap = getauxval(AT_HWCAP) as usize; + let hwcap2 = getauxval(AT_HWCAP2) as usize; + (hwcap, hwcap2) } } #[cfg(feature = "param")] #[inline] pub(crate) fn linux_execfn() -> &'static CStr { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { CStr::from_ptr(libc_getauxval(libc::AT_EXECFN).cast()) } - } else { - cstr!("") + #[cfg(not(feature = "runtime"))] + unsafe { + if let Some(libc_getauxval) = getauxval.get() { + CStr::from_ptr(libc_getauxval(AT_EXECFN).cast()) + } else { + cstr!("") + } + } + + #[cfg(feature = "runtime")] + unsafe { + CStr::from_ptr(getauxval(AT_EXECFN).cast()) } } #[cfg(feature = "runtime")] #[inline] -pub(crate) fn exe_phdrs() -> (*const libc::c_void, usize) { +pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) { unsafe { - ( - libc::getauxval(libc::AT_PHDR) as *const libc::c_void, - libc::getauxval(libc::AT_PHNUM) as usize, - ) + let phdr = getauxval(AT_PHDR) as *const c::c_void; + let phnum = getauxval(AT_PHNUM) as usize; + (phdr, phnum) } } @@ -75,9 +140,17 @@ pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] { /// so if we don't see it, this function returns a null pointer. #[inline] pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { libc_getauxval(linux_raw_sys::general::AT_SYSINFO_EHDR.into()) as *const Elf_Ehdr } - } else { - core::ptr::null() + #[cfg(not(feature = "runtime"))] + unsafe { + if let Some(libc_getauxval) = getauxval.get() { + libc_getauxval(AT_SYSINFO_EHDR) as *const Elf_Ehdr + } else { + null() + } + } + + #[cfg(feature = "runtime")] + unsafe { + getauxval(AT_SYSINFO_EHDR) as *const Elf_Ehdr } } diff --git a/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs index 49cb1457c..f45a25faf 100644 --- a/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs +++ b/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs @@ -5,8 +5,8 @@ //! This uses raw pointers to locate and read the kernel-provided auxv array. #![allow(unsafe_code)] -use super::super::c; -use super::super::elf::*; +use crate::backend::c; +use crate::backend::elf::*; #[cfg(feature = "param")] use crate::ffi::CStr; use core::ffi::c_void; diff --git a/vendor/rustix/src/backend/linux_raw/pid/mod.rs b/vendor/rustix/src/backend/linux_raw/pid/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pid/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/pid/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pid/syscalls.rs new file mode 100644 index 000000000..f36bac048 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pid/syscalls.rs @@ -0,0 +1,18 @@ +//! linux_raw syscalls for PIDs +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use crate::backend::conv::ret_usize_infallible; +use crate::pid::{Pid, RawPid}; + +#[inline] +pub(crate) fn getpid() -> Pid { + unsafe { + let pid = ret_usize_infallible(syscall_readonly!(__NR_getpid)) as RawPid; + Pid::from_raw_unchecked(pid) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/pipe/mod.rs b/vendor/rustix/src/backend/linux_raw/pipe/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pipe/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs new file mode 100644 index 000000000..ed121089d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs @@ -0,0 +1,132 @@ +//! linux_raw syscalls supporting `rustix::pipe`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use crate::backend::conv::{c_int, c_uint, opt_mut, pass_usize, ret, ret_usize, slice}; +use crate::backend::{c, MAX_IOV}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use crate::pipe::{IoSliceRaw, PipeFlags, SpliceFlags}; +use core::cmp; +use core::mem::MaybeUninit; +use linux_raw_sys::general::{F_GETPIPE_SZ, F_SETPIPE_SZ}; + +#[inline] +pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { + // aarch64 and risc64 omit `__NR_pipe`. On mips, `__NR_pipe` uses a special + // calling convention, but using it is not worth complicating our syscall + // wrapping infrastructure at this time. + #[cfg(any( + target_arch = "aarch64", + target_arch = "mips", + target_arch = "mips64", + target_arch = "riscv64", + ))] + { + pipe_with(PipeFlags::empty()) + } + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "mips", + target_arch = "mips64", + target_arch = "riscv64", + )))] + unsafe { + let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(syscall!(__NR_pipe, &mut result))?; + let [p0, p1] = result.assume_init(); + Ok((p0, p1)) + } +} + +#[inline] +pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { + unsafe { + let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(syscall!(__NR_pipe2, &mut result, flags))?; + let [p0, p1] = result.assume_init(); + Ok((p0, p1)) + } +} + +#[inline] +pub fn splice( + fd_in: BorrowedFd, + off_in: Option<&mut u64>, + fd_out: BorrowedFd, + off_out: Option<&mut u64>, + len: usize, + flags: SpliceFlags, +) -> io::Result<usize> { + unsafe { + ret_usize(syscall!( + __NR_splice, + fd_in, + opt_mut(off_in), + fd_out, + opt_mut(off_out), + pass_usize(len), + flags + )) + } +} + +#[inline] +pub unsafe fn vmsplice( + fd: BorrowedFd, + bufs: &[IoSliceRaw], + flags: SpliceFlags, +) -> io::Result<usize> { + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]); + ret_usize(syscall!(__NR_vmsplice, fd, bufs_addr, bufs_len, flags)) +} + +#[inline] +pub fn tee( + fd_in: BorrowedFd, + fd_out: BorrowedFd, + len: usize, + flags: SpliceFlags, +) -> io::Result<usize> { + unsafe { ret_usize(syscall!(__NR_tee, fd_in, fd_out, pass_usize(len), flags)) } +} + +#[inline] +pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret_usize(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETPIPE_SZ))) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETPIPE_SZ))) + } +} + +#[inline] +pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> { + let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?; + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!( + __NR_fcntl64, + fd, + c_uint(F_SETPIPE_SZ), + c_int(size) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_fcntl, + fd, + c_uint(F_SETPIPE_SZ), + c_int(size) + )) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/pipe/types.rs b/vendor/rustix/src/backend/linux_raw/pipe/types.rs new file mode 100644 index 000000000..90d2d79ab --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pipe/types.rs @@ -0,0 +1,72 @@ +use crate::backend::c; +use bitflags::bitflags; +use core::marker::PhantomData; + +bitflags! { + /// `O_*` constants for use with [`pipe_with`]. + /// + /// [`pipe_with`]: crate::io::pipe_with + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct PipeFlags: c::c_uint { + /// `O_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; + /// `O_DIRECT` + const DIRECT = linux_raw_sys::general::O_DIRECT; + /// `O_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; + } +} + +bitflags! { + /// `SPLICE_F_*` constants for use with [`splice`] [`vmsplice`], and + /// [`tee`]. + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct SpliceFlags: c::c_uint { + /// `SPLICE_F_MOVE` + const MOVE = linux_raw_sys::general::SPLICE_F_MOVE; + /// `SPLICE_F_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::SPLICE_F_NONBLOCK; + /// `SPLICE_F_MORE` + const MORE = linux_raw_sys::general::SPLICE_F_MORE; + /// `SPLICE_F_GIFT` + const GIFT = linux_raw_sys::general::SPLICE_F_GIFT; + } +} + +/// A buffer type used with `vmsplice`. +/// +/// It is guaranteed to be ABI compatible with the iovec type on Unix platforms +/// and `WSABUF` on Windows. Unlike `IoSlice` and `IoSliceMut` it is +/// semantically like a raw pointer, and therefore can be shared or mutated as +/// needed. +#[repr(transparent)] +pub struct IoSliceRaw<'a> { + _buf: c::iovec, + _lifetime: PhantomData<&'a ()>, +} + +impl<'a> IoSliceRaw<'a> { + /// Creates a new `IoSlice` wrapping a byte slice. + pub fn from_slice(buf: &'a [u8]) -> Self { + IoSliceRaw { + _buf: c::iovec { + iov_base: (buf.as_ptr() as *mut u8).cast::<c::c_void>(), + iov_len: buf.len() as _, + }, + _lifetime: PhantomData, + } + } + + /// Creates a new `IoSlice` wrapping a mutable byte slice. + pub fn from_slice_mut(buf: &'a mut [u8]) -> Self { + IoSliceRaw { + _buf: c::iovec { + iov_base: buf.as_mut_ptr().cast::<c::c_void>(), + iov_len: buf.len() as _, + }, + _lifetime: PhantomData, + } + } +} diff --git a/vendor/rustix/src/backend/linux_raw/prctl/mod.rs b/vendor/rustix/src/backend/linux_raw/prctl/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/prctl/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/prctl/syscalls.rs b/vendor/rustix/src/backend/linux_raw/prctl/syscalls.rs new file mode 100644 index 000000000..193f4b7b4 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/prctl/syscalls.rs @@ -0,0 +1,22 @@ +//! linux_raw syscalls supporting modules that use `prctl`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::{c_int, ret_c_int}; +use crate::io; + +#[inline] +pub(crate) unsafe fn prctl( + option: c::c_int, + arg2: *mut c::c_void, + arg3: *mut c::c_void, + arg4: *mut c::c_void, + arg5: *mut c::c_void, +) -> io::Result<c::c_int> { + ret_c_int(syscall!(__NR_prctl, c_int(option), arg2, arg3, arg4, arg5)) +} diff --git a/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs b/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs index fc81859d8..35146cfd2 100644 --- a/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs +++ b/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs @@ -14,10 +14,7 @@ pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { #[inline] pub(crate) fn CPU_ZERO(cpuset: &mut RawCpuSet) { - // TODO: With, Rust 1.50, use `cpuset.bits.fill(0)` instead. - for element in &mut cpuset.bits { - *element = 0; - } + cpuset.bits.fill(0) } #[inline] diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs index 0eb6489e7..ac6e28901 100644 --- a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs @@ -6,34 +6,38 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; -use super::super::conv::{ - by_mut, by_ref, c_int, c_uint, negative_pid, pass_usize, ret, ret_c_int, ret_c_uint, - ret_infallible, ret_usize, ret_usize_infallible, size_of, slice, slice_just_addr, - slice_just_addr_mut, slice_mut, zero, +use super::types::RawCpuSet; +use crate::backend::c; +#[cfg(feature = "fs")] +use crate::backend::conv::slice_mut; +use crate::backend::conv::{ + by_mut, by_ref, c_int, c_uint, negative_pid, pass_usize, raw_fd, ret, ret_c_int, + ret_c_int_infallible, ret_c_uint, ret_infallible, ret_owned_fd, ret_usize, size_of, + slice_just_addr, slice_just_addr_mut, zero, }; -use super::types::{RawCpuSet, RawUname}; -use crate::backend::conv::ret_owned_fd; -use crate::fd::{AsRawFd, BorrowedFd, OwnedFd}; +use crate::fd::{AsRawFd, BorrowedFd, OwnedFd, RawFd}; +#[cfg(feature = "fs")] use crate::ffi::CStr; use crate::io; +use crate::pid::RawPid; use crate::process::{ - Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, PidfdFlags, RawNonZeroPid, RawPid, - Resource, Rlimit, Signal, Sysinfo, Uid, WaitId, WaitOptions, WaitStatus, WaitidOptions, - WaitidStatus, + Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, PidfdFlags, PidfdGetfdFlags, Resource, + Rlimit, Uid, WaitId, WaitOptions, WaitStatus, WaitidOptions, WaitidStatus, }; -use core::convert::TryInto; +use crate::signal::Signal; +use crate::utils::as_mut_ptr; use core::mem::MaybeUninit; -use core::num::NonZeroU32; use core::ptr::{null, null_mut}; use linux_raw_sys::general::{ - __kernel_gid_t, __kernel_pid_t, __kernel_uid_t, membarrier_cmd, membarrier_cmd_flag, rlimit, - rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, RLIM64_INFINITY, RLIM_INFINITY, + membarrier_cmd, membarrier_cmd_flag, rlimit, rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, + RLIM64_INFINITY, RLIM_INFINITY, }; +use linux_raw_sys::ioctl::TIOCSCTTY; #[cfg(not(target_os = "wasi"))] #[cfg(feature = "fs")] -use {super::super::conv::ret_c_uint_infallible, crate::fs::Mode}; +use {crate::backend::conv::ret_c_uint_infallible, crate::fs::Mode}; +#[cfg(feature = "fs")] #[inline] pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_chdir, filename)) } @@ -44,13 +48,15 @@ pub(crate) fn fchdir(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_fchdir, fd)) } } +#[cfg(feature = "fs")] #[inline] pub(crate) fn chroot(filename: &CStr) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_chroot, filename)) } } +#[cfg(feature = "fs")] #[inline] -pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result<usize> { +pub(crate) fn getcwd(buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> { let (buf_addr_mut, buf_len) = slice_mut(buf); unsafe { ret_usize(syscall!(__NR_getcwd, buf_addr_mut, buf_len)) } } @@ -63,15 +69,7 @@ pub(crate) fn membarrier_query() -> MembarrierQuery { c_int(membarrier_cmd::MEMBARRIER_CMD_QUERY as _), c_uint(0) )) { - Ok(query) => { - // SAFETY: The safety of `from_bits_unchecked` is discussed - // [here]. Our "source of truth" is Linux, and here, the - // `query` value is coming from Linux, so we know it only - // contains "source of truth" valid bits. - // - // [here]: https://github.com/bitflags/bitflags/pull/207#issuecomment-671668662 - MembarrierQuery::from_bits_unchecked(query) - } + Ok(query) => MembarrierQuery::from_bits_retain(query), Err(_) => MembarrierQuery::empty(), } } @@ -95,30 +93,19 @@ pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<( } #[inline] -pub(crate) fn getpid() -> Pid { - unsafe { - let pid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getpid)) as __kernel_pid_t; - debug_assert!(pid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid as u32)) - } -} - -#[inline] pub(crate) fn getppid() -> Option<Pid> { unsafe { - let ppid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getppid)) as __kernel_pid_t; - Pid::from_raw(ppid as u32) + let ppid = ret_c_int_infallible(syscall_readonly!(__NR_getppid)); + Pid::from_raw(ppid) } } #[inline] pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { unsafe { - let pgid: i32 = - ret_usize(syscall_readonly!(__NR_getpgid, c_uint(Pid::as_raw(pid))))? as __kernel_pid_t; - Ok(Pid::from_raw_nonzero(NonZeroU32::new_unchecked( - pgid as u32, - ))) + let pgid = ret_c_int(syscall_readonly!(__NR_getpgid, c_int(Pid::as_raw(pid))))?; + debug_assert!(pgid > 0); + Ok(Pid::from_raw_unchecked(pgid)) } } @@ -127,8 +114,8 @@ pub(crate) fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { unsafe { ret(syscall_readonly!( __NR_setpgid, - c_uint(Pid::as_raw(pid)), - c_uint(Pid::as_raw(pgid)) + c_int(Pid::as_raw(pid)), + c_int(Pid::as_raw(pgid)) )) } } @@ -138,77 +125,17 @@ pub(crate) fn getpgrp() -> Pid { // Use the `getpgrp` syscall if available. #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] unsafe { - let pgid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getpgrp)) as __kernel_pid_t; + let pgid = ret_c_int_infallible(syscall_readonly!(__NR_getpgrp)); debug_assert!(pgid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid as u32)) + Pid::from_raw_unchecked(pgid) } // Otherwise use `getpgrp` and pass it zero. #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] unsafe { - let pgid: i32 = - ret_usize_infallible(syscall_readonly!(__NR_getpgid, c_uint(0))) as __kernel_pid_t; + let pgid = ret_c_int_infallible(syscall_readonly!(__NR_getpgid, c_uint(0))); debug_assert!(pgid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid as u32)) - } -} - -#[inline] -pub(crate) fn getgid() -> Gid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let gid: i32 = - (ret_usize_infallible(syscall_readonly!(__NR_getgid32)) as __kernel_gid_t).into(); - Gid::from_raw(gid as u32) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getgid)) as __kernel_gid_t; - Gid::from_raw(gid as u32) - } -} - -#[inline] -pub(crate) fn getegid() -> Gid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let gid: i32 = - (ret_usize_infallible(syscall_readonly!(__NR_getegid32)) as __kernel_gid_t).into(); - Gid::from_raw(gid as u32) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getegid)) as __kernel_gid_t; - Gid::from_raw(gid as u32) - } -} - -#[inline] -pub(crate) fn getuid() -> Uid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let uid = (ret_usize_infallible(syscall_readonly!(__NR_getuid32)) as __kernel_uid_t).into(); - Uid::from_raw(uid) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_getuid)) as __kernel_uid_t; - Uid::from_raw(uid as u32) - } -} - -#[inline] -pub(crate) fn geteuid() -> Uid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let uid: i32 = - (ret_usize_infallible(syscall_readonly!(__NR_geteuid32)) as __kernel_uid_t).into(); - Uid::from_raw(uid as u32) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_geteuid)) as __kernel_uid_t; - Uid::from_raw(uid as u32) + Pid::from_raw_unchecked(pgid) } } @@ -220,11 +147,11 @@ pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io: // set bit mask. let size = ret_usize(syscall!( __NR_sched_getaffinity, - c_uint(Pid::as_raw(pid)), + c_int(Pid::as_raw(pid)), size_of::<RawCpuSet, _>(), by_mut(&mut cpuset.bits) ))?; - let bytes = (cpuset as *mut RawCpuSet).cast::<u8>(); + let bytes = as_mut_ptr(cpuset).cast::<u8>(); let rest = bytes.wrapping_add(size); // Zero every byte in the cpuset not set by the kernel. rest.write_bytes(0, core::mem::size_of::<RawCpuSet>() - size); @@ -237,7 +164,7 @@ pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Res unsafe { ret(syscall_readonly!( __NR_sched_setaffinity, - c_uint(Pid::as_raw(pid)), + c_int(Pid::as_raw(pid)), size_of::<RawCpuSet, _>(), slice_just_addr(&cpuset.bits) )) @@ -253,35 +180,20 @@ pub(crate) fn sched_yield() { } } -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::<RawUname>::uninit(); - unsafe { - ret_infallible(syscall!(__NR_uname, &mut uname)); - uname.assume_init() - } -} - #[cfg(feature = "fs")] #[inline] pub(crate) fn umask(mode: Mode) -> Mode { - unsafe { - // TODO: Use `from_bits_retain` when we switch to bitflags 2.0. - Mode::from_bits_truncate(ret_c_uint_infallible(syscall_readonly!(__NR_umask, mode))) - } + unsafe { Mode::from_bits_retain(ret_c_uint_infallible(syscall_readonly!(__NR_umask, mode))) } } #[inline] pub(crate) fn nice(inc: i32) -> io::Result<i32> { - let priority = if inc > -40 && inc < 40 { + let priority = (if inc > -40 && inc < 40 { inc + getpriority_process(None)? } else { inc - } - // TODO: With Rust 1.50, use `.clamp` instead of `.min` and `.max`. - //.clamp(-20, 19); - .min(19) - .max(-20); + }) + .clamp(-20, 19); setpriority_process(None, priority)?; Ok(priority) } @@ -305,7 +217,7 @@ pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { - ret_c_int(syscall_readonly!( __NR_getpriority, c_uint(PRIO_PGRP), - c_uint(Pid::as_raw(pgid)) + c_int(Pid::as_raw(pgid)) ))?) } } @@ -317,7 +229,7 @@ pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { - ret_c_int(syscall_readonly!( __NR_getpriority, c_uint(PRIO_PROCESS), - c_uint(Pid::as_raw(pid)) + c_int(Pid::as_raw(pid)) ))?) } } @@ -340,7 +252,7 @@ pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<( ret(syscall_readonly!( __NR_setpriority, c_uint(PRIO_PGRP), - c_uint(Pid::as_raw(pgid)), + c_int(Pid::as_raw(pgid)), c_int(priority) )) } @@ -352,7 +264,7 @@ pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result ret(syscall_readonly!( __NR_setpriority, c_uint(PRIO_PROCESS), - c_uint(Pid::as_raw(pid)), + c_int(Pid::as_raw(pid)), c_int(priority) )) } @@ -440,7 +352,7 @@ pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Res unsafe { match ret(syscall!( __NR_prlimit64, - c_uint(Pid::as_raw(pid)), + c_int(Pid::as_raw(pid)), limit, by_ref(&lim), &mut result @@ -531,19 +443,14 @@ pub(crate) fn _waitpid( ) -> io::Result<Option<(Pid, WaitStatus)>> { unsafe { let mut status = MaybeUninit::<u32>::uninit(); - let pid = ret_c_uint(syscall!( + let pid = ret_c_int(syscall!( __NR_wait4, c_int(pid as _), &mut status, c_int(waitopts.bits() as _), zero() ))?; - Ok(RawNonZeroPid::new(pid).map(|non_zero| { - ( - Pid::from_raw_nonzero(non_zero), - WaitStatus::new(status.assume_init()), - ) - })) + Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status.assume_init())))) } } @@ -585,7 +492,7 @@ fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result<Option<WaitidStat ret(syscall!( __NR_waitid, c_uint(c::P_PID), - c_uint(Pid::as_raw(Some(pid))), + c_int(Pid::as_raw(Some(pid))), by_mut(&mut status), c_int(options.bits() as _), zero() @@ -631,31 +538,19 @@ unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidS } } -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn exit_group(code: c::c_int) -> ! { - unsafe { syscall_noreturn!(__NR_exit_group, c_int(code)) } -} - #[inline] pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> { unsafe { - let pid = ret_usize(syscall_readonly!(__NR_getsid, c_uint(Pid::as_raw(pid))))?; - debug_assert!(pid > 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( - pid as u32, - ))) + let pid = ret_c_int(syscall_readonly!(__NR_getsid, c_int(Pid::as_raw(pid))))?; + Ok(Pid::from_raw_unchecked(pid)) } } #[inline] pub(crate) fn setsid() -> io::Result<Pid> { unsafe { - let pid = ret_usize(syscall_readonly!(__NR_setsid))?; - debug_assert!(pid > 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( - pid as u32, - ))) + let pid = ret_c_int(syscall_readonly!(__NR_setsid))?; + Ok(Pid::from_raw_unchecked(pid)) } } @@ -696,28 +591,27 @@ pub(crate) fn test_kill_current_process_group() -> io::Result<()> { } #[inline] -pub(crate) unsafe fn prctl( - option: c::c_int, - arg2: *mut c::c_void, - arg3: *mut c::c_void, - arg4: *mut c::c_void, - arg5: *mut c::c_void, -) -> io::Result<c::c_int> { - ret_c_int(syscall!(__NR_prctl, c_int(option), arg2, arg3, arg4, arg5)) -} - -#[inline] -pub(crate) fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { +pub(crate) fn pidfd_getfd( + pidfd: BorrowedFd<'_>, + targetfd: RawFd, + flags: PidfdGetfdFlags, +) -> io::Result<OwnedFd> { unsafe { ret_owned_fd(syscall_readonly!( - __NR_pidfd_open, - pid, + __NR_pidfd_getfd, + pidfd, + raw_fd(targetfd), c_int(flags.bits() as _) )) } } #[inline] +pub(crate) fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { + unsafe { ret_owned_fd(syscall_readonly!(__NR_pidfd_open, pid, flags)) } +} + +#[inline] pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> { let len = buf.len().try_into().map_err(|_| io::Errno::NOMEM)?; @@ -731,16 +625,13 @@ pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> { } #[inline] -pub(crate) fn sysinfo() -> Sysinfo { - let mut info = MaybeUninit::<Sysinfo>::uninit(); +pub(crate) fn ioctl_tiocsctty(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { - ret_infallible(syscall!(__NR_sysinfo, &mut info)); - info.assume_init() + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(TIOCSCTTY), + by_ref(&0_u32) + )) } } - -#[inline] -pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { - let (ptr, len) = slice(name); - unsafe { ret(syscall_readonly!(__NR_sethostname, ptr, len)) } -} diff --git a/vendor/rustix/src/backend/linux_raw/process/types.rs b/vendor/rustix/src/backend/linux_raw/process/types.rs index efdaddbae..f31749b83 100644 --- a/vendor/rustix/src/backend/linux_raw/process/types.rs +++ b/vendor/rustix/src/backend/linux_raw/process/types.rs @@ -1,9 +1,6 @@ -use super::super::c; +use crate::backend::c; use linux_raw_sys::general::membarrier_cmd; -/// `sysinfo` -pub type Sysinfo = linux_raw_sys::general::sysinfo; - /// A command for use with [`membarrier`] and [`membarrier_cpu`]. /// /// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. @@ -81,152 +78,18 @@ pub enum Resource { Rttime = linux_raw_sys::general::RLIMIT_RTTIME, } -/// A signal number for use with [`kill_process`], [`kill_process_group`], -/// and [`kill_current_process_group`]. -/// -/// [`kill_process`]: crate::process::kill_process -/// [`kill_process_group`]: crate::process::kill_process_group -/// [`kill_current_process_group`]: crate::process::kill_current_process_group -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum Signal { - /// `SIGHUP` - Hup = linux_raw_sys::general::SIGHUP, - /// `SIGINT` - Int = linux_raw_sys::general::SIGINT, - /// `SIGQUIT` - Quit = linux_raw_sys::general::SIGQUIT, - /// `SIGILL` - Ill = linux_raw_sys::general::SIGILL, - /// `SIGTRAP` - Trap = linux_raw_sys::general::SIGTRAP, - /// `SIGABRT`, aka `SIGIOT` - #[doc(alias = "Iot")] - #[doc(alias = "Abrt")] - Abort = linux_raw_sys::general::SIGABRT, - /// `SIGBUS` - Bus = linux_raw_sys::general::SIGBUS, - /// `SIGFPE` - Fpe = linux_raw_sys::general::SIGFPE, - /// `SIGKILL` - Kill = linux_raw_sys::general::SIGKILL, - /// `SIGUSR1` - Usr1 = linux_raw_sys::general::SIGUSR1, - /// `SIGSEGV` - Segv = linux_raw_sys::general::SIGSEGV, - /// `SIGUSR2` - Usr2 = linux_raw_sys::general::SIGUSR2, - /// `SIGPIPE` - Pipe = linux_raw_sys::general::SIGPIPE, - /// `SIGALRM` - #[doc(alias = "Alrm")] - Alarm = linux_raw_sys::general::SIGALRM, - /// `SIGTERM` - Term = linux_raw_sys::general::SIGTERM, - /// `SIGSTKFLT` - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] - Stkflt = linux_raw_sys::general::SIGSTKFLT, - /// `SIGCHLD` - #[doc(alias = "Chld")] - Child = linux_raw_sys::general::SIGCHLD, - /// `SIGCONT` - Cont = linux_raw_sys::general::SIGCONT, - /// `SIGSTOP` - Stop = linux_raw_sys::general::SIGSTOP, - /// `SIGTSTP` - Tstp = linux_raw_sys::general::SIGTSTP, - /// `SIGTTIN` - Ttin = linux_raw_sys::general::SIGTTIN, - /// `SIGTTOU` - Ttou = linux_raw_sys::general::SIGTTOU, - /// `SIGURG` - Urg = linux_raw_sys::general::SIGURG, - /// `SIGXCPU` - Xcpu = linux_raw_sys::general::SIGXCPU, - /// `SIGXFSZ` - Xfsz = linux_raw_sys::general::SIGXFSZ, - /// `SIGVTALRM` - #[doc(alias = "Vtalrm")] - Vtalarm = linux_raw_sys::general::SIGVTALRM, - /// `SIGPROF` - Prof = linux_raw_sys::general::SIGPROF, - /// `SIGWINCH` - Winch = linux_raw_sys::general::SIGWINCH, - /// `SIGIO`, aka `SIGPOLL` - #[doc(alias = "Poll")] - Io = linux_raw_sys::general::SIGIO, - /// `SIGPWR` - #[doc(alias = "Pwr")] - Power = linux_raw_sys::general::SIGPWR, - /// `SIGSYS`, aka `SIGUNUSED` - #[doc(alias = "Unused")] - Sys = linux_raw_sys::general::SIGSYS, - /// `SIGRTMIN` - Rtmin = linux_raw_sys::general::SIGRTMIN, -} - -impl Signal { - /// Convert a raw signal number into a `Signal`, if possible. - pub fn from_raw(sig: i32) -> Option<Self> { - match sig as _ { - linux_raw_sys::general::SIGHUP => Some(Self::Hup), - linux_raw_sys::general::SIGINT => Some(Self::Int), - linux_raw_sys::general::SIGQUIT => Some(Self::Quit), - linux_raw_sys::general::SIGILL => Some(Self::Ill), - linux_raw_sys::general::SIGTRAP => Some(Self::Trap), - linux_raw_sys::general::SIGABRT => Some(Self::Abort), - linux_raw_sys::general::SIGBUS => Some(Self::Bus), - linux_raw_sys::general::SIGFPE => Some(Self::Fpe), - linux_raw_sys::general::SIGKILL => Some(Self::Kill), - linux_raw_sys::general::SIGUSR1 => Some(Self::Usr1), - linux_raw_sys::general::SIGSEGV => Some(Self::Segv), - linux_raw_sys::general::SIGUSR2 => Some(Self::Usr2), - linux_raw_sys::general::SIGPIPE => Some(Self::Pipe), - linux_raw_sys::general::SIGALRM => Some(Self::Alarm), - linux_raw_sys::general::SIGTERM => Some(Self::Term), - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] - linux_raw_sys::general::SIGSTKFLT => Some(Self::Stkflt), - linux_raw_sys::general::SIGCHLD => Some(Self::Child), - linux_raw_sys::general::SIGCONT => Some(Self::Cont), - linux_raw_sys::general::SIGSTOP => Some(Self::Stop), - linux_raw_sys::general::SIGTSTP => Some(Self::Tstp), - linux_raw_sys::general::SIGTTIN => Some(Self::Ttin), - linux_raw_sys::general::SIGTTOU => Some(Self::Ttou), - linux_raw_sys::general::SIGURG => Some(Self::Urg), - linux_raw_sys::general::SIGXCPU => Some(Self::Xcpu), - linux_raw_sys::general::SIGXFSZ => Some(Self::Xfsz), - linux_raw_sys::general::SIGVTALRM => Some(Self::Vtalarm), - linux_raw_sys::general::SIGPROF => Some(Self::Prof), - linux_raw_sys::general::SIGWINCH => Some(Self::Winch), - linux_raw_sys::general::SIGIO => Some(Self::Io), - linux_raw_sys::general::SIGPWR => Some(Self::Power), - linux_raw_sys::general::SIGSYS => Some(Self::Sys), - linux_raw_sys::general::SIGRTMIN => Some(Self::Rtmin), - _ => None, - } - } -} - /// `EXIT_SUCCESS` pub const EXIT_SUCCESS: c::c_int = 0; /// `EXIT_FAILURE` pub const EXIT_FAILURE: c::c_int = 1; /// The status value of a child terminated with a [`Signal::Abort`] signal. +/// +/// [`Signal::Abort`]: crate::process::Signal::Abort pub const EXIT_SIGNALED_SIGABRT: c::c_int = 128 + linux_raw_sys::general::SIGABRT as i32; -/// A process identifier as a raw integer. -pub type RawPid = u32; -/// A non-zero process identifier as a raw non-zero integer. -pub type RawNonZeroPid = core::num::NonZeroU32; -/// A group identifier as a raw integer. -pub type RawGid = u32; -/// A user identifier as a raw integer. -pub type RawUid = u32; /// A CPU identifier as a raw integer. pub type RawCpuid = u32; -pub(crate) type RawUname = linux_raw_sys::general::new_utsname; - #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub(crate) struct RawCpuSet { diff --git a/vendor/rustix/src/backend/linux_raw/pty/mod.rs b/vendor/rustix/src/backend/linux_raw/pty/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pty/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/pty/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pty/syscalls.rs new file mode 100644 index 000000000..c2d1b07c1 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/pty/syscalls.rs @@ -0,0 +1,59 @@ +//! linux_raw syscalls supporting `rustix::pty`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::{by_ref, c_uint, ret, ret_owned_fd}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::ffi::CString; +use crate::io; +use crate::path::DecInt; +use crate::pty::OpenptFlags; +#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] +use alloc::vec::Vec; +use core::mem::MaybeUninit; +use linux_raw_sys::ioctl::{TIOCGPTN, TIOCGPTPEER, TIOCSPTLCK}; + +#[cfg(any(apple, freebsdlike, linux_like, target_os = "fuchsia"))] +#[inline] +pub(crate) fn ptsname(fd: BorrowedFd, mut buffer: Vec<u8>) -> io::Result<CString> { + unsafe { + let mut n = MaybeUninit::<c::c_int>::uninit(); + ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGPTN), &mut n))?; + + buffer.clear(); + buffer.extend_from_slice(b"/dev/pts/"); + buffer.extend_from_slice(DecInt::new(n.assume_init()).as_bytes()); + buffer.push(b'\0'); + Ok(CString::from_vec_with_nul_unchecked(buffer)) + } +} + +#[inline] +pub(crate) fn unlockpt(fd: BorrowedFd) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(TIOCSPTLCK), + by_ref(&0) + )) + } +} + +#[cfg(target_os = "linux")] +#[inline] +pub(crate) fn ioctl_tiocgptpeer(fd: BorrowedFd, flags: OpenptFlags) -> io::Result<OwnedFd> { + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(TIOCGPTPEER), + flags + )) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs b/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs index 5533f75e0..95a6efcff 100644 --- a/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs @@ -6,7 +6,7 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::conv::{ret_usize, slice_mut}; +use crate::backend::conv::{ret_usize, slice_mut}; use crate::io; use crate::rand::GetRandomFlags; diff --git a/vendor/rustix/src/backend/linux_raw/rand/types.rs b/vendor/rustix/src/backend/linux_raw/rand/types.rs index 75f17443e..21e950015 100644 --- a/vendor/rustix/src/backend/linux_raw/rand/types.rs +++ b/vendor/rustix/src/backend/linux_raw/rand/types.rs @@ -4,6 +4,8 @@ bitflags! { /// `GRND_*` flags for use with [`getrandom`]. /// /// [`getrandom`]: crate::rand::getrandom + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct GetRandomFlags: u32 { /// `GRND_RANDOM` const RANDOM = linux_raw_sys::general::GRND_RANDOM; diff --git a/vendor/rustix/src/backend/linux_raw/reg.rs b/vendor/rustix/src/backend/linux_raw/reg.rs index afe99c5f4..206031dde 100644 --- a/vendor/rustix/src/backend/linux_raw/reg.rs +++ b/vendor/rustix/src/backend/linux_raw/reg.rs @@ -16,6 +16,7 @@ use super::c; use super::fd::RawFd; use core::marker::PhantomData; +use core::ops::Range; pub(super) trait ToAsm: private::Sealed { /// Convert `self` to a `usize` ready to be passed to a syscall @@ -188,7 +189,7 @@ impl<Num: RetNumber> RetReg<Num> { } #[inline] - pub(super) fn is_in_range(&self, range: core::ops::Range<isize>) -> bool { + pub(super) fn is_in_range(&self, range: Range<isize>) -> bool { range.contains(&(self.raw as isize)) } } diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs index 74363fc32..b9814e731 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs @@ -6,12 +6,11 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; +use crate::backend::c; #[cfg(target_arch = "x86")] -use super::super::conv::by_mut; -use super::super::conv::{ - by_ref, c_int, c_uint, ret, ret_c_int, ret_c_uint, ret_error, ret_usize_infallible, size_of, - zero, +use crate::backend::conv::by_mut; +use crate::backend::conv::{ + by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, size_of, zero, }; #[cfg(feature = "fs")] use crate::fd::BorrowedFd; @@ -19,23 +18,24 @@ use crate::ffi::CStr; #[cfg(feature = "fs")] use crate::fs::AtFlags; use crate::io; -use crate::process::{Pid, RawNonZeroPid, Signal}; -use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack, Timespec}; +use crate::pid::Pid; +use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack}; +use crate::signal::Signal; +use crate::timespec::Timespec; use crate::utils::optional_as_ptr; -#[cfg(target_pointer_width = "32")] -use core::convert::TryInto; use core::mem::MaybeUninit; #[cfg(target_pointer_width = "32")] use linux_raw_sys::general::__kernel_old_timespec; -use linux_raw_sys::general::{__kernel_pid_t, kernel_sigset_t, PR_SET_NAME, SIGCHLD}; +use linux_raw_sys::general::kernel_sigset_t; +use linux_raw_sys::prctl::PR_SET_NAME; #[cfg(target_arch = "x86_64")] -use {super::super::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; +use {crate::backend::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; #[inline] pub(crate) unsafe fn fork() -> io::Result<Option<Pid>> { - let pid = ret_c_uint(syscall_readonly!( + let pid = ret_c_int(syscall_readonly!( __NR_clone, - c_uint(SIGCHLD), + c_int(c::SIGCHLD), zero(), zero(), zero(), @@ -71,9 +71,9 @@ pub(crate) unsafe fn execve( } pub(crate) mod tls { - #[cfg(target_arch = "x86")] - use super::super::tls::UserDesc; use super::*; + #[cfg(target_arch = "x86")] + use crate::backend::runtime::tls::UserDesc; #[cfg(target_arch = "x86")] #[inline] @@ -99,10 +99,8 @@ pub(crate) mod tls { #[inline] pub(crate) unsafe fn set_tid_address(data: *mut c::c_void) -> Pid { - let tid: i32 = - ret_usize_infallible(syscall_readonly!(__NR_set_tid_address, data)) as __kernel_pid_t; - debug_assert_ne!(tid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid as u32)) + let tid: i32 = ret_c_int_infallible(syscall_readonly!(__NR_set_tid_address, data)); + Pid::from_raw_unchecked(tid) } #[inline] @@ -144,12 +142,13 @@ pub(crate) unsafe fn tkill(tid: Pid, sig: Signal) -> io::Result<()> { } #[inline] -pub(crate) unsafe fn sigprocmask(how: How, set: &Sigset) -> io::Result<Sigset> { +pub(crate) unsafe fn sigprocmask(how: How, new: Option<&Sigset>) -> io::Result<Sigset> { let mut old = MaybeUninit::<Sigset>::uninit(); + let new = optional_as_ptr(new); ret(syscall!( __NR_rt_sigprocmask, how, - by_ref(set), + new, &mut old, size_of::<kernel_sigset_t, _>() ))?; @@ -192,6 +191,9 @@ pub(crate) fn sigtimedwait(set: &Sigset, timeout: Option<Timespec>) -> io::Resul let mut info = MaybeUninit::<Siginfo>::uninit(); let timeout_ptr = optional_as_ptr(timeout.as_ref()); + // `rt_sigtimedwait_time64` was introduced in Linux 5.1. The old + // `rt_sigtimedwait` syscall is not y2038-compatible on 32-bit + // architectures. #[cfg(target_pointer_width = "32")] unsafe { match ret_c_int(syscall!( @@ -247,3 +249,8 @@ unsafe fn sigtimedwait_old( Ok(()) } + +#[inline] +pub(crate) fn exit_group(code: c::c_int) -> ! { + unsafe { syscall_noreturn!(__NR_exit_group, c_int(code)) } +} diff --git a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs index 8cc156a71..763971591 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/tls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs @@ -6,9 +6,9 @@ //! kernel-provided AUXV values. #![allow(unsafe_code)] -use super::super::c; -use super::super::elf::*; -use super::super::param::auxv::exe_phdrs_slice; +use crate::backend::c; +use crate::backend::elf::*; +use crate::backend::param::auxv::exe_phdrs_slice; use core::ptr::null; /// For use with [`set_thread_area`]. @@ -29,7 +29,7 @@ pub(crate) fn startup_tls_info() -> StartupTlsInfo { unsafe { for phdr in phdrs { match phdr.p_type { - PT_PHDR => base = phdrs.as_ptr().cast::<u8>().offset(-(phdr.p_vaddr as isize)), + PT_PHDR => base = phdrs.as_ptr().cast::<u8>().sub(phdr.p_vaddr), PT_TLS => tls_phdr = phdr, PT_GNU_STACK => stack_size = phdr.p_memsz, _ => {} diff --git a/vendor/rustix/src/backend/linux_raw/system/mod.rs b/vendor/rustix/src/backend/linux_raw/system/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/system/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/system/syscalls.rs b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs new file mode 100644 index 000000000..514751d6f --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/system/syscalls.rs @@ -0,0 +1,37 @@ +//! linux_raw syscalls supporting `rustix::system`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use super::types::RawUname; +use crate::backend::conv::{ret, ret_infallible, slice}; +use crate::io; +use crate::system::Sysinfo; +use core::mem::MaybeUninit; + +#[inline] +pub(crate) fn uname() -> RawUname { + let mut uname = MaybeUninit::<RawUname>::uninit(); + unsafe { + ret_infallible(syscall!(__NR_uname, &mut uname)); + uname.assume_init() + } +} + +#[inline] +pub(crate) fn sysinfo() -> Sysinfo { + let mut info = MaybeUninit::<Sysinfo>::uninit(); + unsafe { + ret_infallible(syscall!(__NR_sysinfo, &mut info)); + info.assume_init() + } +} + +#[inline] +pub(crate) fn sethostname(name: &[u8]) -> io::Result<()> { + let (ptr, len) = slice(name); + unsafe { ret(syscall_readonly!(__NR_sethostname, ptr, len)) } +} diff --git a/vendor/rustix/src/backend/linux_raw/system/types.rs b/vendor/rustix/src/backend/linux_raw/system/types.rs new file mode 100644 index 000000000..47292735c --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/system/types.rs @@ -0,0 +1,4 @@ +/// `sysinfo` +pub type Sysinfo = linux_raw_sys::system::sysinfo; + +pub(crate) type RawUname = linux_raw_sys::system::new_utsname; diff --git a/vendor/rustix/src/backend/linux_raw/termios/mod.rs b/vendor/rustix/src/backend/linux_raw/termios/mod.rs index 1e0181a99..ef944f04d 100644 --- a/vendor/rustix/src/backend/linux_raw/termios/mod.rs +++ b/vendor/rustix/src/backend/linux_raw/termios/mod.rs @@ -1,2 +1 @@ pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs index 3c8cbb0c9..5e21397bc 100644 --- a/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs @@ -6,21 +6,24 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::conv::{by_ref, c_uint, ret}; +use crate::backend::c; +use crate::backend::conv::{by_ref, c_uint, ret}; use crate::fd::BorrowedFd; use crate::io; -use crate::process::{Pid, RawNonZeroPid}; +use crate::pid::Pid; +#[cfg(feature = "procfs")] +use crate::procfs; use crate::termios::{ - Action, OptionalActions, QueueSelector, Termios, Winsize, BRKINT, CBAUD, CS8, CSIZE, ECHO, - ECHONL, ICANON, ICRNL, IEXTEN, IGNBRK, IGNCR, INLCR, ISIG, ISTRIP, IXON, OPOST, PARENB, PARMRK, - VMIN, VTIME, + Action, ControlModes, InputModes, LocalModes, OptionalActions, OutputModes, QueueSelector, + SpecialCodeIndex, Termios, Winsize, }; #[cfg(feature = "procfs")] use crate::{ffi::CStr, fs::FileType, path::DecInt}; use core::mem::MaybeUninit; -use linux_raw_sys::general::__kernel_pid_t; +use linux_raw_sys::general::IBSHIFT; use linux_raw_sys::ioctl::{ - TCFLSH, TCGETS, TCSBRK, TCSETS, TCXONC, TIOCGPGRP, TIOCGSID, TIOCGWINSZ, TIOCSPGRP, TIOCSWINSZ, + TCFLSH, TCSBRK, TCXONC, TIOCEXCL, TIOCGPGRP, TIOCGSID, TIOCGWINSZ, TIOCNXCL, TIOCSPGRP, + TIOCSWINSZ, }; #[inline] @@ -36,31 +39,7 @@ pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result<Winsize> { pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result<Termios> { unsafe { let mut result = MaybeUninit::<Termios>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(TCGETS), &mut result))?; - Ok(result.assume_init()) - } -} - -#[inline] -#[cfg(any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "x32", - target_arch = "riscv64", - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips64", -))] -pub(crate) fn tcgetattr2(fd: BorrowedFd<'_>) -> io::Result<crate::termios::Termios2> { - unsafe { - let mut result = MaybeUninit::<crate::termios::Termios2>::uninit(); - ret(syscall!( - __NR_ioctl, - fd, - c_uint(linux_raw_sys::ioctl::TCGETS2), - &mut result - ))?; + ret(syscall!(__NR_ioctl, fd, c_uint(c::TCGETS2), &mut result))?; Ok(result.assume_init()) } } @@ -68,13 +47,10 @@ pub(crate) fn tcgetattr2(fd: BorrowedFd<'_>) -> io::Result<crate::termios::Termi #[inline] pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result<Pid> { unsafe { - let mut result = MaybeUninit::<__kernel_pid_t>::uninit(); + let mut result = MaybeUninit::<c::pid_t>::uninit(); ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGPGRP), &mut result))?; let pid = result.assume_init(); - debug_assert!(pid > 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( - pid as u32, - ))) + Ok(Pid::from_raw_unchecked(pid)) } } @@ -86,42 +62,17 @@ pub(crate) fn tcsetattr( ) -> io::Result<()> { // Translate from `optional_actions` into an ioctl request code. On MIPS, // `optional_actions` already has `TCGETS` added to it. - let request = if cfg!(any(target_arch = "mips", target_arch = "mips64")) { - optional_actions as u32 - } else { - TCSETS + optional_actions as u32 - }; - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(request as u32), - by_ref(termios) - )) - } -} - -#[inline] -#[cfg(any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "x32", - target_arch = "riscv64", - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips64", -))] -pub(crate) fn tcsetattr2( - fd: BorrowedFd, - optional_actions: OptionalActions, - termios: &crate::termios::Termios2, -) -> io::Result<()> { + let request = linux_raw_sys::ioctl::TCSETS2 + + if cfg!(any(target_arch = "mips", target_arch = "mips64")) { + optional_actions as u32 - linux_raw_sys::ioctl::TCSETS + } else { + optional_actions as u32 + }; unsafe { ret(syscall_readonly!( __NR_ioctl, fd, - c_uint(linux_raw_sys::ioctl::TCSETS2 + optional_actions as u32), + c_uint(request), by_ref(termios) )) } @@ -164,13 +115,10 @@ pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { #[inline] pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result<Pid> { unsafe { - let mut result = MaybeUninit::<__kernel_pid_t>::uninit(); + let mut result = MaybeUninit::<c::pid_t>::uninit(); ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGSID), &mut result))?; let pid = result.assume_init(); - debug_assert!(pid > 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( - pid as u32, - ))) + Ok(Pid::from_raw_unchecked(pid)) } } @@ -192,66 +140,90 @@ pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { } #[inline] -#[must_use] -#[allow(clippy::missing_const_for_fn)] -pub(crate) fn cfgetospeed(termios: &Termios) -> u32 { - termios.c_cflag & CBAUD +pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TIOCEXCL))) } } #[inline] -#[must_use] -#[allow(clippy::missing_const_for_fn)] -pub(crate) fn cfgetispeed(termios: &Termios) -> u32 { - termios.c_cflag & CBAUD +pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TIOCNXCL))) } } +/// A wrapper around a conceptual `cfsetspeed` which handles an arbitrary +/// integer speed value. #[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - // From the Linux [`cfmakeraw` manual page]: - // - // [`cfmakeraw` manual page]: https://man7.org/linux/man-pages/man3/cfmakeraw.3.html - termios.c_iflag &= !(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - termios.c_oflag &= !OPOST; - termios.c_lflag &= !(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - termios.c_cflag &= !(CSIZE | PARENB); - termios.c_cflag |= CS8; +pub(crate) fn set_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { + let encoded_speed = crate::termios::speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); - // Musl and glibc also do these: - termios.c_cc[VMIN] = 1; - termios.c_cc[VTIME] = 0; + debug_assert_eq!(encoded_speed & !c::CBAUD, 0); + + termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD | c::CIBAUD); + termios.control_modes |= + ControlModes::from_bits_retain(encoded_speed | (encoded_speed << IBSHIFT)); + + termios.input_speed = arbitrary_speed; + termios.output_speed = arbitrary_speed; + + Ok(()) } +/// A wrapper around a conceptual `cfsetospeed` which handles an arbitrary +/// integer speed value. #[inline] -pub(crate) fn cfsetospeed(termios: &mut Termios, speed: u32) -> io::Result<()> { - if (speed & !CBAUD) != 0 { - return Err(io::Errno::INVAL); - } - termios.c_cflag &= !CBAUD; - termios.c_cflag |= speed; +pub(crate) fn set_output_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { + let encoded_speed = crate::termios::speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); + + debug_assert_eq!(encoded_speed & !c::CBAUD, 0); + + termios.control_modes -= ControlModes::from_bits_retain(c::CBAUD); + termios.control_modes |= ControlModes::from_bits_retain(encoded_speed); + + termios.output_speed = arbitrary_speed; + Ok(()) } +/// A wrapper around a conceptual `cfsetispeed` which handles an arbitrary +/// integer speed value. #[inline] -pub(crate) fn cfsetispeed(termios: &mut Termios, speed: u32) -> io::Result<()> { - if speed == 0 { - return Ok(()); - } - if (speed & !CBAUD) != 0 { - return Err(io::Errno::INVAL); - } - termios.c_cflag &= !CBAUD; - termios.c_cflag |= speed; +pub(crate) fn set_input_speed(termios: &mut Termios, arbitrary_speed: u32) -> io::Result<()> { + let encoded_speed = crate::termios::speed::encode(arbitrary_speed).unwrap_or(c::BOTHER); + + debug_assert_eq!(encoded_speed & !c::CBAUD, 0); + + termios.control_modes -= ControlModes::from_bits_retain(c::CIBAUD); + termios.control_modes |= ControlModes::from_bits_retain(encoded_speed << IBSHIFT); + + termios.input_speed = arbitrary_speed; + Ok(()) } #[inline] -pub(crate) fn cfsetspeed(termios: &mut Termios, speed: u32) -> io::Result<()> { - if (speed & !CBAUD) != 0 { - return Err(io::Errno::INVAL); - } - termios.c_cflag &= !CBAUD; - termios.c_cflag |= speed; - Ok(()) +pub(crate) fn cfmakeraw(termios: &mut Termios) { + // From the Linux [`cfmakeraw` manual page]: + // + // [`cfmakeraw` manual page]: https://man7.org/linux/man-pages/man3/cfmakeraw.3.html + termios.input_modes -= InputModes::IGNBRK + | InputModes::BRKINT + | InputModes::PARMRK + | InputModes::ISTRIP + | InputModes::INLCR + | InputModes::IGNCR + | InputModes::ICRNL + | InputModes::IXON; + termios.output_modes -= OutputModes::OPOST; + termios.local_modes -= LocalModes::ECHO + | LocalModes::ECHONL + | LocalModes::ICANON + | LocalModes::ISIG + | LocalModes::IEXTEN; + termios.control_modes -= ControlModes::CSIZE | ControlModes::PARENB; + termios.control_modes |= ControlModes::CS8; + + // Musl and glibc also do these: + termios.special_codes[SpecialCodeIndex::VMIN] = 1; + termios.special_codes[SpecialCodeIndex::VTIME] = 0; } #[inline] @@ -264,8 +236,9 @@ pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { } #[cfg(feature = "procfs")] -pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> { - let fd_stat = super::super::fs::syscalls::fstat(fd)?; +#[allow(unsafe_code)] +pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize> { + let fd_stat = crate::backend::fs::syscalls::fstat(fd)?; // Quick check: if `fd` isn't a character device, it's not a tty. if FileType::from_raw_mode(fd_stat.st_mode) != FileType::CharacterDevice { @@ -276,11 +249,14 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> { tcgetwinsize(fd)?; // Get a fd to '/proc/self/fd'. - let proc_self_fd = io::proc_self_fd()?; + let proc_self_fd = procfs::proc_self_fd()?; // Gather the ttyname by reading the 'fd' file inside 'proc_self_fd'. - let r = - super::super::fs::syscalls::readlinkat(proc_self_fd, DecInt::from_fd(fd).as_c_str(), buf)?; + let r = crate::backend::fs::syscalls::readlinkat( + proc_self_fd, + DecInt::from_fd(fd).as_c_str(), + buf, + )?; // If the number of bytes is equal to the buffer length, truncation may // have occurred. This check also ensures that we have enough space for @@ -288,14 +264,20 @@ pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result<usize> { if r == buf.len() { return Err(io::Errno::RANGE); } - buf[r] = b'\0'; + + // `readlinkat` returns the number of bytes placed in the buffer. + // NUL-terminate the string at that offset. + buf[r].write(b'\0'); // Check that the path we read refers to the same file as `fd`. - let path = CStr::from_bytes_with_nul(&buf[..=r]).unwrap(); + { + // SAFETY: We just wrote the NUL byte above + let path = unsafe { CStr::from_ptr(buf.as_ptr().cast()) }; - let path_stat = super::super::fs::syscalls::stat(path)?; - if path_stat.st_dev != fd_stat.st_dev || path_stat.st_ino != fd_stat.st_ino { - return Err(io::Errno::NODEV); + let path_stat = crate::backend::fs::syscalls::stat(path)?; + if path_stat.st_dev != fd_stat.st_dev || path_stat.st_ino != fd_stat.st_ino { + return Err(io::Errno::NODEV); + } } Ok(r) diff --git a/vendor/rustix/src/backend/linux_raw/termios/types.rs b/vendor/rustix/src/backend/linux_raw/termios/types.rs deleted file mode 100644 index 3fe45af98..000000000 --- a/vendor/rustix/src/backend/linux_raw/termios/types.rs +++ /dev/null @@ -1,495 +0,0 @@ -use super::super::c; - -/// `TCSA*` values for use with [`tcsetattr`]. -/// -/// [`tcsetattr`]: crate::termios::tcsetattr -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum OptionalActions { - /// `TCSANOW`—Make the change immediately. - #[doc(alias = "TCSANOW")] - Now = linux_raw_sys::general::TCSANOW, - - /// `TCSADRAIN`—Make the change after all output has been transmitted. - #[doc(alias = "TCSADRAIN")] - Drain = linux_raw_sys::general::TCSADRAIN, - - /// `TCSAFLUSH`—Discard any pending input and then make the change - /// after all output has been transmitted. - #[doc(alias = "TCSAFLUSH")] - Flush = linux_raw_sys::general::TCSAFLUSH, -} - -/// `TC*` values for use with [`tcflush`]. -/// -/// [`tcflush`]: crate::termios::tcflush -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum QueueSelector { - /// `TCIFLUSH`—Flush data received but not read. - #[doc(alias = "TCIFLUSH")] - IFlush = linux_raw_sys::general::TCIFLUSH, - - /// `TCOFLUSH`—Flush data written but not transmitted. - #[doc(alias = "TCOFLUSH")] - OFlush = linux_raw_sys::general::TCOFLUSH, - - /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. - #[doc(alias = "TCIOFLUSH")] - IOFlush = linux_raw_sys::general::TCIOFLUSH, -} - -/// `TC*` values for use with [`tcflow`]. -/// -/// [`tcflow`]: crate::termios::tcflow -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(u32)] -pub enum Action { - /// `TCOOFF`—Suspend output. - #[doc(alias = "TCOOFF")] - OOff = linux_raw_sys::general::TCOOFF, - - /// `TCOON`—Restart suspended output. - #[doc(alias = "TCOON")] - OOn = linux_raw_sys::general::TCOON, - - /// `TCIOFF`—Transmits a STOP byte. - #[doc(alias = "TCIOFF")] - IOff = linux_raw_sys::general::TCIOFF, - - /// `TCION`—Transmits a START byte. - #[doc(alias = "TCION")] - IOn = linux_raw_sys::general::TCION, -} - -/// `struct termios` for use with [`tcgetattr`] and [`tcsetattr`]. -/// -/// [`tcgetattr`]: crate::termios::tcgetattr -/// [`tcsetattr`]: crate::termios::tcsetattr -#[doc(alias = "termios")] -pub type Termios = linux_raw_sys::general::termios; - -/// `struct termios2` for use with [`tcgetattr2`] and [`tcsetattr2`]. -/// -/// [`tcgetattr2`]: crate::termios::tcgetattr2 -/// [`tcsetattr2`]: crate::termios::tcsetattr2 -#[cfg(any( - target_arch = "x86", - target_arch = "x86_64", - target_arch = "x32", - target_arch = "riscv64", - target_arch = "aarch64", - target_arch = "arm", - target_arch = "mips", - target_arch = "mips64", -))] -#[doc(alias = "termios2")] -pub type Termios2 = linux_raw_sys::general::termios2; - -/// `struct winsize` for use with [`tcgetwinsize`]. -/// -/// [`tcgetwinsize`]: crate::termios::tcgetwinsize -#[doc(alias = "winsize")] -pub type Winsize = linux_raw_sys::general::winsize; - -/// `tcflag_t`—A type for the flags fields of [`Termios`]. -#[doc(alias = "tcflag_t")] -pub type Tcflag = linux_raw_sys::general::tcflag_t; - -/// `speed_t`—A return type for [`cfsetspeed`] and similar. -/// -/// [`cfsetspeed`]: crate::termios::cfsetspeed -#[doc(alias = "speed_t")] -pub type Speed = linux_raw_sys::general::speed_t; - -/// `VINTR` -pub const VINTR: usize = linux_raw_sys::general::VINTR as usize; - -/// `VQUIT` -pub const VQUIT: usize = linux_raw_sys::general::VQUIT as usize; - -/// `VERASE` -pub const VERASE: usize = linux_raw_sys::general::VERASE as usize; - -/// `VKILL` -pub const VKILL: usize = linux_raw_sys::general::VKILL as usize; - -/// `VEOF` -pub const VEOF: usize = linux_raw_sys::general::VEOF as usize; - -/// `VTIME` -pub const VTIME: usize = linux_raw_sys::general::VTIME as usize; - -/// `VMIN` -pub const VMIN: usize = linux_raw_sys::general::VMIN as usize; - -/// `VSWTC` -pub const VSWTC: usize = linux_raw_sys::general::VSWTC as usize; - -/// `VSTART` -pub const VSTART: usize = linux_raw_sys::general::VSTART as usize; - -/// `VSTOP` -pub const VSTOP: usize = linux_raw_sys::general::VSTOP as usize; - -/// `VSUSP` -pub const VSUSP: usize = linux_raw_sys::general::VSUSP as usize; - -/// `VEOL` -pub const VEOL: usize = linux_raw_sys::general::VEOL as usize; - -/// `VREPRINT` -pub const VREPRINT: usize = linux_raw_sys::general::VREPRINT as usize; - -/// `VDISCARD` -pub const VDISCARD: usize = linux_raw_sys::general::VDISCARD as usize; - -/// `VWERASE` -pub const VWERASE: usize = linux_raw_sys::general::VWERASE as usize; - -/// `VLNEXT` -pub const VLNEXT: usize = linux_raw_sys::general::VLNEXT as usize; - -/// `VEOL2` -pub const VEOL2: usize = linux_raw_sys::general::VEOL2 as usize; - -/// `IGNBRK` -pub const IGNBRK: c::c_uint = linux_raw_sys::general::IGNBRK; - -/// `BRKINT` -pub const BRKINT: c::c_uint = linux_raw_sys::general::BRKINT; - -/// `IGNPAR` -pub const IGNPAR: c::c_uint = linux_raw_sys::general::IGNPAR; - -/// `PARMRK` -pub const PARMRK: c::c_uint = linux_raw_sys::general::PARMRK; - -/// `INPCK` -pub const INPCK: c::c_uint = linux_raw_sys::general::INPCK; - -/// `ISTRIP` -pub const ISTRIP: c::c_uint = linux_raw_sys::general::ISTRIP; - -/// `INLCR` -pub const INLCR: c::c_uint = linux_raw_sys::general::INLCR; - -/// `IGNCR` -pub const IGNCR: c::c_uint = linux_raw_sys::general::IGNCR; - -/// `ICRNL` -pub const ICRNL: c::c_uint = linux_raw_sys::general::ICRNL; - -/// `IUCLC` -pub const IUCLC: c::c_uint = linux_raw_sys::general::IUCLC; - -/// `IXON` -pub const IXON: c::c_uint = linux_raw_sys::general::IXON; - -/// `IXANY` -pub const IXANY: c::c_uint = linux_raw_sys::general::IXANY; - -/// `IXOFF` -pub const IXOFF: c::c_uint = linux_raw_sys::general::IXOFF; - -/// `IMAXBEL` -pub const IMAXBEL: c::c_uint = linux_raw_sys::general::IMAXBEL; - -/// `IUTF8` -pub const IUTF8: c::c_uint = linux_raw_sys::general::IUTF8; - -/// `OPOST` -pub const OPOST: c::c_uint = linux_raw_sys::general::OPOST; - -/// `OLCUC` -pub const OLCUC: c::c_uint = linux_raw_sys::general::OLCUC; - -/// `ONLCR` -pub const ONLCR: c::c_uint = linux_raw_sys::general::ONLCR; - -/// `OCRNL` -pub const OCRNL: c::c_uint = linux_raw_sys::general::OCRNL; - -/// `ONOCR` -pub const ONOCR: c::c_uint = linux_raw_sys::general::ONOCR; - -/// `ONLRET` -pub const ONLRET: c::c_uint = linux_raw_sys::general::ONLRET; - -/// `OFILL` -pub const OFILL: c::c_uint = linux_raw_sys::general::OFILL; - -/// `OFDEL` -pub const OFDEL: c::c_uint = linux_raw_sys::general::OFDEL; - -/// `NLDLY` -pub const NLDLY: c::c_uint = linux_raw_sys::general::NLDLY; - -/// `NL0` -pub const NL0: c::c_uint = linux_raw_sys::general::NL0; - -/// `NL1` -pub const NL1: c::c_uint = linux_raw_sys::general::NL1; - -/// `CRDLY` -pub const CRDLY: c::c_uint = linux_raw_sys::general::CRDLY; - -/// `CR0` -pub const CR0: c::c_uint = linux_raw_sys::general::CR0; - -/// `CR1` -pub const CR1: c::c_uint = linux_raw_sys::general::CR1; - -/// `CR2` -pub const CR2: c::c_uint = linux_raw_sys::general::CR2; - -/// `CR3` -pub const CR3: c::c_uint = linux_raw_sys::general::CR3; - -/// `TABDLY` -pub const TABDLY: c::c_uint = linux_raw_sys::general::TABDLY; - -/// `TAB0` -pub const TAB0: c::c_uint = linux_raw_sys::general::TAB0; - -/// `TAB1` -pub const TAB1: c::c_uint = linux_raw_sys::general::TAB1; - -/// `TAB2` -pub const TAB2: c::c_uint = linux_raw_sys::general::TAB2; - -/// `TAB3` -pub const TAB3: c::c_uint = linux_raw_sys::general::TAB3; - -/// `BSDLY` -pub const BSDLY: c::c_uint = linux_raw_sys::general::BSDLY; - -/// `BS0` -pub const BS0: c::c_uint = linux_raw_sys::general::BS0; - -/// `BS1` -pub const BS1: c::c_uint = linux_raw_sys::general::BS1; - -/// `FFDLY` -pub const FFDLY: c::c_uint = linux_raw_sys::general::FFDLY; - -/// `FF0` -pub const FF0: c::c_uint = linux_raw_sys::general::FF0; - -/// `FF1` -pub const FF1: c::c_uint = linux_raw_sys::general::FF1; - -/// `VTDLY` -pub const VTDLY: c::c_uint = linux_raw_sys::general::VTDLY; - -/// `VT0` -pub const VT0: c::c_uint = linux_raw_sys::general::VT0; - -/// `VT1` -pub const VT1: c::c_uint = linux_raw_sys::general::VT1; - -/// `B0` -pub const B0: Speed = linux_raw_sys::general::B0; - -/// `B50` -pub const B50: Speed = linux_raw_sys::general::B50; - -/// `B75` -pub const B75: Speed = linux_raw_sys::general::B75; - -/// `B110` -pub const B110: Speed = linux_raw_sys::general::B110; - -/// `B134` -pub const B134: Speed = linux_raw_sys::general::B134; - -/// `B150` -pub const B150: Speed = linux_raw_sys::general::B150; - -/// `B200` -pub const B200: Speed = linux_raw_sys::general::B200; - -/// `B300` -pub const B300: Speed = linux_raw_sys::general::B300; - -/// `B600` -pub const B600: Speed = linux_raw_sys::general::B600; - -/// `B1200` -pub const B1200: Speed = linux_raw_sys::general::B1200; - -/// `B1800` -pub const B1800: Speed = linux_raw_sys::general::B1800; - -/// `B2400` -pub const B2400: Speed = linux_raw_sys::general::B2400; - -/// `B4800` -pub const B4800: Speed = linux_raw_sys::general::B4800; - -/// `B9600` -pub const B9600: Speed = linux_raw_sys::general::B9600; - -/// `B19200` -pub const B19200: Speed = linux_raw_sys::general::B19200; - -/// `B38400` -pub const B38400: Speed = linux_raw_sys::general::B38400; - -/// `B57600` -pub const B57600: Speed = linux_raw_sys::general::B57600; - -/// `B115200` -pub const B115200: Speed = linux_raw_sys::general::B115200; - -/// `B230400` -pub const B230400: Speed = linux_raw_sys::general::B230400; - -/// `B460800` -pub const B460800: Speed = linux_raw_sys::general::B460800; - -/// `B500000` -pub const B500000: Speed = linux_raw_sys::general::B500000; - -/// `B576000` -pub const B576000: Speed = linux_raw_sys::general::B576000; - -/// `B921600` -pub const B921600: Speed = linux_raw_sys::general::B921600; - -/// `B1000000` -pub const B1000000: Speed = linux_raw_sys::general::B1000000; - -/// `B1152000` -pub const B1152000: Speed = linux_raw_sys::general::B1152000; - -/// `B1500000` -pub const B1500000: Speed = linux_raw_sys::general::B1500000; - -/// `B2000000` -pub const B2000000: Speed = linux_raw_sys::general::B2000000; - -/// `B2500000` -#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] -pub const B2500000: Speed = linux_raw_sys::general::B2500000; - -/// `B3000000` -#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] -pub const B3000000: Speed = linux_raw_sys::general::B3000000; - -/// `B3500000` -#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] -pub const B3500000: Speed = linux_raw_sys::general::B3500000; - -/// `B4000000` -#[cfg(not(any(target_arch = "sparc", target_arch = "sparc64")))] -pub const B4000000: Speed = linux_raw_sys::general::B4000000; - -/// `BOTHER` -pub const BOTHER: c::c_uint = linux_raw_sys::general::BOTHER; - -/// `CSIZE` -pub const CSIZE: c::c_uint = linux_raw_sys::general::CSIZE; - -/// `CS5` -pub const CS5: c::c_uint = linux_raw_sys::general::CS5; - -/// `CS6` -pub const CS6: c::c_uint = linux_raw_sys::general::CS6; - -/// `CS7` -pub const CS7: c::c_uint = linux_raw_sys::general::CS7; - -/// `CS8` -pub const CS8: c::c_uint = linux_raw_sys::general::CS8; - -/// `CSTOPB` -pub const CSTOPB: c::c_uint = linux_raw_sys::general::CSTOPB; - -/// `CREAD` -pub const CREAD: c::c_uint = linux_raw_sys::general::CREAD; - -/// `PARENB` -pub const PARENB: c::c_uint = linux_raw_sys::general::PARENB; - -/// `PARODD` -pub const PARODD: c::c_uint = linux_raw_sys::general::PARODD; - -/// `HUPCL` -pub const HUPCL: c::c_uint = linux_raw_sys::general::HUPCL; - -/// `CLOCAL` -pub const CLOCAL: c::c_uint = linux_raw_sys::general::CLOCAL; - -/// `ISIG` -pub const ISIG: c::c_uint = linux_raw_sys::general::ISIG; - -/// `ICANON`—A flag for the `c_lflag` field of [`Termios`] indicating -/// canonical mode. -pub const ICANON: Tcflag = linux_raw_sys::general::ICANON; - -/// `ECHO` -pub const ECHO: c::c_uint = linux_raw_sys::general::ECHO; - -/// `ECHOE` -pub const ECHOE: c::c_uint = linux_raw_sys::general::ECHOE; - -/// `ECHOK` -pub const ECHOK: c::c_uint = linux_raw_sys::general::ECHOK; - -/// `ECHONL` -pub const ECHONL: c::c_uint = linux_raw_sys::general::ECHONL; - -/// `NOFLSH` -pub const NOFLSH: c::c_uint = linux_raw_sys::general::NOFLSH; - -/// `TOSTOP` -pub const TOSTOP: c::c_uint = linux_raw_sys::general::TOSTOP; - -/// `IEXTEN` -pub const IEXTEN: c::c_uint = linux_raw_sys::general::IEXTEN; - -/// `EXTA` -pub const EXTA: c::c_uint = linux_raw_sys::general::EXTA; - -/// `EXTB` -pub const EXTB: c::c_uint = linux_raw_sys::general::EXTB; - -/// `CBAUD` -pub const CBAUD: c::c_uint = linux_raw_sys::general::CBAUD; - -/// `CBAUDEX` -pub const CBAUDEX: c::c_uint = linux_raw_sys::general::CBAUDEX; - -/// `CIBAUD` -pub const CIBAUD: c::c_uint = linux_raw_sys::general::CIBAUD; - -/// `CMSPAR` -pub const CMSPAR: c::c_uint = linux_raw_sys::general::CMSPAR; - -/// `CRTSCTS` -pub const CRTSCTS: c::c_uint = linux_raw_sys::general::CRTSCTS; - -/// `XCASE` -pub const XCASE: c::c_uint = linux_raw_sys::general::XCASE; - -/// `ECHOCTL` -pub const ECHOCTL: c::c_uint = linux_raw_sys::general::ECHOCTL; - -/// `ECHOPRT` -pub const ECHOPRT: c::c_uint = linux_raw_sys::general::ECHOPRT; - -/// `ECHOKE` -pub const ECHOKE: c::c_uint = linux_raw_sys::general::ECHOKE; - -/// `FLUSHO` -pub const FLUSHO: c::c_uint = linux_raw_sys::general::FLUSHO; - -/// `PENDIN` -pub const PENDIN: c::c_uint = linux_raw_sys::general::PENDIN; - -/// `EXTPROC` -pub const EXTPROC: c::c_uint = linux_raw_sys::general::EXTPROC; - -/// `XTABS` -pub const XTABS: c::c_uint = linux_raw_sys::general::XTABS; diff --git a/vendor/rustix/src/backend/linux_raw/thread/futex.rs b/vendor/rustix/src/backend/linux_raw/thread/futex.rs index 9e087f9f1..4cde309a5 100644 --- a/vendor/rustix/src/backend/linux_raw/thread/futex.rs +++ b/vendor/rustix/src/backend/linux_raw/thread/futex.rs @@ -1,7 +1,9 @@ bitflags::bitflags! { - /// Flags for use with [`futex`]. + /// `FUTEX_*` flags for use with [`futex`]. /// /// [`futex`]: crate::thread::futex + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FutexFlags: u32 { /// `FUTEX_PRIVATE_FLAG` const PRIVATE = linux_raw_sys::general::FUTEX_PRIVATE_FLAG; @@ -10,7 +12,7 @@ bitflags::bitflags! { } } -/// Operations for use with [`futex`]. +/// `FUTEX_*` operations for use with [`futex`]. /// /// [`futex`]: crate::thread::futex #[derive(Debug, Copy, Clone, Eq, PartialEq)] diff --git a/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs b/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs index 1895c8c6d..f23b7c2df 100644 --- a/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs @@ -6,20 +6,19 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -use super::super::c; -use super::super::conv::{ - by_ref, c_int, c_uint, ret, ret_c_int, ret_usize, ret_usize_infallible, zero, +use crate::backend::c; +use crate::backend::conv::{ + by_mut, by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_usize, + slice_just_addr, slice_just_addr_mut, zero, }; use crate::fd::BorrowedFd; use crate::io; -use crate::process::{Pid, RawNonZeroPid}; +use crate::pid::Pid; use crate::thread::{ClockId, FutexFlags, FutexOperation, NanosleepRelativeResult, Timespec}; use core::mem::MaybeUninit; -use linux_raw_sys::general::{__kernel_pid_t, __kernel_timespec, TIMER_ABSTIME}; #[cfg(target_pointer_width = "32")] -use { - core::convert::TryInto, core::ptr, linux_raw_sys::general::timespec as __kernel_old_timespec, -}; +use linux_raw_sys::general::timespec as __kernel_old_timespec; +use linux_raw_sys::general::{__kernel_timespec, TIMER_ABSTIME}; #[inline] pub(crate) fn clock_nanosleep_relative( @@ -86,14 +85,10 @@ unsafe fn clock_nanosleep_relative_old( &mut old_rem ))?; let old_rem = old_rem.assume_init(); - // TODO: With Rust 1.55, we can use MaybeUninit::write here. - ptr::write( - rem.as_mut_ptr(), - __kernel_timespec { - tv_sec: old_rem.tv_sec.into(), - tv_nsec: old_rem.tv_nsec.into(), - }, - ); + rem.write(__kernel_timespec { + tv_sec: old_rem.tv_sec.into(), + tv_nsec: old_rem.tv_nsec.into(), + }); Ok(()) } @@ -194,23 +189,18 @@ unsafe fn nanosleep_old( let mut old_rem = MaybeUninit::<__kernel_old_timespec>::uninit(); ret(syscall!(__NR_nanosleep, by_ref(&old_req), &mut old_rem))?; let old_rem = old_rem.assume_init(); - // TODO: With Rust 1.55, we can use MaybeUninit::write here. - ptr::write( - rem.as_mut_ptr(), - __kernel_timespec { - tv_sec: old_rem.tv_sec.into(), - tv_nsec: old_rem.tv_nsec.into(), - }, - ); + rem.write(__kernel_timespec { + tv_sec: old_rem.tv_sec.into(), + tv_nsec: old_rem.tv_nsec.into(), + }); Ok(()) } #[inline] pub(crate) fn gettid() -> Pid { unsafe { - let tid: i32 = ret_usize_infallible(syscall_readonly!(__NR_gettid)) as __kernel_pid_t; - debug_assert_ne!(tid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid as u32)) + let tid = ret_c_int_infallible(syscall_readonly!(__NR_gettid)); + Pid::from_raw_unchecked(tid) } } @@ -283,48 +273,48 @@ unsafe fn futex_old( )) } -#[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result<c::c_int> { unsafe { ret_c_int(syscall_readonly!(__NR_setns, fd, c_int(nstype))) } } -#[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub(crate) fn unshare(flags: crate::thread::UnshareFlags) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_unshare, c_uint(flags.bits()))) } + unsafe { ret(syscall_readonly!(__NR_unshare, flags)) } } -#[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub(crate) fn capget( header: &mut linux_raw_sys::general::__user_cap_header_struct, data: &mut [MaybeUninit<linux_raw_sys::general::__user_cap_data_struct>], ) -> io::Result<()> { - let header: *mut _ = header; - unsafe { ret(syscall!(__NR_capget, header, data)) } + unsafe { + ret(syscall!( + __NR_capget, + by_mut(header), + slice_just_addr_mut(data) + )) + } } -#[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub(crate) fn capset( header: &mut linux_raw_sys::general::__user_cap_header_struct, data: &[linux_raw_sys::general::__user_cap_data_struct], ) -> io::Result<()> { - let header: *mut _ = header; - unsafe { ret(syscall!(__NR_capset, header, data.as_ptr())) } + unsafe { ret(syscall!(__NR_capset, by_mut(header), slice_just_addr(data))) } } #[inline] -pub(crate) fn setuid_thread(uid: crate::process::Uid) -> io::Result<()> { +pub(crate) fn setuid_thread(uid: crate::ugid::Uid) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_setuid, uid)) } } #[inline] pub(crate) fn setresuid_thread( - ruid: crate::process::Uid, - euid: crate::process::Uid, - suid: crate::process::Uid, + ruid: crate::ugid::Uid, + euid: crate::ugid::Uid, + suid: crate::ugid::Uid, ) -> io::Result<()> { #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))] unsafe { @@ -337,15 +327,15 @@ pub(crate) fn setresuid_thread( } #[inline] -pub(crate) fn setgid_thread(gid: crate::process::Gid) -> io::Result<()> { +pub(crate) fn setgid_thread(gid: crate::ugid::Gid) -> io::Result<()> { unsafe { ret(syscall_readonly!(__NR_setgid, gid)) } } #[inline] pub(crate) fn setresgid_thread( - rgid: crate::process::Gid, - egid: crate::process::Gid, - sgid: crate::process::Gid, + rgid: crate::ugid::Gid, + egid: crate::ugid::Gid, + sgid: crate::ugid::Gid, ) -> io::Result<()> { #[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "sparc"))] unsafe { diff --git a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs index c039393ef..634ce2674 100644 --- a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs @@ -6,34 +6,32 @@ #![allow(unsafe_code)] #![allow(clippy::undocumented_unsafe_blocks)] -#[cfg(feature = "time")] -use super::super::conv::{by_ref, ret_owned_fd}; -use super::super::conv::{ret, ret_infallible}; -use super::types::ClockId; -#[cfg(feature = "time")] -use crate::fd::BorrowedFd; -#[cfg(feature = "time")] -use crate::fd::OwnedFd; +use crate::backend::conv::{ret, ret_infallible}; +use crate::clockid::ClockId; use crate::io; -#[cfg(feature = "time")] -use crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; +use crate::timespec::Timespec; use core::mem::MaybeUninit; -use linux_raw_sys::general::__kernel_timespec; -#[cfg(feature = "time")] +#[cfg(all(feature = "time", target_pointer_width = "32"))] +use linux_raw_sys::general::itimerspec as __kernel_old_itimerspec; #[cfg(target_pointer_width = "32")] -use {core::convert::TryInto, linux_raw_sys::general::itimerspec as __kernel_old_itimerspec}; -#[cfg(target_pointer_width = "32")] -use {core::ptr, linux_raw_sys::general::timespec as __kernel_old_timespec}; +use linux_raw_sys::general::timespec as __kernel_old_timespec; +#[cfg(feature = "time")] +use { + crate::backend::conv::{by_ref, ret_owned_fd}, + crate::fd::BorrowedFd, + crate::fd::OwnedFd, + crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, +}; // `clock_gettime` has special optimizations via the vDSO. #[cfg(feature = "time")] -pub(crate) use super::super::vdso_wrappers::{clock_gettime, clock_gettime_dynamic}; +pub(crate) use crate::backend::vdso_wrappers::{clock_gettime, clock_gettime_dynamic}; #[inline] -pub(crate) fn clock_getres(which_clock: ClockId) -> __kernel_timespec { +pub(crate) fn clock_getres(which_clock: ClockId) -> Timespec { #[cfg(target_pointer_width = "32")] unsafe { - let mut result = MaybeUninit::<__kernel_timespec>::uninit(); + let mut result = MaybeUninit::<Timespec>::uninit(); if let Err(err) = ret(syscall!(__NR_clock_getres_time64, which_clock, &mut result)) { // See the comments in `rustix_clock_gettime_via_syscall` about // emulation. @@ -44,30 +42,28 @@ pub(crate) fn clock_getres(which_clock: ClockId) -> __kernel_timespec { } #[cfg(target_pointer_width = "64")] unsafe { - let mut result = MaybeUninit::<__kernel_timespec>::uninit(); + let mut result = MaybeUninit::<Timespec>::uninit(); ret_infallible(syscall!(__NR_clock_getres, which_clock, &mut result)); result.assume_init() } } #[cfg(target_pointer_width = "32")] -unsafe fn clock_getres_old(which_clock: ClockId, result: &mut MaybeUninit<__kernel_timespec>) { +unsafe fn clock_getres_old(which_clock: ClockId, result: &mut MaybeUninit<Timespec>) { let mut old_result = MaybeUninit::<__kernel_old_timespec>::uninit(); ret_infallible(syscall!(__NR_clock_getres, which_clock, &mut old_result)); let old_result = old_result.assume_init(); - // TODO: With Rust 1.55, we can use MaybeUninit::write here. - ptr::write( - result.as_mut_ptr(), - __kernel_timespec { - tv_sec: old_result.tv_sec.into(), - tv_nsec: old_result.tv_nsec.into(), - }, - ); + result.write(Timespec { + tv_sec: old_result.tv_sec.into(), + tv_nsec: old_result.tv_nsec.into(), + }); } #[cfg(feature = "time")] #[inline] -pub(crate) fn clock_settime(which_clock: ClockId, timespec: __kernel_timespec) -> io::Result<()> { +pub(crate) fn clock_settime(which_clock: ClockId, timespec: Timespec) -> io::Result<()> { + // `clock_settime64` was introduced in Linux 5.1. The old `clock_settime` + // syscall is not y2038-compatible on 32-bit architectures. #[cfg(target_pointer_width = "32")] unsafe { match ret(syscall_readonly!( @@ -91,7 +87,7 @@ pub(crate) fn clock_settime(which_clock: ClockId, timespec: __kernel_timespec) - #[cfg(feature = "time")] #[cfg(target_pointer_width = "32")] -unsafe fn clock_settime_old(which_clock: ClockId, timespec: __kernel_timespec) -> io::Result<()> { +unsafe fn clock_settime_old(which_clock: ClockId, timespec: Timespec) -> io::Result<()> { let old_timespec = __kernel_old_timespec { tv_sec: timespec .tv_sec @@ -200,20 +196,16 @@ unsafe fn timerfd_settime_old( &mut old_result ))?; let old_result = old_result.assume_init(); - // TODO: With Rust 1.55, we can use MaybeUninit::write here. - ptr::write( - result.as_mut_ptr(), - Itimerspec { - it_interval: __kernel_timespec { - tv_sec: old_result.it_interval.tv_sec.into(), - tv_nsec: old_result.it_interval.tv_nsec.into(), - }, - it_value: __kernel_timespec { - tv_sec: old_result.it_value.tv_sec.into(), - tv_nsec: old_result.it_value.tv_nsec.into(), - }, + result.write(Itimerspec { + it_interval: Timespec { + tv_sec: old_result.it_interval.tv_sec.into(), + tv_nsec: old_result.it_interval.tv_nsec.into(), }, - ); + it_value: Timespec { + tv_sec: old_result.it_value.tv_sec.into(), + tv_nsec: old_result.it_value.tv_nsec.into(), + }, + }); Ok(()) } @@ -252,19 +244,15 @@ unsafe fn timerfd_gettime_old( let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); ret(syscall!(__NR_timerfd_gettime, fd, &mut old_result))?; let old_result = old_result.assume_init(); - // TODO: With Rust 1.55, we can use MaybeUninit::write here. - ptr::write( - result.as_mut_ptr(), - Itimerspec { - it_interval: __kernel_timespec { - tv_sec: old_result.it_interval.tv_sec.into(), - tv_nsec: old_result.it_interval.tv_nsec.into(), - }, - it_value: __kernel_timespec { - tv_sec: old_result.it_value.tv_sec.into(), - tv_nsec: old_result.it_value.tv_nsec.into(), - }, + result.write(Itimerspec { + it_interval: Timespec { + tv_sec: old_result.it_interval.tv_sec.into(), + tv_nsec: old_result.it_interval.tv_nsec.into(), + }, + it_value: Timespec { + tv_sec: old_result.it_value.tv_sec.into(), + tv_nsec: old_result.it_value.tv_nsec.into(), }, - ); + }); Ok(()) } diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs index fcdd7f6d6..62cb167e6 100644 --- a/vendor/rustix/src/backend/linux_raw/time/types.rs +++ b/vendor/rustix/src/backend/linux_raw/time/types.rs @@ -1,16 +1,6 @@ -use super::super::c; -use crate::fd::BorrowedFd; +use crate::backend::c; use bitflags::bitflags; -/// `struct timespec` -pub type Timespec = linux_raw_sys::general::__kernel_timespec; - -/// A type for the `tv_sec` field of [`Timespec`]. -pub type Secs = linux_raw_sys::general::__kernel_time64_t; - -/// A type for the `tv_nsec` field of [`Timespec`]. -pub type Nsecs = i64; - /// `struct itimerspec` for use with [`timerfd_gettime`] and /// [`timerfd_settime`]. /// @@ -18,73 +8,12 @@ pub type Nsecs = i64; /// [`timerfd_settime`]: crate::time::timerfd_settime pub type Itimerspec = linux_raw_sys::general::__kernel_itimerspec; -/// `CLOCK_*` constants for use with [`clock_gettime`]. -/// -/// These constants are always supported at runtime, so `clock_gettime` never -/// has to fail with `INVAL` due to an unsupported clock. See -/// [`DynamicClockId`] for a greater set of clocks, with the caveat that not -/// all of them are always supported. -/// -/// [`clock_gettime`]: crate::time::clock_gettime -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - Realtime = linux_raw_sys::general::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC` - Monotonic = linux_raw_sys::general::CLOCK_MONOTONIC, - - /// `CLOCK_PROCESS_CPUTIME_ID` - ProcessCPUTime = linux_raw_sys::general::CLOCK_PROCESS_CPUTIME_ID, - - /// `CLOCK_THREAD_CPUTIME_ID` - ThreadCPUTime = linux_raw_sys::general::CLOCK_THREAD_CPUTIME_ID, - - /// `CLOCK_REALTIME_COARSE` - RealtimeCoarse = linux_raw_sys::general::CLOCK_REALTIME_COARSE, - - /// `CLOCK_MONOTONIC_COARSE` - MonotonicCoarse = linux_raw_sys::general::CLOCK_MONOTONIC_COARSE, - - /// `CLOCK_MONOTONIC_RAW` - MonotonicRaw = linux_raw_sys::general::CLOCK_MONOTONIC_RAW, -} - -/// `CLOCK_*` constants for use with [`clock_gettime_dynamic`]. -/// -/// These constants may be unsupported at runtime, depending on the OS version, -/// and `clock_gettime_dynamic` may fail with `INVAL`. See [`ClockId`] for -/// clocks which are always supported at runtime. -/// -/// [`clock_gettime_dynamic`]: crate::time::clock_gettime_dynamic -#[derive(Debug, Copy, Clone)] -#[non_exhaustive] -pub enum DynamicClockId<'a> { - /// `ClockId` values that are always supported at runtime. - Known(ClockId), - - /// Linux dynamic clocks. - Dynamic(BorrowedFd<'a>), - - /// `CLOCK_REALTIME_ALARM`, available on Linux >= 3.0 - RealtimeAlarm, - - /// `CLOCK_TAI`, available on Linux >= 3.10 - Tai, - - /// `CLOCK_BOOTTIME`, available on Linux >= 2.6.39 - Boottime, - - /// `CLOCK_BOOTTIME_ALARM`, available on Linux >= 2.6.39 - BoottimeAlarm, -} - bitflags! { /// `TFD_*` flags for use with [`timerfd_create`]. /// /// [`timerfd_create`]: crate::time::timerfd_create + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TimerfdFlags: c::c_uint { /// `TFD_NONBLOCK` const NONBLOCK = linux_raw_sys::general::TFD_NONBLOCK; @@ -98,6 +27,8 @@ bitflags! { /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. /// /// [`timerfd_settime`]: crate::time::timerfd_settime + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct TimerfdTimerFlags: c::c_uint { /// `TFD_TIMER_ABSTIME` const ABSTIME = linux_raw_sys::general::TFD_TIMER_ABSTIME; diff --git a/vendor/rustix/src/backend/linux_raw/ugid/mod.rs b/vendor/rustix/src/backend/linux_raw/ugid/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/ugid/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/ugid/syscalls.rs b/vendor/rustix/src/backend/linux_raw/ugid/syscalls.rs new file mode 100644 index 000000000..12ff6dce1 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/ugid/syscalls.rs @@ -0,0 +1,67 @@ +//! linux_raw syscalls for UIDs and GIDs +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use crate::backend::c; +use crate::backend::conv::ret_usize_infallible; +use crate::ugid::{Gid, Uid}; + +#[inline] +pub(crate) fn getuid() -> Uid { + #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] + unsafe { + let uid = ret_usize_infallible(syscall_readonly!(__NR_getuid32)) as c::uid_t; + Uid::from_raw(uid) + } + #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] + unsafe { + let uid = ret_usize_infallible(syscall_readonly!(__NR_getuid)) as c::uid_t; + Uid::from_raw(uid) + } +} + +#[inline] +pub(crate) fn geteuid() -> Uid { + #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] + unsafe { + let uid = ret_usize_infallible(syscall_readonly!(__NR_geteuid32)) as c::uid_t; + Uid::from_raw(uid) + } + #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] + unsafe { + let uid = ret_usize_infallible(syscall_readonly!(__NR_geteuid)) as c::uid_t; + Uid::from_raw(uid) + } +} + +#[inline] +pub(crate) fn getgid() -> Gid { + #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] + unsafe { + let gid = ret_usize_infallible(syscall_readonly!(__NR_getgid32)) as c::gid_t; + Gid::from_raw(gid) + } + #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] + unsafe { + let gid = ret_usize_infallible(syscall_readonly!(__NR_getgid)) as c::gid_t; + Gid::from_raw(gid) + } +} + +#[inline] +pub(crate) fn getegid() -> Gid { + #[cfg(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86"))] + unsafe { + let gid = ret_usize_infallible(syscall_readonly!(__NR_getegid32)) as c::gid_t; + Gid::from_raw(gid) + } + #[cfg(not(any(target_arch = "arm", target_arch = "sparc", target_arch = "x86")))] + unsafe { + let gid = ret_usize_infallible(syscall_readonly!(__NR_getegid)) as c::gid_t; + Gid::from_raw(gid) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs index 97d5862a0..422793690 100644 --- a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs +++ b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs @@ -9,22 +9,30 @@ //! functions. #![allow(unsafe_code)] -use super::conv::{c_int, ret}; #[cfg(target_arch = "x86")] use super::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; -use super::time::types::{ClockId, DynamicClockId, Timespec}; -use super::{c, vdso}; -use crate::io; +use super::vdso; #[cfg(all(asm, target_arch = "x86"))] use core::arch::asm; -use core::mem::{transmute, MaybeUninit}; +use core::mem::transmute; use core::ptr::null_mut; use core::sync::atomic::AtomicPtr; use core::sync::atomic::Ordering::Relaxed; #[cfg(target_pointer_width = "32")] +#[cfg(feature = "time")] use linux_raw_sys::general::timespec as __kernel_old_timespec; -use linux_raw_sys::general::{__kernel_clockid_t, __kernel_timespec}; - +#[cfg(feature = "time")] +use { + super::c, + super::conv::{c_int, ret}, + crate::clockid::{ClockId, DynamicClockId}, + crate::io, + crate::timespec::Timespec, + core::mem::MaybeUninit, + linux_raw_sys::general::{__kernel_clockid_t, __kernel_timespec}, +}; + +#[cfg(feature = "time")] #[inline] pub(crate) fn clock_gettime(which_clock: ClockId) -> __kernel_timespec { // SAFETY: `CLOCK_GETTIME` contains either null or the address of a @@ -42,6 +50,7 @@ pub(crate) fn clock_gettime(which_clock: ClockId) -> __kernel_timespec { } } +#[cfg(feature = "time")] #[inline] pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Result<Timespec> { let id = match which_clock { @@ -198,6 +207,7 @@ pub(super) mod x86_via_vdso { // With the indirect call, it isn't meaningful to do a separate // `_readonly` optimization. + #[allow(unused_imports)] pub(in crate::backend) use { syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly, syscall3 as syscall3_readonly, @@ -206,6 +216,7 @@ pub(super) mod x86_via_vdso { }; } +#[cfg(feature = "time")] type ClockGettimeType = unsafe extern "C" fn(c::c_int, *mut Timespec) -> c::c_int; /// The underlying syscall functions are only called from asm, using the @@ -215,6 +226,7 @@ type ClockGettimeType = unsafe extern "C" fn(c::c_int, *mut Timespec) -> c::c_in pub(super) type SyscallType = unsafe extern "C" fn(); /// Initialize `CLOCK_GETTIME` and return its value. +#[cfg(feature = "time")] fn init_clock_gettime() -> ClockGettimeType { init(); // SAFETY: Load the function address from static storage that we @@ -234,10 +246,12 @@ fn init_syscall() -> SyscallType { /// `AtomicPtr` can't hold a `fn` pointer, so we use a `*` pointer to this /// placeholder type, and cast it as needed. struct Function; +#[cfg(feature = "time")] static mut CLOCK_GETTIME: AtomicPtr<Function> = AtomicPtr::new(null_mut()); #[cfg(target_arch = "x86")] static mut SYSCALL: AtomicPtr<Function> = AtomicPtr::new(null_mut()); +#[cfg(feature = "time")] unsafe extern "C" fn rustix_clock_gettime_via_syscall( clockid: c::c_int, res: *mut Timespec, @@ -248,6 +262,7 @@ unsafe extern "C" fn rustix_clock_gettime_via_syscall( } } +#[cfg(feature = "time")] #[cfg(target_pointer_width = "32")] unsafe fn _rustix_clock_gettime_via_syscall( clockid: c::c_int, @@ -260,6 +275,7 @@ unsafe fn _rustix_clock_gettime_via_syscall( } } +#[cfg(feature = "time")] #[cfg(target_pointer_width = "32")] unsafe fn _rustix_clock_gettime_via_syscall_old( clockid: c::c_int, @@ -285,6 +301,7 @@ unsafe fn _rustix_clock_gettime_via_syscall_old( } } +#[cfg(feature = "time")] #[cfg(target_pointer_width = "64")] unsafe fn _rustix_clock_gettime_via_syscall( clockid: c::c_int, @@ -314,14 +331,18 @@ fn minimal_init() { // If the memory happens to already be initialized, this is redundant, but // not harmful. unsafe { - CLOCK_GETTIME - .compare_exchange( - null_mut(), - rustix_clock_gettime_via_syscall as *mut Function, - Relaxed, - Relaxed, - ) - .ok(); + #[cfg(feature = "time")] + { + CLOCK_GETTIME + .compare_exchange( + null_mut(), + rustix_clock_gettime_via_syscall as *mut Function, + Relaxed, + Relaxed, + ) + .ok(); + } + #[cfg(target_arch = "x86")] { SYSCALL @@ -340,46 +361,49 @@ fn init() { minimal_init(); if let Some(vdso) = vdso::Vdso::new() { - // Look up the platform-specific `clock_gettime` symbol as documented - // [here], except on 32-bit platforms where we look up the - // `64`-suffixed variant and fail if we don't find it. - // - // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html - #[cfg(target_arch = "x86_64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); - #[cfg(target_arch = "arm")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "aarch64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_clock_gettime")); - #[cfg(target_arch = "x86")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "riscv64")] - let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_clock_gettime")); - #[cfg(target_arch = "powerpc64")] - let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_clock_gettime")); - #[cfg(target_arch = "mips")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); - #[cfg(target_arch = "mips64")] - let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); - - // On all 64-bit platforms, the 64-bit `clock_gettime` symbols are - // always available. - #[cfg(target_pointer_width = "64")] - let ok = true; - - // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are not - // available on older kernel versions. - #[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "x86"))] - let ok = !ptr.is_null(); - - if ok { - assert!(!ptr.is_null()); - - // SAFETY: Store the computed function addresses in static storage - // so that we don't need to compute it again (but if we do, it doesn't - // hurt anything). - unsafe { - CLOCK_GETTIME.store(ptr.cast(), Relaxed); + #[cfg(feature = "time")] + { + // Look up the platform-specific `clock_gettime` symbol as documented + // [here], except on 32-bit platforms where we look up the + // `64`-suffixed variant and fail if we don't find it. + // + // [here]: https://man7.org/linux/man-pages/man7/vdso.7.html + #[cfg(target_arch = "x86_64")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); + #[cfg(target_arch = "arm")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); + #[cfg(target_arch = "aarch64")] + let ptr = vdso.sym(cstr!("LINUX_2.6.39"), cstr!("__kernel_clock_gettime")); + #[cfg(target_arch = "x86")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); + #[cfg(target_arch = "riscv64")] + let ptr = vdso.sym(cstr!("LINUX_4.15"), cstr!("__vdso_clock_gettime")); + #[cfg(target_arch = "powerpc64")] + let ptr = vdso.sym(cstr!("LINUX_2.6.15"), cstr!("__kernel_clock_gettime")); + #[cfg(target_arch = "mips")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); + #[cfg(target_arch = "mips64")] + let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); + + // On all 64-bit platforms, the 64-bit `clock_gettime` symbols are + // always available. + #[cfg(target_pointer_width = "64")] + let ok = true; + + // On some 32-bit platforms, the 64-bit `clock_gettime` symbols are not + // available on older kernel versions. + #[cfg(any(target_arch = "arm", target_arch = "mips", target_arch = "x86"))] + let ok = !ptr.is_null(); + + if ok { + assert!(!ptr.is_null()); + + // SAFETY: Store the computed function addresses in static storage + // so that we don't need to compute it again (but if we do, it + // doesn't hurt anything). + unsafe { + CLOCK_GETTIME.store(ptr.cast(), Relaxed); + } } } |