From 4e8199b572f2035b7749cba276ece3a26630d23e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:21 +0200 Subject: Adding upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/rustix/.cargo-checksum.json | 2 +- vendor/rustix/Cargo.lock | 1281 -------------- vendor/rustix/Cargo.toml | 59 +- vendor/rustix/README.md | 10 +- vendor/rustix/build.rs | 15 +- vendor/rustix/ci/getsockopt-timeouts.patch | 80 - vendor/rustix/ci/s390x-stat-have-nsec.patch | 27 - vendor/rustix/ci/translate-errno.patch | 28 - vendor/rustix/examples/dup2_to_replace_stdio.rs | 55 - vendor/rustix/examples/hello.rs | 43 - vendor/rustix/examples/process.rs | 105 -- vendor/rustix/examples/stdio.rs | 465 ----- vendor/rustix/examples/time.rs | 20 - vendor/rustix/src/backend/libc/conv.rs | 222 +++ vendor/rustix/src/backend/libc/fs/dir.rs | 483 ++++++ vendor/rustix/src/backend/libc/fs/makedev.rs | 90 + vendor/rustix/src/backend/libc/fs/mod.rs | 19 + vendor/rustix/src/backend/libc/fs/syscalls.rs | 1772 ++++++++++++++++++++ vendor/rustix/src/backend/libc/fs/types.rs | 1116 ++++++++++++ vendor/rustix/src/backend/libc/io/epoll.rs | 573 +++++++ vendor/rustix/src/backend/libc/io/errno.rs | 1106 ++++++++++++ vendor/rustix/src/backend/libc/io/io_slice.rs | 87 + vendor/rustix/src/backend/libc/io/mod.rs | 13 + vendor/rustix/src/backend/libc/io/poll_fd.rs | 136 ++ vendor/rustix/src/backend/libc/io/syscalls.rs | 533 ++++++ vendor/rustix/src/backend/libc/io/types.rs | 164 ++ .../rustix/src/backend/libc/io/windows_syscalls.rs | 39 + vendor/rustix/src/backend/libc/io_lifetimes.rs | 77 + vendor/rustix/src/backend/libc/io_uring/mod.rs | 1 + .../rustix/src/backend/libc/io_uring/syscalls.rs | 55 + vendor/rustix/src/backend/libc/mm/mod.rs | 2 + vendor/rustix/src/backend/libc/mm/syscalls.rs | 218 +++ vendor/rustix/src/backend/libc/mm/types.rs | 428 +++++ vendor/rustix/src/backend/libc/mod.rs | 111 ++ vendor/rustix/src/backend/libc/net/addr.rs | 330 ++++ vendor/rustix/src/backend/libc/net/ext.rs | 210 +++ vendor/rustix/src/backend/libc/net/mod.rs | 7 + .../rustix/src/backend/libc/net/read_sockaddr.rs | 255 +++ vendor/rustix/src/backend/libc/net/send_recv.rs | 83 + vendor/rustix/src/backend/libc/net/syscalls.rs | 886 ++++++++++ vendor/rustix/src/backend/libc/net/types.rs | 687 ++++++++ .../rustix/src/backend/libc/net/write_sockaddr.rs | 102 ++ vendor/rustix/src/backend/libc/offset.rs | 406 +++++ vendor/rustix/src/backend/libc/param/auxv.rs | 54 + vendor/rustix/src/backend/libc/param/mod.rs | 1 + vendor/rustix/src/backend/libc/process/cpu_set.rs | 49 + vendor/rustix/src/backend/libc/process/mod.rs | 12 + vendor/rustix/src/backend/libc/process/syscalls.rs | 465 +++++ vendor/rustix/src/backend/libc/process/types.rs | 414 +++++ vendor/rustix/src/backend/libc/process/wait.rs | 6 + vendor/rustix/src/backend/libc/rand/mod.rs | 2 + vendor/rustix/src/backend/libc/rand/syscalls.rs | 16 + vendor/rustix/src/backend/libc/rand/types.rs | 19 + vendor/rustix/src/backend/libc/termios/mod.rs | 2 + vendor/rustix/src/backend/libc/termios/syscalls.rs | 158 ++ vendor/rustix/src/backend/libc/termios/types.rs | 1046 ++++++++++++ vendor/rustix/src/backend/libc/thread/mod.rs | 2 + vendor/rustix/src/backend/libc/thread/syscalls.rs | 295 ++++ vendor/rustix/src/backend/libc/time/mod.rs | 3 + vendor/rustix/src/backend/libc/time/syscalls.rs | 414 +++++ vendor/rustix/src/backend/libc/time/types.rs | 364 ++++ vendor/rustix/src/backend/libc/weak.rs | 226 +++ vendor/rustix/src/backend/libc/winsock_c.rs | 82 + .../src/backend/linux_raw/arch/inline/aarch64.rs | 268 +++ .../src/backend/linux_raw/arch/inline/arm.rs | 265 +++ .../src/backend/linux_raw/arch/inline/mips.rs | 543 ++++++ .../src/backend/linux_raw/arch/inline/mips64.rs | 466 +++++ .../src/backend/linux_raw/arch/inline/mod.rs | 18 + .../src/backend/linux_raw/arch/inline/powerpc64.rs | 413 +++++ .../src/backend/linux_raw/arch/inline/riscv64.rs | 265 +++ .../src/backend/linux_raw/arch/inline/thumb.rs | 322 ++++ .../src/backend/linux_raw/arch/inline/x86.rs | 494 ++++++ .../src/backend/linux_raw/arch/inline/x86_64.rs | 293 ++++ vendor/rustix/src/backend/linux_raw/arch/mod.rs | 222 +++ .../src/backend/linux_raw/arch/outline/aarch64.s | 119 ++ .../src/backend/linux_raw/arch/outline/arm.s | 135 ++ .../src/backend/linux_raw/arch/outline/mips.s | 213 +++ .../src/backend/linux_raw/arch/outline/mips64.s | 189 +++ .../src/backend/linux_raw/arch/outline/mod.rs | 33 + .../src/backend/linux_raw/arch/outline/nr_last.rs | 166 ++ .../src/backend/linux_raw/arch/outline/powerpc64.s | 132 ++ .../src/backend/linux_raw/arch/outline/riscv64.s | 116 ++ .../src/backend/linux_raw/arch/outline/x86.rs | 285 ++++ .../src/backend/linux_raw/arch/outline/x86.s | 381 +++++ .../src/backend/linux_raw/arch/outline/x86_64.s | 122 ++ vendor/rustix/src/backend/linux_raw/c.rs | 29 + vendor/rustix/src/backend/linux_raw/conv.rs | 790 +++++++++ vendor/rustix/src/backend/linux_raw/elf.rs | 176 ++ vendor/rustix/src/backend/linux_raw/fs/dir.rs | 225 +++ vendor/rustix/src/backend/linux_raw/fs/makedev.rs | 19 + vendor/rustix/src/backend/linux_raw/fs/mod.rs | 4 + vendor/rustix/src/backend/linux_raw/fs/syscalls.rs | 1384 +++++++++++++++ vendor/rustix/src/backend/linux_raw/fs/types.rs | 646 +++++++ vendor/rustix/src/backend/linux_raw/io/epoll.rs | 555 ++++++ vendor/rustix/src/backend/linux_raw/io/errno.rs | 517 ++++++ vendor/rustix/src/backend/linux_raw/io/io_slice.rs | 98 ++ vendor/rustix/src/backend/linux_raw/io/mod.rs | 7 + vendor/rustix/src/backend/linux_raw/io/poll_fd.rs | 93 + vendor/rustix/src/backend/linux_raw/io/syscalls.rs | 676 ++++++++ vendor/rustix/src/backend/linux_raw/io/types.rs | 128 ++ .../rustix/src/backend/linux_raw/io_uring/mod.rs | 1 + .../src/backend/linux_raw/io_uring/syscalls.rs | 63 + vendor/rustix/src/backend/linux_raw/mm/mod.rs | 2 + vendor/rustix/src/backend/linux_raw/mm/syscalls.rs | 214 +++ vendor/rustix/src/backend/linux_raw/mm/types.rs | 208 +++ vendor/rustix/src/backend/linux_raw/mod.rs | 68 + vendor/rustix/src/backend/linux_raw/net/addr.rs | 172 ++ vendor/rustix/src/backend/linux_raw/net/mod.rs | 6 + .../src/backend/linux_raw/net/read_sockaddr.rs | 175 ++ .../rustix/src/backend/linux_raw/net/send_recv.rs | 42 + .../rustix/src/backend/linux_raw/net/syscalls.rs | 1248 ++++++++++++++ vendor/rustix/src/backend/linux_raw/net/types.rs | 282 ++++ .../src/backend/linux_raw/net/write_sockaddr.rs | 60 + vendor/rustix/src/backend/linux_raw/param/auxv.rs | 370 ++++ .../src/backend/linux_raw/param/libc_auxv.rs | 74 + vendor/rustix/src/backend/linux_raw/param/mod.rs | 12 + .../src/backend/linux_raw/param/mustang_auxv.rs | 159 ++ .../src/backend/linux_raw/process/cpu_set.rs | 47 + vendor/rustix/src/backend/linux_raw/process/mod.rs | 4 + .../src/backend/linux_raw/process/syscalls.rs | 560 +++++++ .../rustix/src/backend/linux_raw/process/types.rs | 246 +++ .../rustix/src/backend/linux_raw/process/wait.rs | 39 + vendor/rustix/src/backend/linux_raw/rand/mod.rs | 2 + .../rustix/src/backend/linux_raw/rand/syscalls.rs | 17 + vendor/rustix/src/backend/linux_raw/rand/types.rs | 15 + vendor/rustix/src/backend/linux_raw/reg.rs | 258 +++ vendor/rustix/src/backend/linux_raw/runtime/mod.rs | 2 + .../src/backend/linux_raw/runtime/syscalls.rs | 107 ++ vendor/rustix/src/backend/linux_raw/runtime/tls.rs | 57 + vendor/rustix/src/backend/linux_raw/termios/mod.rs | 2 + .../src/backend/linux_raw/termios/syscalls.rs | 252 +++ .../rustix/src/backend/linux_raw/termios/types.rs | 460 +++++ .../rustix/src/backend/linux_raw/thread/futex.rs | 39 + vendor/rustix/src/backend/linux_raw/thread/mod.rs | 4 + .../src/backend/linux_raw/thread/syscalls.rs | 290 ++++ vendor/rustix/src/backend/linux_raw/time/mod.rs | 3 + .../rustix/src/backend/linux_raw/time/syscalls.rs | 229 +++ vendor/rustix/src/backend/linux_raw/time/types.rs | 154 ++ vendor/rustix/src/backend/linux_raw/vdso.rs | 310 ++++ .../rustix/src/backend/linux_raw/vdso_wrappers.rs | 399 +++++ vendor/rustix/src/const_assert.rs | 1 + vendor/rustix/src/fs/abs.rs | 42 +- vendor/rustix/src/fs/at.rs | 55 +- vendor/rustix/src/fs/constants.rs | 15 +- vendor/rustix/src/fs/copy_file_range.rs | 6 +- vendor/rustix/src/fs/cwd.rs | 6 +- vendor/rustix/src/fs/dir.rs | 4 +- vendor/rustix/src/fs/fadvise.rs | 8 +- vendor/rustix/src/fs/fcntl.rs | 72 +- vendor/rustix/src/fs/fcntl_darwin.rs | 8 +- vendor/rustix/src/fs/fcopyfile.rs | 16 +- vendor/rustix/src/fs/fd.rs | 97 +- vendor/rustix/src/fs/file_type.rs | 4 +- vendor/rustix/src/fs/getpath.rs | 6 +- vendor/rustix/src/fs/makedev.rs | 8 +- vendor/rustix/src/fs/memfd_create.rs | 8 +- vendor/rustix/src/fs/mod.rs | 51 +- vendor/rustix/src/fs/openat2.rs | 10 +- vendor/rustix/src/fs/sendfile.rs | 6 +- vendor/rustix/src/fs/statx.rs | 10 +- vendor/rustix/src/imp/libc/conv.rs | 220 --- vendor/rustix/src/imp/libc/fs/dir.rs | 402 ----- vendor/rustix/src/imp/libc/fs/makedev.rs | 90 - vendor/rustix/src/imp/libc/fs/mod.rs | 18 - vendor/rustix/src/imp/libc/fs/syscalls.rs | 1670 ------------------ vendor/rustix/src/imp/libc/fs/types.rs | 1028 ------------ vendor/rustix/src/imp/libc/io/epoll.rs | 568 ------- vendor/rustix/src/imp/libc/io/errno.rs | 997 ----------- vendor/rustix/src/imp/libc/io/io_slice.rs | 85 - vendor/rustix/src/imp/libc/io/mod.rs | 13 - vendor/rustix/src/imp/libc/io/poll_fd.rs | 136 -- vendor/rustix/src/imp/libc/io/syscalls.rs | 456 ----- vendor/rustix/src/imp/libc/io/types.rs | 89 - vendor/rustix/src/imp/libc/io/windows_syscalls.rs | 39 - vendor/rustix/src/imp/libc/io_lifetimes.rs | 109 -- vendor/rustix/src/imp/libc/io_uring/mod.rs | 1 - vendor/rustix/src/imp/libc/io_uring/syscalls.rs | 55 - vendor/rustix/src/imp/libc/mm/mod.rs | 2 - vendor/rustix/src/imp/libc/mm/syscalls.rs | 218 --- vendor/rustix/src/imp/libc/mm/types.rs | 397 ----- vendor/rustix/src/imp/libc/mod.rs | 111 -- vendor/rustix/src/imp/libc/net/addr.rs | 320 ---- vendor/rustix/src/imp/libc/net/ext.rs | 223 --- vendor/rustix/src/imp/libc/net/mod.rs | 7 - vendor/rustix/src/imp/libc/net/read_sockaddr.rs | 249 --- vendor/rustix/src/imp/libc/net/send_recv.rs | 77 - vendor/rustix/src/imp/libc/net/syscalls.rs | 866 ---------- vendor/rustix/src/imp/libc/net/types.rs | 621 ------- vendor/rustix/src/imp/libc/net/write_sockaddr.rs | 96 -- vendor/rustix/src/imp/libc/offset.rs | 361 ---- vendor/rustix/src/imp/libc/param/auxv.rs | 66 - vendor/rustix/src/imp/libc/param/mod.rs | 1 - vendor/rustix/src/imp/libc/process/cpu_set.rs | 49 - vendor/rustix/src/imp/libc/process/mod.rs | 12 - vendor/rustix/src/imp/libc/process/syscalls.rs | 419 ----- vendor/rustix/src/imp/libc/process/types.rs | 361 ---- vendor/rustix/src/imp/libc/process/wait.rs | 6 - vendor/rustix/src/imp/libc/rand/mod.rs | 2 - vendor/rustix/src/imp/libc/rand/syscalls.rs | 16 - vendor/rustix/src/imp/libc/rand/types.rs | 19 - vendor/rustix/src/imp/libc/termios/mod.rs | 2 - vendor/rustix/src/imp/libc/termios/syscalls.rs | 159 -- vendor/rustix/src/imp/libc/termios/types.rs | 951 ----------- vendor/rustix/src/imp/libc/thread/mod.rs | 2 - vendor/rustix/src/imp/libc/thread/syscalls.rs | 282 ---- vendor/rustix/src/imp/libc/time/mod.rs | 3 - vendor/rustix/src/imp/libc/time/syscalls.rs | 414 ----- vendor/rustix/src/imp/libc/time/types.rs | 362 ---- vendor/rustix/src/imp/libc/weak.rs | 226 --- vendor/rustix/src/imp/libc/winsock_c.rs | 82 - .../src/imp/linux_raw/arch/inline/aarch64.rs | 266 --- vendor/rustix/src/imp/linux_raw/arch/inline/arm.rs | 263 --- .../rustix/src/imp/linux_raw/arch/inline/mips.rs | 543 ------ .../rustix/src/imp/linux_raw/arch/inline/mips64.rs | 464 ----- vendor/rustix/src/imp/linux_raw/arch/inline/mod.rs | 17 - .../src/imp/linux_raw/arch/inline/powerpc64.rs | 411 ----- .../src/imp/linux_raw/arch/inline/riscv64.rs | 263 --- vendor/rustix/src/imp/linux_raw/arch/inline/x86.rs | 492 ------ .../rustix/src/imp/linux_raw/arch/inline/x86_64.rs | 291 ---- vendor/rustix/src/imp/linux_raw/arch/mod.rs | 218 --- .../src/imp/linux_raw/arch/outline/aarch64.s | 119 -- vendor/rustix/src/imp/linux_raw/arch/outline/arm.s | 135 -- .../rustix/src/imp/linux_raw/arch/outline/mips.s | 213 --- .../rustix/src/imp/linux_raw/arch/outline/mips64.s | 189 --- .../rustix/src/imp/linux_raw/arch/outline/mod.rs | 33 - .../src/imp/linux_raw/arch/outline/nr_last.rs | 166 -- .../src/imp/linux_raw/arch/outline/powerpc64.s | 132 -- .../src/imp/linux_raw/arch/outline/riscv64.s | 116 -- .../rustix/src/imp/linux_raw/arch/outline/x86.rs | 285 ---- vendor/rustix/src/imp/linux_raw/arch/outline/x86.s | 381 ----- .../rustix/src/imp/linux_raw/arch/outline/x86_64.s | 122 -- vendor/rustix/src/imp/linux_raw/c.rs | 29 - vendor/rustix/src/imp/linux_raw/conv.rs | 770 --------- vendor/rustix/src/imp/linux_raw/elf.rs | 172 -- vendor/rustix/src/imp/linux_raw/fs/dir.rs | 213 --- vendor/rustix/src/imp/linux_raw/fs/makedev.rs | 19 - vendor/rustix/src/imp/linux_raw/fs/mod.rs | 5 - vendor/rustix/src/imp/linux_raw/fs/syscalls.rs | 1391 --------------- vendor/rustix/src/imp/linux_raw/fs/types.rs | 613 ------- vendor/rustix/src/imp/linux_raw/io/epoll.rs | 551 ------ vendor/rustix/src/imp/linux_raw/io/errno.rs | 511 ------ vendor/rustix/src/imp/linux_raw/io/io_slice.rs | 98 -- vendor/rustix/src/imp/linux_raw/io/mod.rs | 7 - vendor/rustix/src/imp/linux_raw/io/poll_fd.rs | 93 - vendor/rustix/src/imp/linux_raw/io/syscalls.rs | 560 ------- vendor/rustix/src/imp/linux_raw/io/types.rs | 67 - vendor/rustix/src/imp/linux_raw/io_uring/mod.rs | 1 - .../rustix/src/imp/linux_raw/io_uring/syscalls.rs | 64 - vendor/rustix/src/imp/linux_raw/mm/mod.rs | 2 - vendor/rustix/src/imp/linux_raw/mm/syscalls.rs | 214 --- vendor/rustix/src/imp/linux_raw/mm/types.rs | 208 --- vendor/rustix/src/imp/linux_raw/mod.rs | 68 - vendor/rustix/src/imp/linux_raw/net/addr.rs | 172 -- vendor/rustix/src/imp/linux_raw/net/ext.rs | 64 - vendor/rustix/src/imp/linux_raw/net/mod.rs | 8 - .../rustix/src/imp/linux_raw/net/read_sockaddr.rs | 175 -- vendor/rustix/src/imp/linux_raw/net/send_recv.rs | 42 - vendor/rustix/src/imp/linux_raw/net/syscalls.rs | 1234 -------------- vendor/rustix/src/imp/linux_raw/net/types.rs | 282 ---- .../rustix/src/imp/linux_raw/net/write_sockaddr.rs | 60 - vendor/rustix/src/imp/linux_raw/param/auxv.rs | 203 --- vendor/rustix/src/imp/linux_raw/param/mod.rs | 1 - vendor/rustix/src/imp/linux_raw/process/cpu_set.rs | 47 - vendor/rustix/src/imp/linux_raw/process/mod.rs | 4 - .../rustix/src/imp/linux_raw/process/syscalls.rs | 517 ------ vendor/rustix/src/imp/linux_raw/process/types.rs | 246 --- vendor/rustix/src/imp/linux_raw/process/wait.rs | 39 - vendor/rustix/src/imp/linux_raw/rand/mod.rs | 2 - vendor/rustix/src/imp/linux_raw/rand/syscalls.rs | 17 - vendor/rustix/src/imp/linux_raw/rand/types.rs | 15 - vendor/rustix/src/imp/linux_raw/reg.rs | 258 --- vendor/rustix/src/imp/linux_raw/runtime/mod.rs | 2 - .../rustix/src/imp/linux_raw/runtime/syscalls.rs | 104 -- vendor/rustix/src/imp/linux_raw/runtime/tls.rs | 62 - vendor/rustix/src/imp/linux_raw/termios/mod.rs | 2 - .../rustix/src/imp/linux_raw/termios/syscalls.rs | 249 --- vendor/rustix/src/imp/linux_raw/termios/types.rs | 456 ----- vendor/rustix/src/imp/linux_raw/thread/futex.rs | 39 - vendor/rustix/src/imp/linux_raw/thread/mod.rs | 4 - vendor/rustix/src/imp/linux_raw/thread/syscalls.rs | 280 ---- vendor/rustix/src/imp/linux_raw/time/mod.rs | 3 - vendor/rustix/src/imp/linux_raw/time/syscalls.rs | 229 --- vendor/rustix/src/imp/linux_raw/time/types.rs | 154 -- vendor/rustix/src/imp/linux_raw/vdso.rs | 435 ----- vendor/rustix/src/imp/linux_raw/vdso_wrappers.rs | 397 ----- vendor/rustix/src/io/close.rs | 6 +- vendor/rustix/src/io/dup.rs | 20 +- vendor/rustix/src/io/errno.rs | 4 +- vendor/rustix/src/io/eventfd.rs | 8 +- vendor/rustix/src/io/fcntl.rs | 86 + vendor/rustix/src/io/fd/owned.rs | 4 +- vendor/rustix/src/io/fd/raw.rs | 2 +- vendor/rustix/src/io/ioctl.rs | 22 +- vendor/rustix/src/io/is_read_write.rs | 10 +- vendor/rustix/src/io/mod.rs | 45 +- vendor/rustix/src/io/owned_fd.rs | 272 --- vendor/rustix/src/io/pipe.rs | 91 +- vendor/rustix/src/io/poll.rs | 6 +- vendor/rustix/src/io/procfs.rs | 106 +- vendor/rustix/src/io/read_write.rs | 32 +- vendor/rustix/src/io/stdio.rs | 96 +- vendor/rustix/src/io_uring.rs | 19 +- vendor/rustix/src/lib.rs | 30 +- vendor/rustix/src/mm/madvise.rs | 6 +- vendor/rustix/src/mm/mmap.rs | 28 +- vendor/rustix/src/mm/msync.rs | 6 +- vendor/rustix/src/mm/userfaultfd.rs | 8 +- vendor/rustix/src/net/addr.rs | 204 +-- vendor/rustix/src/net/ip.rs | 423 +++-- vendor/rustix/src/net/send_recv.rs | 28 +- vendor/rustix/src/net/socket.rs | 62 +- vendor/rustix/src/net/socket_addr_any.rs | 20 +- vendor/rustix/src/net/socketpair.rs | 6 +- vendor/rustix/src/net/sockopt.rs | 102 +- vendor/rustix/src/net/wsa.rs | 4 +- vendor/rustix/src/param/auxv.rs | 10 +- vendor/rustix/src/param/init.rs | 4 +- vendor/rustix/src/param/mod.rs | 10 +- vendor/rustix/src/path/arg.rs | 28 +- vendor/rustix/src/path/dec_int.rs | 2 +- vendor/rustix/src/process/chdir.rs | 10 +- vendor/rustix/src/process/exit.rs | 8 +- vendor/rustix/src/process/id.rs | 53 +- vendor/rustix/src/process/kill.rs | 10 +- vendor/rustix/src/process/membarrier.rs | 10 +- vendor/rustix/src/process/mod.rs | 13 +- vendor/rustix/src/process/prctl.rs | 1120 +++++++++++++ vendor/rustix/src/process/priority.rs | 16 +- vendor/rustix/src/process/procctl.rs | 180 ++ vendor/rustix/src/process/rlimit.rs | 10 +- vendor/rustix/src/process/sched.rs | 22 +- vendor/rustix/src/process/sched_yield.rs | 4 +- vendor/rustix/src/process/uname.rs | 6 +- vendor/rustix/src/process/wait.rs | 26 +- vendor/rustix/src/rand/getrandom.rs | 6 +- vendor/rustix/src/runtime.rs | 38 +- vendor/rustix/src/termios/cf.rs | 14 +- vendor/rustix/src/termios/constants.rs | 401 +++-- vendor/rustix/src/termios/mod.rs | 105 +- vendor/rustix/src/termios/tc.rs | 26 +- vendor/rustix/src/termios/tty.rs | 11 +- vendor/rustix/src/thread/clock.rs | 14 +- vendor/rustix/src/thread/futex.rs | 6 +- vendor/rustix/src/thread/id.rs | 4 +- vendor/rustix/src/thread/mod.rs | 9 + vendor/rustix/src/thread/prctl.rs | 989 +++++++++++ vendor/rustix/src/thread/setns.rs | 89 + vendor/rustix/src/time/clock.rs | 12 +- vendor/rustix/src/time/timerfd.rs | 13 +- vendor/rustix/src/utils.rs | 16 + vendor/rustix/tests/backends.rs | 109 -- vendor/rustix/tests/fs/cwd.rs | 3 - vendor/rustix/tests/fs/dir.rs | 37 - vendor/rustix/tests/fs/fcntl.rs | 17 - vendor/rustix/tests/fs/file.rs | 83 - vendor/rustix/tests/fs/flock.rs | 34 - vendor/rustix/tests/fs/futimens.rs | 42 - vendor/rustix/tests/fs/invalid_offset.rs | 182 -- vendor/rustix/tests/fs/long_paths.rs | 28 - vendor/rustix/tests/fs/main.rs | 47 - vendor/rustix/tests/fs/makedev.rs | 10 - vendor/rustix/tests/fs/mkdirat.rs | 33 - vendor/rustix/tests/fs/mknodat.rs | 27 - vendor/rustix/tests/fs/openat.rs | 33 - vendor/rustix/tests/fs/openat2.rs | 184 -- vendor/rustix/tests/fs/readdir.rs | 68 - vendor/rustix/tests/fs/renameat.rs | 104 -- vendor/rustix/tests/fs/statfs.rs | 49 - vendor/rustix/tests/fs/utimensat.rs | 127 -- vendor/rustix/tests/fs/y2038.rs | 146 -- vendor/rustix/tests/io/dup2_to_replace_stdio.rs | 18 - vendor/rustix/tests/io/epoll.rs | 103 -- vendor/rustix/tests/io/error.rs | 14 - vendor/rustix/tests/io/eventfd.rs | 24 - vendor/rustix/tests/io/from_into.rs | 28 - vendor/rustix/tests/io/ioctl.rs | 14 - vendor/rustix/tests/io/main.rs | 31 - vendor/rustix/tests/io/poll.rs | 63 - vendor/rustix/tests/io/procfs.rs | 8 - vendor/rustix/tests/io/read_write.rs | 118 -- vendor/rustix/tests/io/seals.rs | 41 - vendor/rustix/tests/mm/main.rs | 13 - vendor/rustix/tests/mm/mlock.rs | 79 - vendor/rustix/tests/mm/mmap.rs | 163 -- vendor/rustix/tests/mm/prot.rs | 4 - vendor/rustix/tests/net/addr.rs | 92 - vendor/rustix/tests/net/connect_bind_send.rs | 487 ------ vendor/rustix/tests/net/main.rs | 32 - vendor/rustix/tests/net/poll.rs | 119 -- vendor/rustix/tests/net/sockopt.rs | 158 -- vendor/rustix/tests/net/unix.rs | 147 -- vendor/rustix/tests/net/v4.rs | 86 - vendor/rustix/tests/net/v6.rs | 95 -- vendor/rustix/tests/param/auxv.rs | 41 - vendor/rustix/tests/param/main.rs | 14 - vendor/rustix/tests/param/weak.rs | 201 --- vendor/rustix/tests/path/arg.rs | 167 -- vendor/rustix/tests/path/dec_int.rs | 20 - vendor/rustix/tests/path/main.rs | 13 - vendor/rustix/tests/process/cpu_set.rs | 14 - vendor/rustix/tests/process/id.rs | 65 - vendor/rustix/tests/process/main.rs | 28 - vendor/rustix/tests/process/membarrier.rs | 40 - vendor/rustix/tests/process/priority.rs | 83 - vendor/rustix/tests/process/proc.rs | 5 - vendor/rustix/tests/process/rlimit.rs | 51 - vendor/rustix/tests/process/sched_yield.rs | 7 - vendor/rustix/tests/process/uname.rs | 13 - vendor/rustix/tests/process/wait.rs | 25 - vendor/rustix/tests/process/weak.rs | 201 --- vendor/rustix/tests/process/working_directory.rs | 43 - vendor/rustix/tests/rand/getrandom.rs | 7 - vendor/rustix/tests/rand/main.rs | 9 - vendor/rustix/tests/termios/isatty.rs | 69 - vendor/rustix/tests/termios/main.rs | 10 - vendor/rustix/tests/termios/ttyname.rs | 24 - vendor/rustix/tests/thread/clocks.rs | 212 --- vendor/rustix/tests/thread/id.rs | 7 - vendor/rustix/tests/thread/main.rs | 9 - vendor/rustix/tests/time/dynamic_clocks.rs | 22 - vendor/rustix/tests/time/main.rs | 14 - vendor/rustix/tests/time/monotonic.rs | 45 - vendor/rustix/tests/time/timerfd.rs | 75 - vendor/rustix/tests/time/timespec.rs | 26 - vendor/rustix/tests/time/y2038.rs | 77 - 425 files changed, 35414 insertions(+), 38032 deletions(-) delete mode 100644 vendor/rustix/Cargo.lock delete mode 100644 vendor/rustix/ci/getsockopt-timeouts.patch delete mode 100644 vendor/rustix/ci/s390x-stat-have-nsec.patch delete mode 100644 vendor/rustix/ci/translate-errno.patch delete mode 100644 vendor/rustix/examples/dup2_to_replace_stdio.rs delete mode 100644 vendor/rustix/examples/hello.rs delete mode 100644 vendor/rustix/examples/process.rs delete mode 100644 vendor/rustix/examples/stdio.rs delete mode 100644 vendor/rustix/examples/time.rs create mode 100644 vendor/rustix/src/backend/libc/conv.rs create mode 100644 vendor/rustix/src/backend/libc/fs/dir.rs create mode 100644 vendor/rustix/src/backend/libc/fs/makedev.rs create mode 100644 vendor/rustix/src/backend/libc/fs/mod.rs create mode 100644 vendor/rustix/src/backend/libc/fs/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/fs/types.rs create mode 100644 vendor/rustix/src/backend/libc/io/epoll.rs create mode 100644 vendor/rustix/src/backend/libc/io/errno.rs create mode 100644 vendor/rustix/src/backend/libc/io/io_slice.rs create mode 100644 vendor/rustix/src/backend/libc/io/mod.rs create mode 100644 vendor/rustix/src/backend/libc/io/poll_fd.rs create mode 100644 vendor/rustix/src/backend/libc/io/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/io/types.rs create mode 100644 vendor/rustix/src/backend/libc/io/windows_syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/io_lifetimes.rs create mode 100644 vendor/rustix/src/backend/libc/io_uring/mod.rs create mode 100644 vendor/rustix/src/backend/libc/io_uring/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/mm/mod.rs create mode 100644 vendor/rustix/src/backend/libc/mm/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/mm/types.rs create mode 100644 vendor/rustix/src/backend/libc/mod.rs create mode 100644 vendor/rustix/src/backend/libc/net/addr.rs create mode 100644 vendor/rustix/src/backend/libc/net/ext.rs create mode 100644 vendor/rustix/src/backend/libc/net/mod.rs create mode 100644 vendor/rustix/src/backend/libc/net/read_sockaddr.rs create mode 100644 vendor/rustix/src/backend/libc/net/send_recv.rs create mode 100644 vendor/rustix/src/backend/libc/net/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/net/types.rs create mode 100644 vendor/rustix/src/backend/libc/net/write_sockaddr.rs create mode 100644 vendor/rustix/src/backend/libc/offset.rs create mode 100644 vendor/rustix/src/backend/libc/param/auxv.rs create mode 100644 vendor/rustix/src/backend/libc/param/mod.rs create mode 100644 vendor/rustix/src/backend/libc/process/cpu_set.rs create mode 100644 vendor/rustix/src/backend/libc/process/mod.rs create mode 100644 vendor/rustix/src/backend/libc/process/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/process/types.rs create mode 100644 vendor/rustix/src/backend/libc/process/wait.rs create mode 100644 vendor/rustix/src/backend/libc/rand/mod.rs create mode 100644 vendor/rustix/src/backend/libc/rand/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/rand/types.rs create mode 100644 vendor/rustix/src/backend/libc/termios/mod.rs create mode 100644 vendor/rustix/src/backend/libc/termios/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/termios/types.rs create mode 100644 vendor/rustix/src/backend/libc/thread/mod.rs create mode 100644 vendor/rustix/src/backend/libc/thread/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/time/mod.rs create mode 100644 vendor/rustix/src/backend/libc/time/syscalls.rs create mode 100644 vendor/rustix/src/backend/libc/time/types.rs create mode 100644 vendor/rustix/src/backend/libc/weak.rs create mode 100644 vendor/rustix/src/backend/libc/winsock_c.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/aarch64.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/arm.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/mips.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/mips64.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/powerpc64.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/riscv64.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/thumb.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/inline/x86_64.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/arm.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/mips.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/nr_last.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/powerpc64.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/riscv64.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/x86.rs create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/x86.s create mode 100644 vendor/rustix/src/backend/linux_raw/arch/outline/x86_64.s create mode 100644 vendor/rustix/src/backend/linux_raw/c.rs create mode 100644 vendor/rustix/src/backend/linux_raw/conv.rs create mode 100644 vendor/rustix/src/backend/linux_raw/elf.rs create mode 100644 vendor/rustix/src/backend/linux_raw/fs/dir.rs create mode 100644 vendor/rustix/src/backend/linux_raw/fs/makedev.rs create mode 100644 vendor/rustix/src/backend/linux_raw/fs/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/fs/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/fs/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/epoll.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/errno.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/io_slice.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/poll_fd.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io_uring/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/mm/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/mm/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/mm/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/addr.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/send_recv.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs create mode 100644 vendor/rustix/src/backend/linux_raw/param/auxv.rs create mode 100644 vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs create mode 100644 vendor/rustix/src/backend/linux_raw/param/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs create mode 100644 vendor/rustix/src/backend/linux_raw/process/cpu_set.rs create mode 100644 vendor/rustix/src/backend/linux_raw/process/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/process/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/process/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/process/wait.rs create mode 100644 vendor/rustix/src/backend/linux_raw/rand/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/rand/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/rand/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/reg.rs create mode 100644 vendor/rustix/src/backend/linux_raw/runtime/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/runtime/tls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/termios/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/termios/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/termios/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/thread/futex.rs create mode 100644 vendor/rustix/src/backend/linux_raw/thread/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/thread/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/time/mod.rs create mode 100644 vendor/rustix/src/backend/linux_raw/time/syscalls.rs create mode 100644 vendor/rustix/src/backend/linux_raw/time/types.rs create mode 100644 vendor/rustix/src/backend/linux_raw/vdso.rs create mode 100644 vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs delete mode 100644 vendor/rustix/src/imp/libc/conv.rs delete mode 100644 vendor/rustix/src/imp/libc/fs/dir.rs delete mode 100644 vendor/rustix/src/imp/libc/fs/makedev.rs delete mode 100644 vendor/rustix/src/imp/libc/fs/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/fs/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/fs/types.rs delete mode 100644 vendor/rustix/src/imp/libc/io/epoll.rs delete mode 100644 vendor/rustix/src/imp/libc/io/errno.rs delete mode 100644 vendor/rustix/src/imp/libc/io/io_slice.rs delete mode 100644 vendor/rustix/src/imp/libc/io/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/io/poll_fd.rs delete mode 100644 vendor/rustix/src/imp/libc/io/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/io/types.rs delete mode 100644 vendor/rustix/src/imp/libc/io/windows_syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/io_lifetimes.rs delete mode 100644 vendor/rustix/src/imp/libc/io_uring/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/io_uring/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/mm/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/mm/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/mm/types.rs delete mode 100644 vendor/rustix/src/imp/libc/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/net/addr.rs delete mode 100644 vendor/rustix/src/imp/libc/net/ext.rs delete mode 100644 vendor/rustix/src/imp/libc/net/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/net/read_sockaddr.rs delete mode 100644 vendor/rustix/src/imp/libc/net/send_recv.rs delete mode 100644 vendor/rustix/src/imp/libc/net/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/net/types.rs delete mode 100644 vendor/rustix/src/imp/libc/net/write_sockaddr.rs delete mode 100644 vendor/rustix/src/imp/libc/offset.rs delete mode 100644 vendor/rustix/src/imp/libc/param/auxv.rs delete mode 100644 vendor/rustix/src/imp/libc/param/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/process/cpu_set.rs delete mode 100644 vendor/rustix/src/imp/libc/process/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/process/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/process/types.rs delete mode 100644 vendor/rustix/src/imp/libc/process/wait.rs delete mode 100644 vendor/rustix/src/imp/libc/rand/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/rand/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/rand/types.rs delete mode 100644 vendor/rustix/src/imp/libc/termios/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/termios/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/termios/types.rs delete mode 100644 vendor/rustix/src/imp/libc/thread/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/thread/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/time/mod.rs delete mode 100644 vendor/rustix/src/imp/libc/time/syscalls.rs delete mode 100644 vendor/rustix/src/imp/libc/time/types.rs delete mode 100644 vendor/rustix/src/imp/libc/weak.rs delete mode 100644 vendor/rustix/src/imp/libc/winsock_c.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/aarch64.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/arm.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/mips.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/mips64.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/powerpc64.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/riscv64.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/x86.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/inline/x86_64.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/aarch64.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/arm.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/mips.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/mips64.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/nr_last.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/powerpc64.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/riscv64.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/x86.s delete mode 100644 vendor/rustix/src/imp/linux_raw/arch/outline/x86_64.s delete mode 100644 vendor/rustix/src/imp/linux_raw/c.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/conv.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/elf.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/fs/dir.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/fs/makedev.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/fs/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/fs/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/fs/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/epoll.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/errno.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/io_slice.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/poll_fd.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io_uring/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/io_uring/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/mm/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/mm/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/mm/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/addr.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/ext.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/read_sockaddr.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/send_recv.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/net/write_sockaddr.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/param/auxv.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/param/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/process/cpu_set.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/process/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/process/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/process/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/process/wait.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/rand/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/rand/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/rand/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/reg.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/runtime/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/runtime/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/runtime/tls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/termios/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/termios/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/termios/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/thread/futex.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/thread/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/thread/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/time/mod.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/time/syscalls.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/time/types.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/vdso.rs delete mode 100644 vendor/rustix/src/imp/linux_raw/vdso_wrappers.rs create mode 100644 vendor/rustix/src/io/fcntl.rs delete mode 100644 vendor/rustix/src/io/owned_fd.rs create mode 100644 vendor/rustix/src/process/prctl.rs create mode 100644 vendor/rustix/src/process/procctl.rs create mode 100644 vendor/rustix/src/thread/prctl.rs create mode 100644 vendor/rustix/src/thread/setns.rs delete mode 100644 vendor/rustix/tests/backends.rs delete mode 100644 vendor/rustix/tests/fs/cwd.rs delete mode 100644 vendor/rustix/tests/fs/dir.rs delete mode 100644 vendor/rustix/tests/fs/fcntl.rs delete mode 100644 vendor/rustix/tests/fs/file.rs delete mode 100644 vendor/rustix/tests/fs/flock.rs delete mode 100644 vendor/rustix/tests/fs/futimens.rs delete mode 100644 vendor/rustix/tests/fs/invalid_offset.rs delete mode 100644 vendor/rustix/tests/fs/long_paths.rs delete mode 100644 vendor/rustix/tests/fs/main.rs delete mode 100644 vendor/rustix/tests/fs/makedev.rs delete mode 100644 vendor/rustix/tests/fs/mkdirat.rs delete mode 100644 vendor/rustix/tests/fs/mknodat.rs delete mode 100644 vendor/rustix/tests/fs/openat.rs delete mode 100644 vendor/rustix/tests/fs/openat2.rs delete mode 100644 vendor/rustix/tests/fs/readdir.rs delete mode 100644 vendor/rustix/tests/fs/renameat.rs delete mode 100644 vendor/rustix/tests/fs/statfs.rs delete mode 100644 vendor/rustix/tests/fs/utimensat.rs delete mode 100644 vendor/rustix/tests/fs/y2038.rs delete mode 100644 vendor/rustix/tests/io/dup2_to_replace_stdio.rs delete mode 100644 vendor/rustix/tests/io/epoll.rs delete mode 100644 vendor/rustix/tests/io/error.rs delete mode 100644 vendor/rustix/tests/io/eventfd.rs delete mode 100644 vendor/rustix/tests/io/from_into.rs delete mode 100644 vendor/rustix/tests/io/ioctl.rs delete mode 100644 vendor/rustix/tests/io/main.rs delete mode 100644 vendor/rustix/tests/io/poll.rs delete mode 100644 vendor/rustix/tests/io/procfs.rs delete mode 100644 vendor/rustix/tests/io/read_write.rs delete mode 100644 vendor/rustix/tests/io/seals.rs delete mode 100644 vendor/rustix/tests/mm/main.rs delete mode 100644 vendor/rustix/tests/mm/mlock.rs delete mode 100644 vendor/rustix/tests/mm/mmap.rs delete mode 100644 vendor/rustix/tests/mm/prot.rs delete mode 100644 vendor/rustix/tests/net/addr.rs delete mode 100644 vendor/rustix/tests/net/connect_bind_send.rs delete mode 100644 vendor/rustix/tests/net/main.rs delete mode 100644 vendor/rustix/tests/net/poll.rs delete mode 100644 vendor/rustix/tests/net/sockopt.rs delete mode 100644 vendor/rustix/tests/net/unix.rs delete mode 100644 vendor/rustix/tests/net/v4.rs delete mode 100644 vendor/rustix/tests/net/v6.rs delete mode 100644 vendor/rustix/tests/param/auxv.rs delete mode 100644 vendor/rustix/tests/param/main.rs delete mode 100644 vendor/rustix/tests/param/weak.rs delete mode 100644 vendor/rustix/tests/path/arg.rs delete mode 100644 vendor/rustix/tests/path/dec_int.rs delete mode 100644 vendor/rustix/tests/path/main.rs delete mode 100644 vendor/rustix/tests/process/cpu_set.rs delete mode 100644 vendor/rustix/tests/process/id.rs delete mode 100644 vendor/rustix/tests/process/main.rs delete mode 100644 vendor/rustix/tests/process/membarrier.rs delete mode 100644 vendor/rustix/tests/process/priority.rs delete mode 100644 vendor/rustix/tests/process/proc.rs delete mode 100644 vendor/rustix/tests/process/rlimit.rs delete mode 100644 vendor/rustix/tests/process/sched_yield.rs delete mode 100644 vendor/rustix/tests/process/uname.rs delete mode 100644 vendor/rustix/tests/process/wait.rs delete mode 100644 vendor/rustix/tests/process/weak.rs delete mode 100644 vendor/rustix/tests/process/working_directory.rs delete mode 100644 vendor/rustix/tests/rand/getrandom.rs delete mode 100644 vendor/rustix/tests/rand/main.rs delete mode 100644 vendor/rustix/tests/termios/isatty.rs delete mode 100644 vendor/rustix/tests/termios/main.rs delete mode 100644 vendor/rustix/tests/termios/ttyname.rs delete mode 100644 vendor/rustix/tests/thread/clocks.rs delete mode 100644 vendor/rustix/tests/thread/id.rs delete mode 100644 vendor/rustix/tests/thread/main.rs delete mode 100644 vendor/rustix/tests/time/dynamic_clocks.rs delete mode 100644 vendor/rustix/tests/time/main.rs delete mode 100644 vendor/rustix/tests/time/monotonic.rs delete mode 100644 vendor/rustix/tests/time/timerfd.rs delete mode 100644 vendor/rustix/tests/time/timespec.rs delete mode 100644 vendor/rustix/tests/time/y2038.rs (limited to 'vendor/rustix') diff --git a/vendor/rustix/.cargo-checksum.json b/vendor/rustix/.cargo-checksum.json index 400d20075..03b6e41ab 100644 --- a/vendor/rustix/.cargo-checksum.json +++ b/vendor/rustix/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CODE_OF_CONDUCT.md":"f210602311e3f74b32f46237fd55f4ce36d798e85e3db1432ec667f63a7ffc44","CONTRIBUTING.md":"fb570c76cf924cd75b77bed52b0dbe1e87ce224dc3428c48d98301710dcc331e","COPYRIGHT":"377c2e7c53250cc5905c0b0532d35973392af16ffb9596a41d99d202cf3617c9","Cargo.lock":"e37f04aa97ce0f46b8e576c184cf2721da3b5bb2f3d5c70e8b7d499ba28dbdff","Cargo.toml":"4c6237c9b334bdcc8b7abd9155666ec8721df934bd76e69a85ab81bb0d92f0c0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-Apache-2.0_WITH_LLVM-exception":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","ORG_CODE_OF_CONDUCT.md":"a62b69bf86e605ee1bcbb2f0a12ba79e4cebb6983a7b6491949750aecc4f2178","README.md":"a39bb3863c4d4cde6c9d8b9d99fad5b030ca14f85a6dbb8cc7c0f9403703cf08","SECURITY.md":"4d75afb09dd28eb5982e3a1f768ee398d90204669ceef3240a16b31dcf04148a","benches/mod.rs":"89a1349fc84e32d3f144daa4b6b41a97b3fd8dfaa71e7e4c0c7b4963f5afb019","build.rs":"69283e1aef247eb8d51ee41ca9e32efd57fd031da6f8ae20268b342eb1c9d19f","ci/getsockopt-timeouts.patch":"f2941f99cbcb4f3382b89f094d7ae74d7f4814ac9b27f594f4e83e26f45b8f07","ci/s390x-stat-have-nsec.patch":"d8f446000f25451eda8b65f350c7feb482aedcd71f8bde724321f70749edc363","ci/translate-errno.patch":"0bf9576a791eba44566ab1507b54d309c73cfc5504bff6e8ca07940b2c3e7b61","examples/dup2_to_replace_stdio.rs":"20816ccca0f0498ffa4a97dc3d9dc8d2fbdd88fd15dae55f2bf60529865dc9c7","examples/hello.rs":"06594427a12147298ef47dbece0f3cb10f8ebd1badc894e7545fbad2892e269f","examples/process.rs":"f2f4a58d8dfecbf8f71b825da805a143948ec8e1c907c8ef329bf0cacf54719d","examples/stdio.rs":"d1e7f68624814b925ceced2de457cbd0902b457ff1a441f0c6e28ed020d8dcb4","examples/time.rs":"965499c22e4dd9493b30a8ab3d72c3e0d79a1451d022dd4365a2a17a4caad6b0","src/const_assert.rs":"05a0b46b4b3333efe4148f29c523046754c3f08454e7d3cd1f17a3beb38f040b","src/cstr.rs":"e5db2aae8fcbad410218696e3e3b3a0da3cc17fc7f64360fc1127bc4e4deff76","src/ffi/mod.rs":"1990dae8190991142bef24220f02b99c96c5bfa7dda2a7974d9dcac265d58945","src/fs/abs.rs":"89714d984afe1d872a2d3b2a44dee2051a09956631518e0fe7b0ea7d1612f4a5","src/fs/at.rs":"f462bf9a2476c5047c76e2c9e167e3e7f3a080133041d8497e039cb5e84c33f2","src/fs/constants.rs":"301ab8e8e99d1d673ebf0e6a6a4f28671130759c934aea1659340edbf4ded90d","src/fs/copy_file_range.rs":"b880f1686c1a48f49e7549bfb1bcfc448db432b80ba4c8550f4eebcbc30755b3","src/fs/cwd.rs":"10f8bc2354151a383ec2d225b72990e4d3c81d711817614acfe4620295b8b5c5","src/fs/dir.rs":"c1567c8420bffffc92628da80c2334e9b647cbb7d286ef5daa9f14a3540d6bc5","src/fs/fadvise.rs":"7231349ba3b750db4527d3b3af5588c447a76fcc8374aeaf6c808bb04e3ebcc6","src/fs/fcntl.rs":"c6beed70a0a6a66acc82d9e6d6b14908a3bf6d352940f5d5cf008e6f19f322d9","src/fs/fcntl_darwin.rs":"a8e5b53914138fea9db62d486aad6a96159bdb75f4670c2ac519ae7f6dcb1552","src/fs/fcopyfile.rs":"4c41bb477fc262f108a79b724fce69a938d87293573327c8bcae8d7bc6931f88","src/fs/fd.rs":"eb8064a06b5b3e2fba4a18bd2a51ab5455c64a30123ed4b442e087de40ae0acd","src/fs/file_type.rs":"42dc46831af066ff4df1009626a962e4e014c6e0782e358224bf485b4dd52708","src/fs/getpath.rs":"85712f58fabef750ccaf8c256a0ad8dd3579e5a40c8eabba8bfc0ec6f59995c6","src/fs/makedev.rs":"1ee9e56ceb3f081764cbffb2a50df4fe70b15c874ad0264679b6c096f0962282","src/fs/memfd_create.rs":"564732f58d3eb529fa9b67b8b311c1a1762ce2f13e6ee58b7fd344e647ac13a7","src/fs/mod.rs":"3e3bc020f3d2c93fb86ee8cafdd2c6b6ca5fb1ec6b3d9c67615023477151bb9c","src/fs/openat2.rs":"ece04e9229ab634837a6ccc2d4fd14e9967f39ae4fe29c3616ea6eaa1713b153","src/fs/sendfile.rs":"11e1c067f442962a3a7b9dc39362b57c45c912c612851fd56aea4cfae3092269","src/fs/statx.rs":"1c74d7d1cc0744f4c1f1ab2e9de189b49861740b309143861b0b25daaedd7f6e","src/imp/libc/conv.rs":"a62a08ab930833d605ab81384b454e7fc01c5060bb3fff5717554949a10917b0","src/imp/libc/fs/dir.rs":"83a4a60b9e5ce68e39c9f8a5e0974944b7589a13d9718fcdd0cad607c26bbb0d","src/imp/libc/fs/makedev.rs":"2213273074906d2c71a3bd2033fad1828fcbb71a5ec4fd416b7f6345fa9912d2","src/imp/libc/fs/mod.rs":"00ba2c415cfb1f23128307edd108d7638d8e03317ce7d59f485451b814ddbbc5","src/imp/libc/fs/syscalls.rs":"f53ba484f9ac89ae4e2d93acc99771677eebf4f711edc8ab2e762e0ffa910ac2","src/imp/libc/fs/types.rs":"1ffc14e0ca66908491b5b7652db4cb6d8d8c16769f1dcfa506c73117b948fa3f","src/imp/libc/io/epoll.rs":"e498add7e93a7f1ce8793b24dafecbdab7e0968760c32bf2cccb811d542fda4a","src/imp/libc/io/errno.rs":"9e4aad81b3fd6d7b4afbd6a64638a8b07da715c67f21405c7e53a3003ab96e6b","src/imp/libc/io/io_slice.rs":"22b034b07e6db028bd4f7cb423fb0bf4c2d4e852a44c68f5b4b4c9a327a533ef","src/imp/libc/io/mod.rs":"a76e0071a887a6bdb1a3edc4887f91889d4beab1426e73417958257467f3c602","src/imp/libc/io/poll_fd.rs":"71c83405affcac8a4a7d4339cf71add4f3ccc2f3ef72cda835eec96f5a115cd6","src/imp/libc/io/syscalls.rs":"82e6ce8ca531c290d8da7901b1622e8c6e56866731ab78bb2b465d6184197a7d","src/imp/libc/io/types.rs":"7cdd0354ca7443d2eb1fa9aa335d6981b3bab7ef2d6e34c312529befb9dfbf6d","src/imp/libc/io/windows_syscalls.rs":"741f524b384d59e703b278739563ab04273dbb48c062349353dd9b7cf9ed2332","src/imp/libc/io_lifetimes.rs":"2bc5f59216136c74a72e208ac486c662451f23e6d72689532a7721c397f8a024","src/imp/libc/io_uring/mod.rs":"2c6478857a0751625edabd61acb841819bfba1093b1faeded15693c805d84952","src/imp/libc/io_uring/syscalls.rs":"cd5fb63023f8a615ef9aec699fd15f3d993a7c91467f00f5fdb3e93aab201661","src/imp/libc/mm/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/imp/libc/mm/syscalls.rs":"563d2fe119968b85c64b5765caf10aa252765027c8f2d7dc393503233fa3eecf","src/imp/libc/mm/types.rs":"1fcfda95f1e26c766da6c2778829e2dc21d9071ab6666c68d7975723c281ea5b","src/imp/libc/mod.rs":"2ec1e54673eda7ada51e4039ca5312786db9cfe401b5bcab3a70a79cea32ab0d","src/imp/libc/net/addr.rs":"b158799745f833d28397d5ce1253419d4f78b8e4ba61c7b6710fa5f7d51ef7ce","src/imp/libc/net/ext.rs":"d4be1c18d597dbaee64fd5771358ff7a7fdc2a6a2d11972692a19a19a91a80c5","src/imp/libc/net/mod.rs":"772c788c60141e41044b59c4812c4208f52838da1effe1d476ab1d99304d9f9d","src/imp/libc/net/read_sockaddr.rs":"b97728bbb759910a8af699d4456df5c92ad3c58df18180d0c93bebc4349ed981","src/imp/libc/net/send_recv.rs":"1d9376d8f481d3c6b5bfb048e7471368fc15f5c861d95c89e1368fe36928fdab","src/imp/libc/net/syscalls.rs":"e138bec0fb988c850e3ae3f0ce4f39a51943dd502276246b30bf0815baabf46e","src/imp/libc/net/types.rs":"87c0de2e72008df7039ac429f479fb5fd58db9a686c5e3fc1a12f04dad48bf2b","src/imp/libc/net/write_sockaddr.rs":"77b43e57d13a4bba1c9aaed5c19685a85bf8624190cd582672c36b0692602016","src/imp/libc/offset.rs":"fd50f582675b61dd1966a831e3bf1063469012d3aacc839633bc27ec57b06bb0","src/imp/libc/param/auxv.rs":"90c71482be3c378c1de08af28117ee0b1e86fca738d81101612672d7607fdf75","src/imp/libc/param/mod.rs":"5234b8f1bcb886cca6ea003d411d75eaeebe58deedd80e3441354bf46ed85d4d","src/imp/libc/process/cpu_set.rs":"9c0734ac8f07431e0ad704ca5bd749c9fba25d295c8ee59dd92437c0d6fa05b2","src/imp/libc/process/mod.rs":"45a9979d6bc7c669ffe212c55ffbf6ea8f4bdb9a711c894b9e93b52a05e611d7","src/imp/libc/process/syscalls.rs":"eac779d8ae7529c8e7c3e66d1eb3e127cbc7497850d756c9968a5bf1116c2c42","src/imp/libc/process/types.rs":"516ba32a547b46a8e80ad20d4a17bf24a00bff0b69b74f56df119f770f3dfff6","src/imp/libc/process/wait.rs":"47862cd801bb2e0b4f98a48d6755fb263014675896fd888eb500866ba35b2ba4","src/imp/libc/rand/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/imp/libc/rand/syscalls.rs":"dd675f045e4f18ae57db9a67f95c67a3f0d14d3b8df22907c4e80ca4b611dd43","src/imp/libc/rand/types.rs":"8a840167af1454d1399c1defb254e9a626ab46d00981e9c7360828be6ac45b08","src/imp/libc/termios/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/imp/libc/termios/syscalls.rs":"19ec1fcad6a8262ff00bf2da1e504bd4020477aa37a3cbfdd6eaa9d39a539b91","src/imp/libc/termios/types.rs":"646552053670ea8b77b024b6eaa2024fb5f70ad1677e11a3e54df5f191f39aac","src/imp/libc/thread/mod.rs":"0de5f67a684b9fd7628d3009d2ea5fd51b8770e8b387eed14f59152157844287","src/imp/libc/thread/syscalls.rs":"53b2ffe0d16a01c98e1b65a40754cf994733b06a04df584959b952e558ecab06","src/imp/libc/time/mod.rs":"38563ea68829ca5a4b1b0695ac8a5c05718e85bdc88a36dc805efdfce45d3909","src/imp/libc/time/syscalls.rs":"abfbc3dedc61bb3037a7df7d867a63f63711553f358e52a3d9592f9a757097a3","src/imp/libc/time/types.rs":"09a6332f36a1a65dc0dbb0cf55dd3e74d8d610b5a8993a723afa54dce2c8ba05","src/imp/libc/weak.rs":"eba805bb69e9017a9969354269ace291fccfebc35278faf6c7b39578e0bcd1b1","src/imp/libc/winsock_c.rs":"34b26b3fe14720e4c66069c2c1c3daeb632ac2b1750bb1798243bb4efc26573b","src/imp/linux_raw/arch/inline/aarch64.rs":"6b525ba80c295111e47b1dbe5fa77d8505348b61ea2afc9a7f17b315b56919ae","src/imp/linux_raw/arch/inline/arm.rs":"371525cf45f74928b84f2f38bad78967c461c123842106fe3942927485b3e2d0","src/imp/linux_raw/arch/inline/mips.rs":"34197d3900d31e976810b730ae1561044804acec484db7dfc507c64ffbfe9916","src/imp/linux_raw/arch/inline/mips64.rs":"582f4fbc7124dc3521473d9f4a0864ffafb7a9b4616df9b619cb4c9723cacc1d","src/imp/linux_raw/arch/inline/mod.rs":"4d0eace2ef2821e97f694326757ec06970c2b9f02afe95a989db27e7f8162cc9","src/imp/linux_raw/arch/inline/powerpc64.rs":"b5991ed219451392000421fbf3fdcb2680a2375011941522455f1279a5edf71b","src/imp/linux_raw/arch/inline/riscv64.rs":"f2018fc2624ea814fe58d8ad8ec5f47431fc651f5441a429b3d57eda1b4de2e2","src/imp/linux_raw/arch/inline/x86.rs":"3052fb3e24e310bd6e39b9a01fb6c8f5562dcee52c46cca65f91d5d4f4eec111","src/imp/linux_raw/arch/inline/x86_64.rs":"fca7d3b64cef714a9a79db2d725381457347262262414798ad5863082739b812","src/imp/linux_raw/arch/mod.rs":"3ed41804d3db006be712e97fa40927bdbea934cf77760553ffc9e9dd376d0531","src/imp/linux_raw/arch/outline/aarch64.s":"84f066b6fe3cf25ed61c7aa420408c6d5a0b33a7c91b748ed81e47737567975f","src/imp/linux_raw/arch/outline/arm.s":"fa266bf9f4533da1e96c27c4ae5418c86f44074ac0c6afcff0404738e11365da","src/imp/linux_raw/arch/outline/debug/librustix_outline_aarch64.a":"2be1d64488c0a02c9777e0defc3e9bd47839da3982b5e790b02160d423366431","src/imp/linux_raw/arch/outline/debug/librustix_outline_arm.a":"a3aefaa54bb7384dcacb04e47c4c726bcafb331f993fbe7051e73ce4ea6b6301","src/imp/linux_raw/arch/outline/debug/librustix_outline_mips.a":"95e8393bf38ee28e9fe911eb142deeb1af1d48744692a59dba166da695a2217c","src/imp/linux_raw/arch/outline/debug/librustix_outline_mips64.a":"825207c9ce2d7bca5ab424d1017df7412d3ef583478ca6f6e7a5274feffeb524","src/imp/linux_raw/arch/outline/debug/librustix_outline_powerpc64.a":"0889c12a2345e476ac6185d27a592cc79da75dc2937bbe83267a0068c549b4e8","src/imp/linux_raw/arch/outline/debug/librustix_outline_riscv64.a":"1e1ffad421ad95a79222a293c2e2b791dc36b4a3ceef69d245d02b805f6f7520","src/imp/linux_raw/arch/outline/debug/librustix_outline_x86.a":"c9dd9bcf5dd3513dacdde072152489f4a29824bfaa198ac026ec04a70f3fb73c","src/imp/linux_raw/arch/outline/debug/librustix_outline_x86_64.a":"f638a09b8aef86c11a5a6bd8ff3934f07890155ce6fbff381273ae48c1f4ab89","src/imp/linux_raw/arch/outline/mips.s":"e265e8fa0b9785a9f2779d6ba70ce982b954b802862b0026dc70fd79b12968bb","src/imp/linux_raw/arch/outline/mips64.s":"c79de202f0eb00e2d9cf1fce2b9a2cabfe4ff2f5cc1476bcfd6c3d139570d447","src/imp/linux_raw/arch/outline/mod.rs":"d1429a7d6a5b27a2ccdcf79bd8a27814eecd6b3e149105950fe88d976ba147ad","src/imp/linux_raw/arch/outline/nr_last.rs":"1639aa5267da1ad668f98f502710e6896f945baf4f780f05810c2a194e924443","src/imp/linux_raw/arch/outline/powerpc64.s":"0847fa3f160846ee02771550667913734ba9773e2221f2279c4f296d6f5b7bd4","src/imp/linux_raw/arch/outline/release/librustix_outline_aarch64.a":"fa8d31702cafb24d9799c162d3319c522892e91c58fbbff2b09950a0fa81b46f","src/imp/linux_raw/arch/outline/release/librustix_outline_arm.a":"0f7c8c5c02d5329d884f800da70aaf6b5b67c14000b12afb708f3e4758aa1f7a","src/imp/linux_raw/arch/outline/release/librustix_outline_mips.a":"c9254760fa993e88662c5e1e8911d994f29e203b37a0fc9b550be193125f5031","src/imp/linux_raw/arch/outline/release/librustix_outline_mips64.a":"224f9ac5196833491bee67fd287a53b7e88111731e2eaaa3ebefba31faea373b","src/imp/linux_raw/arch/outline/release/librustix_outline_powerpc64.a":"1f04e44c3d863bac066520c787444c314f2aa2f8d8d3cae38990ecc008b9b6e1","src/imp/linux_raw/arch/outline/release/librustix_outline_riscv64.a":"465b6631b33632f4a6aca32b04134cd07993cd1bb55405a080157829d7396373","src/imp/linux_raw/arch/outline/release/librustix_outline_x86.a":"380aa7c802be2795471407d438e3da768df9bdc7340cc448d3a91b2d123dbf19","src/imp/linux_raw/arch/outline/release/librustix_outline_x86_64.a":"36f837703d7f0e246b7f596441010fdc1be27e42417af925b6040504c5aa32a4","src/imp/linux_raw/arch/outline/riscv64.s":"ca5303c0c8af6de1f246d658003e270d4e29d6c68dd90c6eee372d045bdf7305","src/imp/linux_raw/arch/outline/x86.rs":"f87a50c1eea6956a4d6b454b0b3322aa59f688918188cc5c15cfd07595e48efc","src/imp/linux_raw/arch/outline/x86.s":"4604e3b41161802343e2e4c890fd2042098a901d95893ebe4c436f97fd47cad3","src/imp/linux_raw/arch/outline/x86_64.s":"a530084cd42ad8d4b2d36526f4e04f45a6e29ea49882e2c561ac2eeac16272bf","src/imp/linux_raw/c.rs":"f112bda3f89c5859f9130ef1a9de1000054af7992073c20ac230230610a29a6e","src/imp/linux_raw/conv.rs":"cbe92c6a8f181bcd4b3678cd24b3ee65c4625545dda290c5d35604aaa7120aca","src/imp/linux_raw/elf.rs":"5be25de1b9be04601573c704fd9deef62f86b42be5e70d241a9a87ca72a56a07","src/imp/linux_raw/fs/dir.rs":"aa2e68489d0efca8cf7028c140aaa7dc19f8228beab78700aa057df7c62cf08d","src/imp/linux_raw/fs/makedev.rs":"c6b4505c4bcbbc2460e80f3097eb15e2c8ef38d6c6e7abd78e39c53c372139e2","src/imp/linux_raw/fs/mod.rs":"2a7db3cf1b3f9afd0044a4329797f0f255d2eb4c5161fe99c1bd70f10bb72dde","src/imp/linux_raw/fs/syscalls.rs":"a853513369b9bc7cd5f94b514bef8df96f010e1efda972fb23bef5d8c2ed5433","src/imp/linux_raw/fs/types.rs":"e99daf778002b98644428b8a6fd129bfa8c6499ff1d3c2f4b15c40a347446592","src/imp/linux_raw/io/epoll.rs":"894134fdff9c6e3b3e3b5fbd1b51a978ad9b0dd05dc975b46237e446cc585cc6","src/imp/linux_raw/io/errno.rs":"c972e22a4ae9cc0ad8c8d3407a243c132b1b448eda38f9c2ef3e6e256c99d511","src/imp/linux_raw/io/io_slice.rs":"5ba992f3fe701184841006588b35f2452156b73e3bef9e07460e4b1f61ac889f","src/imp/linux_raw/io/mod.rs":"6ea805b91d571217c9649364121d0824bbdf4635b36c9150e5968fbeb75c0892","src/imp/linux_raw/io/poll_fd.rs":"9f5a15c80094cc3334acd171c0621d033b44d5d9a987a57acbdcd62cb17d871b","src/imp/linux_raw/io/syscalls.rs":"7c6504d3990d0012cec0ab85cde361719fa4b0c65a8707a9e6c26a240b042e44","src/imp/linux_raw/io/types.rs":"230462d5bec3e0f9373d231899aebac6f7a796d59634700b12a57f0b5f964a33","src/imp/linux_raw/io_uring/mod.rs":"2c6478857a0751625edabd61acb841819bfba1093b1faeded15693c805d84952","src/imp/linux_raw/io_uring/syscalls.rs":"e0a02f6d90bdc82952046d805a8e9ed2d842ac276d0b6d02bd3c2a1f55db6e60","src/imp/linux_raw/mm/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/imp/linux_raw/mm/syscalls.rs":"6ef85f7dc389b8886840c2acdcb0e58fc8f81f6fa58929ae0ec03c8236f5a79c","src/imp/linux_raw/mm/types.rs":"a5d0ea04a85df5e196d68a8524c4325963c7b2ded3d7d48713c8e855273b60d4","src/imp/linux_raw/mod.rs":"9fd16496692a41767bba186a655e70d10d3c1c67a15acff9adb49f0898f3d12b","src/imp/linux_raw/net/addr.rs":"b439d61da1356708987bf7de3dcb44ba45d58dbf8b2db1234b0fdcd88365078c","src/imp/linux_raw/net/ext.rs":"25440556ff6f67842b286df557dcfb1259836ae523bb02c05960144a8b364a80","src/imp/linux_raw/net/mod.rs":"a03a3756141e47185ff5f55f7ed6e044776129d6c8aa3f0bd1d3a87582a98763","src/imp/linux_raw/net/read_sockaddr.rs":"0357ae643c384b08578aa0b148ac9b236953da9b36b2e387a40d5b87ae9eccef","src/imp/linux_raw/net/send_recv.rs":"42834cf8148abd02021115a61d57b23bb323dd8ad0d1b9a91d17fb8f7defab01","src/imp/linux_raw/net/syscalls.rs":"160eaeaef2d8f530494da261e01f55adcef6bd5bb9b73de5d7f79f20b4d342f9","src/imp/linux_raw/net/types.rs":"c61b689d7f4b9b68d065935d70926d47b5ac7246b2fbe4f20d144a0c2f417fc2","src/imp/linux_raw/net/write_sockaddr.rs":"ec0bf20a354cb86e2b5646bfc79297a378f11fcdf5641c16e4dd13e305011dc6","src/imp/linux_raw/param/auxv.rs":"6834154a21a134aa446a2f1c6ede0631daec2cb9d89254e8734ad4dc35c4e08c","src/imp/linux_raw/param/mod.rs":"5234b8f1bcb886cca6ea003d411d75eaeebe58deedd80e3441354bf46ed85d4d","src/imp/linux_raw/process/cpu_set.rs":"2c996e58b556d7528885bc5a8477846a60d0086f812364643db0d2ee6e99d9e4","src/imp/linux_raw/process/mod.rs":"fb393c70a9c63ef9a6bf1fb5a2dc94f07d6b0b6987cc5231c15c607015dafd68","src/imp/linux_raw/process/syscalls.rs":"177430a8c0388e8843a4d9ba360aff7f6dc4c27dbe393fa4c6a844595ef505a1","src/imp/linux_raw/process/types.rs":"fba10dc8ca9eaf4d481cb82bd1540cf5c05620533c44f917c09a22ea55ef408c","src/imp/linux_raw/process/wait.rs":"81e20506feb1e6f90a1fe0cc01768d380e11e7f8afe5212e353030835dba2408","src/imp/linux_raw/rand/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/imp/linux_raw/rand/syscalls.rs":"cddee8ba4026d140d4b76fee4d83f4e4613f7c8ecaa20a33fa1329ce6cc9f88a","src/imp/linux_raw/rand/types.rs":"271416d5241d70932b8a17f3b67eefd1b9c360f217f807de3d73192e9b620552","src/imp/linux_raw/reg.rs":"f9ab26b045150894b98c741f9e80ac2734bf7598f5cf166ab080938febe7af20","src/imp/linux_raw/runtime/mod.rs":"b2cae8cce3822c3c92942f06ea0b68464040dcac33c6f0f7ee392c6269993347","src/imp/linux_raw/runtime/syscalls.rs":"97fac3c6f4687975548b36d0d612d8d77d6769419d46c69e50f4eed48ad3877a","src/imp/linux_raw/runtime/tls.rs":"f307c3a8f0f63907d67842d22c3c0a4ccea039dbaf28caa96518f2546a2d5e17","src/imp/linux_raw/termios/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/imp/linux_raw/termios/syscalls.rs":"462a740ff5b11c0790667dad85121338d5298beaa6c1f714dc6376498b64b66f","src/imp/linux_raw/termios/types.rs":"e2f3f256aa25e807ed05ed566b8b6fcbd2fd6d273dcc199c0eafca2fee78e0f0","src/imp/linux_raw/thread/futex.rs":"e4ca5be060c52538b97df3781d84e2eb4d8241a7f647b2874412bc0fe6061efa","src/imp/linux_raw/thread/mod.rs":"f7132a68c9db1b4a796781b9e8d0ac268a1ddb713e510bfd43425564ec9b39c4","src/imp/linux_raw/thread/syscalls.rs":"9cfd86d7f0ac0525276780f60d257bb9c7247b1c796c83bbee6c42ecb22ff1cf","src/imp/linux_raw/time/mod.rs":"672724f55b7b7be6a7452bb1cc2d28b5f0aaa840a2856fe363acce624e1beefc","src/imp/linux_raw/time/syscalls.rs":"4d7a88e651c10253fd36218eef123b19d985f383ffb70b890ad4f5999c69be9b","src/imp/linux_raw/time/types.rs":"865d968a6d2903344982f94c69868031cd1fea582318659ca4c69a11d8a53e33","src/imp/linux_raw/vdso.rs":"3e57ba3f17f1a04166230b39b1aac7a5c5387aa2a5168703a4395179a560edb8","src/imp/linux_raw/vdso_wrappers.rs":"a9972929081844ef18da1ffac334b6f866472be132d7e7c95c0002d2db1b43b1","src/io/close.rs":"3b3d1a691b25fc1f1c72a7c695b839780b6c2064e7d94c517073900fc838694f","src/io/dup.rs":"2ee79ce8b234ff6cc06dd8330d8ea2b5f4ffa95c34187bc55a41942cf4a54ec6","src/io/errno.rs":"a2d75f39bdfc559dd90ba13d74e7891e2d7d15dc64c56761a730c8d13e0e83bb","src/io/eventfd.rs":"64cec379d3e5cf87af3fc1366a424d5ed2145f4cf4436fee924ec158ab060ba3","src/io/fd/mod.rs":"a1eab9ce9a2c4454053afdfd3f3705e4cb971e94cc453e4f13690f2f0d83dc2c","src/io/fd/owned.rs":"d733407758c6e8a6b663515c7827a723ac63bc4d40401b103d4b4a7df04f5426","src/io/fd/raw.rs":"1b33986fc135f247a0891bdd48482ee09b9d05b04d2ac9993bf24443c85b4ceb","src/io/ioctl.rs":"ec6940e91ec39eeb7346c49cf2fa72624531ccc7910c757cc5291643277e2db1","src/io/is_read_write.rs":"559d7c8fcf279578d9efe8c67d3db5d23761544a885409117f53558a5ec9c29e","src/io/mod.rs":"ebd5cf558103710dab169fcdd77842818e573ec47fe12e5626fd0f4ef51c1830","src/io/owned_fd.rs":"69cccac3c1cc3a52c20a714bb56c14b2ddf5766652eb09b2da1ceb82ad73665c","src/io/pipe.rs":"840390696389df7e57aba6172b932aede6ea5cdec456407dd0ba954f0677d472","src/io/poll.rs":"1f10bafe78c9fec3b040541e29b84047c2fe1a98ca16fe4fc258f2d63e9f2a0a","src/io/procfs.rs":"2c974415ce34fecfccddf88f92e5040877630c10871d9cf2f031db6634b8bd80","src/io/read_write.rs":"cde17bc43767621a264b757597d13f05df35d717902e3e344bd59e76a8b8fe00","src/io/seek_from.rs":"16072918edbb97e7ac92a0b38bcf0781ff9e968f77661df7778fa0154d2a105e","src/io/stdio.rs":"4aa1d46780edca3aec48875237a57e852f53943b209a62105b7377ad34618e2b","src/io_uring.rs":"7671bec00805cce7b6e5bf3901049d7509e5cc6bedecba06237e89ac7d95a878","src/lib.rs":"f3a80816a1cf382262da37903d223bf244280386a114241f726a8e4707810374","src/mm/madvise.rs":"b29247b66d2a976c49e336279882249285f9b27f6f30ee525d12d525799bd0c1","src/mm/mmap.rs":"0a4eae3d6e884eb963dccc9015849e1ba731e0a5a0acbdd90372136a70569f9f","src/mm/mod.rs":"92d2cb7e8e27b8e6bf2e18e29137aa249935f9ae97ee48aa30fcbb1acd0f4b6e","src/mm/msync.rs":"ca17288060951768990cbf565e4e653e75460934915e4f853978efd1f46864f4","src/mm/userfaultfd.rs":"e41f459094b6dcdad1d78e65f10089cfd5d8a835a95355cde1416e0fdeacabb1","src/net/addr.rs":"0cd121bea50d8937006a8d469e3cd323a9c8d4f17bfb1945877af5be5410b3ec","src/net/ip.rs":"ebe5c42ed6175188bb1d8237d9a0790a32ee200ee6eaceafe470c46be4f882a5","src/net/mod.rs":"cc99751c260f63d1d98bfd26c08ed71cb7fb1f9535c98af75965be25c81a1cf5","src/net/send_recv.rs":"96aef488ef4bd8a4ec9935b19fb2e52803829fab81739080f9198fd5e4bda2bb","src/net/socket.rs":"55356915bfa5d7287cd85decbbd25103b48ca37eb575e79e93259111ae470791","src/net/socket_addr_any.rs":"9a3b764acce0c100ad3e1c9b261b4e02572d7371e81cc0fbaab7b92de3ec5236","src/net/socketpair.rs":"d182f30242bfedd7126456c9dafe857edc9631067cef3bbdbd3aa82e7e7bc56b","src/net/sockopt.rs":"4872f25587b92e2c63b70d2a9e35d81d1bf2d96e541c5af2573e8b94f142e1c0","src/net/wsa.rs":"9bec9297f9982fdf8f9519c339da79b5b339ed50514b59d13ad7d7c139e129a8","src/param/auxv.rs":"f0d6fb69afe647d2358cc6380ceda80b34b7eacecdcc222be84bb15a3ba0fe3f","src/param/init.rs":"448349cd928655068757a8dd4509664d4707d53934e0957ca9dfabae737fefc1","src/param/mod.rs":"ec67d1a4a781764ea2afd9650222c72fbe6499fcb85b473aa9442a5a7214a8e5","src/path/arg.rs":"12385b9129ccd567bb4e158326a1b163cd4efd8d30518965594ae81afdb52466","src/path/dec_int.rs":"753efc79daaaef39a3e9d0c8c0fe6558764dda13ffd3821b93c156b658eedb15","src/path/mod.rs":"513fea21b1ba0226c3c5da769ded06a7cd7abe9f49cec9d165bc62a15da126a8","src/process/chdir.rs":"a9f83bc78714215e0e2fc1ded2b24f2c11c785a68789522e320aa54cf9e72fc3","src/process/exit.rs":"3ab0711958947df06351fbb6ca2bc06bd6f4e782e2e58e175ebdd41e38b6118b","src/process/id.rs":"615ad352b2c41568885df08548b287b6d18022ac7011349eb1aabc4827d89409","src/process/kill.rs":"81ffb9dc56ff3aef9786d1146ef3f16d634dde333e6218018d73b59390171b82","src/process/membarrier.rs":"c05567bf62114725cbecee92fc33cef4792ed874085599c4db8d1aac599972be","src/process/mod.rs":"ddb175818000530be4240ca59c8565bc90a4a22b9eabe677977fce444f82c2be","src/process/priority.rs":"406b98d679364193840245cf1895ffabc1f043b1cdfff6da28f9a340fc7232b7","src/process/rlimit.rs":"dc7914cc7ff084e056f162c51e808b544fe5a614f550daa452bda84abdc672d2","src/process/sched.rs":"10d75f67ba5cfbd62bdd39dda9ea289b5e86c834ffb129b7b0ac810797201b8b","src/process/sched_yield.rs":"4d16a9238e90a88fdac43b47e165bfe872c83f9ff6454ac1451e72d910b19d0e","src/process/uname.rs":"5dfa68eaca2538c342330d1332d36a822f1f11913d7d3e1235732cd2ba432778","src/process/wait.rs":"37089a8d28441099822a60ffc8b04ac98d0c60049b3fa82791f913504d78b00c","src/rand/getrandom.rs":"b7a5054ccc6f3dab01c9ab1eb2eaf4a7b3826afb8ce4e6e7352af8cf730afc01","src/rand/mod.rs":"9bde22996f417e84b54720a584b440b895f19ea4717a7638af98ff4c1485ca98","src/runtime.rs":"b577f2f12fffb4e75bde8e1b5a45e556b2e8ffc285edfdcc8deafd84463f158e","src/termios/cf.rs":"0788c3faf08beb7e907ba585d894b5b7006710eb7463581ecb35eeab1e7344bf","src/termios/constants.rs":"bd76e99f82ee8bfaa6e5f84b0f63127d4e5c4393c5f8669509d1c752130a127c","src/termios/mod.rs":"8f895da97fb833257931c5e77507096b946b1b72f6fea983b66afd5a61282feb","src/termios/tc.rs":"102ffbcee98ad72c02f6e4be77f761594a44b625c56df4c0667e08cb8fd3eba9","src/termios/tty.rs":"d07168a6f7e04e8ee5b070c03f840b83e6a047aba478995780c10ba4ee127126","src/thread/clock.rs":"de463cfa2b5420db29e3cd3b6658a3c36bea2fcc000cba8e2e71013cc0f5e2dd","src/thread/futex.rs":"902ca7274c2b2fe2f5743639697d80869339a03457d549c92e0e40fc1518faa4","src/thread/id.rs":"becf72b98879e853f19b01d69a9e301a4041efafa3587c6786cba35513ed3f2d","src/thread/mod.rs":"b2d79a861c2459b262e7ac7f6cf51f86bfea65961298bc9210c5915e60165f52","src/time/clock.rs":"e8a66ab064565e5682da378212f2a57036e8a94a48f2f4e197fb75f54d43845b","src/time/mod.rs":"9fc60d342eb166729729531cf88a3ec3e8baa71b6788f40aeef1351ee8b6c94d","src/time/timerfd.rs":"9ccf7c47f4f453c6f2405252ba9b6a534c7b5306a5cd237f0819d4f0255ee45b","src/utils.rs":"0341598c878ce8e4e11fd2dbda8aeb04b11a31f9255578c0a781b2a89d2811a1","tests/backends.rs":"05840d02e96c11bbeeb00c8c5afc647872f5650839bebeb973ba34eb5bc23036","tests/fs/cwd.rs":"6227a70d733e17844e43bcba3dff1dcf939f93ca60286298ea1ce392ef0b028a","tests/fs/dir.rs":"fe13dd693695d0737b565e765e60eb86d76d42c15e135481e6c8e79d206c213c","tests/fs/fcntl.rs":"855b3e69f65994268c541eda40fa366e7be46fdd2ce2ac075bdd6795a0a4f3d6","tests/fs/file.rs":"1985d226a4376e3aec86620d1d1aacbf950683ed939db851e6342227f5d7227a","tests/fs/flock.rs":"82ec6477a71b8a9d6942686829dd7ede12514d70cb90b71e2fc48a1286db7476","tests/fs/futimens.rs":"bd9388b8cdd53d6b9b0da7b531d79a37257488218efd68b342b37051497c2b4d","tests/fs/invalid_offset.rs":"bebe8fa9f0555731fc97bd3ecb40489cc41c02a1ac3c48c9c1ea25b201440bdd","tests/fs/long_paths.rs":"449a1a69014f86b4b960db0d52bd104274df16fbff96aaed6d8a37bee627ed09","tests/fs/main.rs":"855ab2ca2a9088a96b29e12f0c8e29982a5c7f30689a0b8cfc04110aad3fedb3","tests/fs/makedev.rs":"41787d477f23bf1c6705d10f834b4c8e973506e3e1146d3e29c95ce7e667df54","tests/fs/mkdirat.rs":"0ec3b9f0e8ed193701e23e95c3f7bcf1e771788361906885ca83af65de71694c","tests/fs/mknodat.rs":"d32ce6ff5b2efcc3166cb0766af9577945493cc9342bb73b5bd70475ab8365e3","tests/fs/openat.rs":"e5471aa6597a9fc591d2e4b11470d5cc68192d1025c71a709662c762aa8298eb","tests/fs/openat2.rs":"7730c44886ce8766d2c035067caf6de13ce1fa4b11ac871375dfa06a99688f76","tests/fs/readdir.rs":"2e2a34da27b5b3cbd1296a3c428a45dce0c3a1ac9414e5002008b21611a3799f","tests/fs/renameat.rs":"021ebfc3375cbf3f8f3823364647a21a60ea1ec784acb1d9fbb6e309484acf85","tests/fs/statfs.rs":"1dab0140a8c8a296b3389868064643eda84c49363b2189c6c1f86392631f7f4a","tests/fs/utimensat.rs":"0aa41d9c40f0c33983590d69d9f4779d17b4ce7bc952bb1b6ae7b506fb1a9de0","tests/fs/y2038.rs":"992377ea3fc22550f33bda36e1debc356728810ca2b679234c86316504ce5982","tests/io/dup2_to_replace_stdio.rs":"0325983ece27c323ab1a04542d56eac26e517425f98eeef607e100f680f50469","tests/io/epoll.rs":"71689f28351b61946bf05a3c89a80c4a85f8e6ddb17bd6370b4ca5cc22cce51c","tests/io/error.rs":"cb9ba3bd5383cfc0f7caef321e70f12ee3ba1072cb8b213b295d0e22bfd7bc81","tests/io/eventfd.rs":"084f9bc64b12bc2fee9b83fd29bfa42dd64d9b710f5b63bd75a37cb6a2f0b760","tests/io/from_into.rs":"8f3e70a9ed0433f24d30d3444596138fdc91f363dedbe9908e0d8b6b8cac6b14","tests/io/ioctl.rs":"908182673e65ae67d02997608efb3c6597379c17fe1fc285183b9cbb94046519","tests/io/main.rs":"d9215378d1d9a91263c2831803e6b691cc5ee5fd3f3dfe03633269741413a9b8","tests/io/poll.rs":"6bf9ad8584c2bbffd0fd35a5f30d564f5399e38cd7d229a41bf2c822a07bf0d9","tests/io/procfs.rs":"313d308dbcb818804185b4f4a1090e87f126a76a3561d4032f4f94a2734790d6","tests/io/read_write.rs":"741ac241604706eb7b5e65d0b70b2750fc7a97b5e193e2f83b9badec60c155ec","tests/io/seals.rs":"63a8d6918604989b261207e5ce5ca9894bd4bfd51a4efc8ae4e1b0df9a12dd4b","tests/mm/main.rs":"189d731e45d8f78c7866e065e62b0ee7cd4d00f707be2cf1e2d2ac03cd64f57b","tests/mm/mlock.rs":"a7a9461ece82e006b52f0edd352d66c1a0c7ed448a985185050186c3c09104f4","tests/mm/mmap.rs":"342e9b03058c01b81c5f94caf0bb8d9804e3aab88ba125cf41335c89e3140db1","tests/mm/prot.rs":"b384ab62497ab431d54c22a1ebadab0d8d82218bd90c301d47b8ffe77646bf7b","tests/net/addr.rs":"735fbc06c637a8ff2a600ba01bb38acea597576f6e1038849906cb6c374885d9","tests/net/connect_bind_send.rs":"5f07265b705e0ea8503e3783183aef9efcca8c22b44d07543601f68c8bd6a90a","tests/net/main.rs":"4e5b3933201581d0f728a2fddf8c606b909c46ecf783df7bff70bf02e759def6","tests/net/poll.rs":"c09bab98177d9d53a011fae59a04c16d4cd3891f5503cac34515a849159e7af9","tests/net/sockopt.rs":"45cd771f8eeec1e4a1b10f15742e5774d801459abd8eed9f169f83415d06e524","tests/net/unix.rs":"8dc0ab6801d3384a9449147830357b272eb109cc444f64afcbbc30265eb07309","tests/net/v4.rs":"f3027b3e1aff90470a175aa8aed7705f5961d6cb5c22f95a222d22dfa73e9a6b","tests/net/v6.rs":"7169e5468627f024a00788589e881f578081c1989cfe545077f5eb424f5013f1","tests/param/auxv.rs":"e59ef1ff4207ef21546046a38215a49be0531f58f440e775643f8b413f9a5e62","tests/param/main.rs":"376e2c6a79931e9b2005686b845bf9d7a76531079c10e0863fcff4cd95a9a2b7","tests/param/weak.rs":"3a7f0a468a6153dabf49fc5bcd735c559d9dfcf8e770194fde71ee266281f68f","tests/path/arg.rs":"2ef95bfa674db279a04927dc986b4ea6da64559d2764c1a3a38b7ef73d6bb656","tests/path/dec_int.rs":"e1f9c55aa5e1a3bb974e80cad0ddc04161b558c7e9b01b0e8d391ce8c78c1aea","tests/path/main.rs":"d9efb138a9f1bad0de19ca0270234eda4209e12c822d88f25dbb8367ad27f05d","tests/process/cpu_set.rs":"f34f4eacf69ce49793506e598f488d640b38a29239101eddc9a06616759883c0","tests/process/id.rs":"c605520595555fa25071dd32a98f7a63c1c3435d04a96048240d9547c2eb2705","tests/process/main.rs":"25dd3e10bb46857eca97ebca1aa080e0cf0a0c73a50c5629da53abfc59109e6c","tests/process/membarrier.rs":"65d74ff51b6f64bbca0b0f5e4e36f7008fcb378e200d8c647f91da572ca15f83","tests/process/priority.rs":"bc67dfeca05ca3b5fb4589dfcde9d7110520006249d523cb12b3e860c42095e1","tests/process/proc.rs":"d47b7c35c24cb98d2219e4c453b96be9648c635bfa996e86d4050da2de157962","tests/process/rlimit.rs":"c23813bc6f3940a67f58264bf3a45d7f5688ed1f5bd020ea0cb00c97f85734f1","tests/process/sched_yield.rs":"1c7b83fdbd91bce384fec844acc0775548ed7ae7b6e3dde255b2f47fdaedb5ea","tests/process/uname.rs":"0c0347a81df9029c04290149256e333dcb45078f0b5a107a192193d7749d886f","tests/process/wait.rs":"e671016a65ab4f0e5711af33bcdeb639ee92f4894a964dd6fde23b33ffb80f92","tests/process/weak.rs":"9f62b62c7b11427e994dd46cd59522a4d879c5dfef39406eb7d78aceb665989e","tests/process/working_directory.rs":"c914188666a966857084bdeedd897c2ab741b0a6819536c9c303dd414d7dedd8","tests/rand/getrandom.rs":"6d2ec8dfbe92ad996bb1fb98dc6760ffee131c6d494f6ed01fa4442df3b4c23d","tests/rand/main.rs":"4bfa0968870ca7712bd5cf07f67c1e380934d414c925070ef381f0edbdd6ddfc","tests/termios/isatty.rs":"b6b9895345c97562c9d3d1a6297652bb7610b06394676a58cd5d334bf7c42697","tests/termios/main.rs":"83e824f25798cc9e2ba975f58f7446517748d5e82ef3e2e95b6c5166665cd1ec","tests/termios/ttyname.rs":"89cbdfeb87ccf060b8b2217f955fd18ec49b6125a51497e404185afcae93881e","tests/thread/clocks.rs":"e22fd56af0ac63a38ddfc7bce29c0820f074e27e4fe20b8270db54ffe4697835","tests/thread/id.rs":"29e24d640045a5eb1e73b72aead0df5b75f7e812503aa86d46fdada66f2967a8","tests/thread/main.rs":"716d0008c297865517a169f28c3789c217b1f735df927b486931c40577603894","tests/time/dynamic_clocks.rs":"74f83e581bce16e45e0fbe512ee939647fe7ff9ae0462b77763077d5cf0dc1e5","tests/time/main.rs":"1641dc6ce6aed219c9c62f917e35c2935494ae2e5098583f72450415ef684f94","tests/time/monotonic.rs":"2ca0292e6d7e6d5bdc8263f053ee1eeaf09f95674e432770ad3e0cf46d0ebf54","tests/time/timerfd.rs":"fab1509bfccda9d867ed436621d028b516d553a4ef75d95221e9e359252d47fc","tests/time/timespec.rs":"a8192c52071b22fed45f5cf80d0a525b29d28e5f69a020d5d6e2dd3ebba3609a","tests/time/y2038.rs":"969a01bf34f3aee83a98d9139a8c739f8dd72bf574a41561a630c1a1e004f08c"},"package":"ef258c11e17f5c01979a10543a30a4e12faef6aab217a74266e747eefa3aed88"} \ No newline at end of file +{"files":{"CODE_OF_CONDUCT.md":"f210602311e3f74b32f46237fd55f4ce36d798e85e3db1432ec667f63a7ffc44","CONTRIBUTING.md":"fb570c76cf924cd75b77bed52b0dbe1e87ce224dc3428c48d98301710dcc331e","COPYRIGHT":"377c2e7c53250cc5905c0b0532d35973392af16ffb9596a41d99d202cf3617c9","Cargo.toml":"2b7e8820633cb8422365f8ac45e1724cfd2202d212a570b1882ecd12600a52c6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-Apache-2.0_WITH_LLVM-exception":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","ORG_CODE_OF_CONDUCT.md":"a62b69bf86e605ee1bcbb2f0a12ba79e4cebb6983a7b6491949750aecc4f2178","README.md":"7f4a59fcebb44a860dfe5c32e85ada9a83e8dcd6214ba46258e13b566b59b8ed","SECURITY.md":"4d75afb09dd28eb5982e3a1f768ee398d90204669ceef3240a16b31dcf04148a","benches/mod.rs":"89a1349fc84e32d3f144daa4b6b41a97b3fd8dfaa71e7e4c0c7b4963f5afb019","build.rs":"1fe75202f65ca5724a5e4a2615efb166304e014e29bc7e11261177be522e7d73","src/backend/libc/conv.rs":"a94f5937ad41d7c13e4554481ea1d8ac10c2954b22e55ca0ccd93dedaeb6f1d6","src/backend/libc/fs/dir.rs":"e4110428c2bca8b35733cce9fde8b53f541bef52cb78380f103264d1ef6cffe3","src/backend/libc/fs/makedev.rs":"b8c7f845c3286b9efd7c6d32e58026b36999c583769e52716544191f765873c8","src/backend/libc/fs/mod.rs":"e749e9ebae31c41a7b22a046fdb6c4462ed9e341e0b441f0b755774e17c01428","src/backend/libc/fs/syscalls.rs":"85545b4786ba417b11ae7c9a4ed5711495d40f22c701d983ceb01c91e83ae041","src/backend/libc/fs/types.rs":"f4bfcf89faf517eae82637202a87b04f75d1b1be21a32e27d65ce143d02d4342","src/backend/libc/io/epoll.rs":"25e89e9dd758b7f33f84c3a8062efe63fdb7c9f9b4ab345d7140dbae590d8a26","src/backend/libc/io/errno.rs":"cef81f24b14891b9e7e0165c1d5f69ca15e0d591ce44c369fe2528d31b5e7d52","src/backend/libc/io/io_slice.rs":"34da1bcc17993318fa93b7e71ff36116044ac12a031963710af84c3ed1bc443a","src/backend/libc/io/mod.rs":"a76e0071a887a6bdb1a3edc4887f91889d4beab1426e73417958257467f3c602","src/backend/libc/io/poll_fd.rs":"71c83405affcac8a4a7d4339cf71add4f3ccc2f3ef72cda835eec96f5a115cd6","src/backend/libc/io/syscalls.rs":"4ad98f71e052b3213bffb9769cf8d79e9de02df596c253d575b08f593f1d297c","src/backend/libc/io/types.rs":"62bbef9f8b1223214b88d1ae54401e550d2e96e853602cde0bfcf553809e9e0e","src/backend/libc/io/windows_syscalls.rs":"741f524b384d59e703b278739563ab04273dbb48c062349353dd9b7cf9ed2332","src/backend/libc/io_lifetimes.rs":"8d5c5a789321d0874a53b5bb6cbc0df866634c7c1ad2a20a7b073e0ad2c85169","src/backend/libc/io_uring/mod.rs":"2c6478857a0751625edabd61acb841819bfba1093b1faeded15693c805d84952","src/backend/libc/io_uring/syscalls.rs":"01f8a4cda26bf4e0e6ba92d9d6aa27b70387e1f3fa5566130edba03bce9bc842","src/backend/libc/mm/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/backend/libc/mm/syscalls.rs":"2f6600bc0d13b8a425e3c082df04c296091ea3c435c7a47a235f302a53034bef","src/backend/libc/mm/types.rs":"af20d737e5994ce40831658cc3a5e20d707a92f76d1597e950ab62a1cc97b95d","src/backend/libc/mod.rs":"524dd7181a289aa4d3bef121f6f3160b215b5bde754812299cd1cd498a9db4eb","src/backend/libc/net/addr.rs":"ce6468d789cfd944cc72d3cd27c29f23c257d8b95a534ea5bf40a26ef1f72ca5","src/backend/libc/net/ext.rs":"201977ad8a8eff409c7e7f5b3d060ffc37a8396b196bbf397a650fdefaff636f","src/backend/libc/net/mod.rs":"772c788c60141e41044b59c4812c4208f52838da1effe1d476ab1d99304d9f9d","src/backend/libc/net/read_sockaddr.rs":"ac28ddcccd8dba65d979709fabac34bb5f459e95fea1877cad2e6b14073414cf","src/backend/libc/net/send_recv.rs":"b22a1f64a8628769e94fa4082ed100b1845f9a01a158c5777836947e7e71d7f9","src/backend/libc/net/syscalls.rs":"64450f0a90bcf5e80f9ac814fb197f3063570f16c6daf215bad3fb292f57a656","src/backend/libc/net/types.rs":"7851d7c258b580ab8c64463dba951668afcb928ed687be6480af455ee5603c63","src/backend/libc/net/write_sockaddr.rs":"140ea379b63e93ae27ca6764a6103204ba31431796484eb91d1829c754e8166b","src/backend/libc/offset.rs":"5a31da74aace8ca17af40c60004f4ffa4caab7df06d833edfb9268fcfc7231fd","src/backend/libc/param/auxv.rs":"7d71f224f7d9c547b6b5e1425cad03466328b7b8ad2a62f49d9e29e075061e43","src/backend/libc/param/mod.rs":"5234b8f1bcb886cca6ea003d411d75eaeebe58deedd80e3441354bf46ed85d4d","src/backend/libc/process/cpu_set.rs":"9c0734ac8f07431e0ad704ca5bd749c9fba25d295c8ee59dd92437c0d6fa05b2","src/backend/libc/process/mod.rs":"45a9979d6bc7c669ffe212c55ffbf6ea8f4bdb9a711c894b9e93b52a05e611d7","src/backend/libc/process/syscalls.rs":"496875ec58336293966db86d8af01e9a2f070598c39895012e75cf3826c3be5e","src/backend/libc/process/types.rs":"48d6a96ef735f7e4842edec75ea37650919e97f62bcd1cefabc0bdf58a93fb40","src/backend/libc/process/wait.rs":"47862cd801bb2e0b4f98a48d6755fb263014675896fd888eb500866ba35b2ba4","src/backend/libc/rand/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/backend/libc/rand/syscalls.rs":"dd675f045e4f18ae57db9a67f95c67a3f0d14d3b8df22907c4e80ca4b611dd43","src/backend/libc/rand/types.rs":"8a840167af1454d1399c1defb254e9a626ab46d00981e9c7360828be6ac45b08","src/backend/libc/termios/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/backend/libc/termios/syscalls.rs":"42fb689f202c22bbd6ad7e286f9dde657f5ac7717743efb2ac7fe6a0e551e9fb","src/backend/libc/termios/types.rs":"314fbb3dbd5a6e05e4ac700ad30c4f4a129fad73493dcf372c9295fd7b5740b6","src/backend/libc/thread/mod.rs":"0de5f67a684b9fd7628d3009d2ea5fd51b8770e8b387eed14f59152157844287","src/backend/libc/thread/syscalls.rs":"0d59679e92b28e51bb2680fd3d0aad0ef768fbdba37435bec3e249031bc61715","src/backend/libc/time/mod.rs":"38563ea68829ca5a4b1b0695ac8a5c05718e85bdc88a36dc805efdfce45d3909","src/backend/libc/time/syscalls.rs":"6d78a726329e8dc45c4cf965aa38989398ea119729587f4729aa363d8dc7d72e","src/backend/libc/time/types.rs":"f48f6baa4b5dc5cfd5b937911d234ed7d94d3c19f6305334d21d72dfcf246c68","src/backend/libc/weak.rs":"89b985e993ecc4e932631814e1b67933ae0127e278042f67926ad2fcfa55f90a","src/backend/libc/winsock_c.rs":"1739787b6a6e878c5d0213ec7a2151c3495589962829711c04e3e8a7782fd846","src/backend/linux_raw/arch/inline/aarch64.rs":"67011427b3cecd29ee716113d952e70d63574c96d1d3ea3c75d46250bde9ca44","src/backend/linux_raw/arch/inline/arm.rs":"7760d51aef17a69a797eb96fd61f7fade0d55bc87ec9a3e77fa6bb6aebaecdbb","src/backend/linux_raw/arch/inline/mips.rs":"d00c84cfdb4e37bdee9a2daa0a7b3298afbb4ebe288702203cb43d9c2617012d","src/backend/linux_raw/arch/inline/mips64.rs":"ab5455c9b2511ba6b67a66873cd8b53bf77471249fd2779d6437ebb4934087b5","src/backend/linux_raw/arch/inline/mod.rs":"48e60ed847f1fe7bcf561d3dd04217589698b576649d17094da98bbfcb826e8a","src/backend/linux_raw/arch/inline/powerpc64.rs":"dcd12314184441f5f7705bea6b829103c7abc9062db366ae5584023a38252a36","src/backend/linux_raw/arch/inline/riscv64.rs":"58a58203e9cac2ed21e4a7b26692c5d56d3c2bcddb3f60a648efd18a02129f3c","src/backend/linux_raw/arch/inline/thumb.rs":"82b88c9a3b6837f28a738cc760fc2403e7014abdb2c35d2bdbc8073235ae2863","src/backend/linux_raw/arch/inline/x86.rs":"459cca47f3300418de9945858ba42009e66e4be3c8da268481f30ae4e815b3db","src/backend/linux_raw/arch/inline/x86_64.rs":"7c893ca306b3b8a5980c525dc5fa23187a0526bc9f7ac637204d88a1d596df5d","src/backend/linux_raw/arch/mod.rs":"2f2e26f5742c302bb44f367ad265de573d89494eae0789fa44b5a39248e354e3","src/backend/linux_raw/arch/outline/aarch64.s":"84f066b6fe3cf25ed61c7aa420408c6d5a0b33a7c91b748ed81e47737567975f","src/backend/linux_raw/arch/outline/arm.s":"fa266bf9f4533da1e96c27c4ae5418c86f44074ac0c6afcff0404738e11365da","src/backend/linux_raw/arch/outline/debug/librustix_outline_aarch64.a":"168fda5b82263fee87661cb146d8de281aa18f6748b372d4e24cfd73a5f3d9c1","src/backend/linux_raw/arch/outline/debug/librustix_outline_arm.a":"2f07acdd80130f32835b64a6e1afa37f62510674c45d5c4c53c39185e1091cb6","src/backend/linux_raw/arch/outline/debug/librustix_outline_mips.a":"82b042b867680439a9a8123439cc81fd597bc2a579d63448c860260bc3061cf7","src/backend/linux_raw/arch/outline/debug/librustix_outline_mips64.a":"1fd5e6e5e6c92dc8990dc3526f4c9340c246b6000c70097b058e5463a16f7c2c","src/backend/linux_raw/arch/outline/debug/librustix_outline_powerpc64.a":"08a7322545cd3ee790f7ee51e459dd289f7dc44ba4f71a94c951c6e7b655e685","src/backend/linux_raw/arch/outline/debug/librustix_outline_riscv64.a":"74ea44d51255593cd95d3298020df872536ec7b967f0d779018482a49966ecdd","src/backend/linux_raw/arch/outline/debug/librustix_outline_x86.a":"aeb926e156f39fb87dc438dcd441cce9f04dec3a083a96344a373ea8900d55f5","src/backend/linux_raw/arch/outline/debug/librustix_outline_x86_64.a":"c77044773834308d327927ac87a1a36a8fc4be333a876c2e356743deb455a24c","src/backend/linux_raw/arch/outline/mips.s":"e265e8fa0b9785a9f2779d6ba70ce982b954b802862b0026dc70fd79b12968bb","src/backend/linux_raw/arch/outline/mips64.s":"c79de202f0eb00e2d9cf1fce2b9a2cabfe4ff2f5cc1476bcfd6c3d139570d447","src/backend/linux_raw/arch/outline/mod.rs":"d97b3657e828a40553677469887b1efab0544812ca592ef359a2d4230a0dd621","src/backend/linux_raw/arch/outline/nr_last.rs":"82d92b9ca8307c19d74ced1ae2c0b31f2a7c5db70fa31fdedb55d38a90601455","src/backend/linux_raw/arch/outline/powerpc64.s":"0847fa3f160846ee02771550667913734ba9773e2221f2279c4f296d6f5b7bd4","src/backend/linux_raw/arch/outline/release/librustix_outline_aarch64.a":"fa8d31702cafb24d9799c162d3319c522892e91c58fbbff2b09950a0fa81b46f","src/backend/linux_raw/arch/outline/release/librustix_outline_arm.a":"0f7c8c5c02d5329d884f800da70aaf6b5b67c14000b12afb708f3e4758aa1f7a","src/backend/linux_raw/arch/outline/release/librustix_outline_mips.a":"c9254760fa993e88662c5e1e8911d994f29e203b37a0fc9b550be193125f5031","src/backend/linux_raw/arch/outline/release/librustix_outline_mips64.a":"224f9ac5196833491bee67fd287a53b7e88111731e2eaaa3ebefba31faea373b","src/backend/linux_raw/arch/outline/release/librustix_outline_powerpc64.a":"1f04e44c3d863bac066520c787444c314f2aa2f8d8d3cae38990ecc008b9b6e1","src/backend/linux_raw/arch/outline/release/librustix_outline_riscv64.a":"465b6631b33632f4a6aca32b04134cd07993cd1bb55405a080157829d7396373","src/backend/linux_raw/arch/outline/release/librustix_outline_x86.a":"380aa7c802be2795471407d438e3da768df9bdc7340cc448d3a91b2d123dbf19","src/backend/linux_raw/arch/outline/release/librustix_outline_x86_64.a":"36f837703d7f0e246b7f596441010fdc1be27e42417af925b6040504c5aa32a4","src/backend/linux_raw/arch/outline/riscv64.s":"ca5303c0c8af6de1f246d658003e270d4e29d6c68dd90c6eee372d045bdf7305","src/backend/linux_raw/arch/outline/x86.rs":"f7e12a0f3fe8e97acb1ade2c9e61d82542f00ad4d8fe684a8dcd9f30fd9ab5d4","src/backend/linux_raw/arch/outline/x86.s":"4604e3b41161802343e2e4c890fd2042098a901d95893ebe4c436f97fd47cad3","src/backend/linux_raw/arch/outline/x86_64.s":"a530084cd42ad8d4b2d36526f4e04f45a6e29ea49882e2c561ac2eeac16272bf","src/backend/linux_raw/c.rs":"f112bda3f89c5859f9130ef1a9de1000054af7992073c20ac230230610a29a6e","src/backend/linux_raw/conv.rs":"ad343251bb09c263ef4c7a280fadceb2f515830873426cadb6f3cd908f0ca8be","src/backend/linux_raw/elf.rs":"a257fbc3f22e4970605cf72a3b301dc2eaee2f5f1b3b0ea434fa192db3c3164e","src/backend/linux_raw/fs/dir.rs":"d54842a373968da54bdae73e10ccab7a8bc19c1bc75b6dca2bb70818c5b275ea","src/backend/linux_raw/fs/makedev.rs":"c6b4505c4bcbbc2460e80f3097eb15e2c8ef38d6c6e7abd78e39c53c372139e2","src/backend/linux_raw/fs/mod.rs":"021f88307e54b391367066ac38c8316064cf1c526350ed1ee1da89475a2c1566","src/backend/linux_raw/fs/syscalls.rs":"e2c9a41b4a63ed3afb022803bff4d991a375d3d9f75ccce311a8ea48c54f52b9","src/backend/linux_raw/fs/types.rs":"de709c7da97a8b15fff7e99f086398056885e3eb397c0de658dd7e68bc78a7b6","src/backend/linux_raw/io/epoll.rs":"71026126ddf47c07ef568a1ee5057c57da41026e80c4787b1b168a54b01a51a6","src/backend/linux_raw/io/errno.rs":"db192a59aa27f3ae34f7c9b246c158c4db173e6ffb03860ce1c5541c0dac31bb","src/backend/linux_raw/io/io_slice.rs":"5ba992f3fe701184841006588b35f2452156b73e3bef9e07460e4b1f61ac889f","src/backend/linux_raw/io/mod.rs":"6ea805b91d571217c9649364121d0824bbdf4635b36c9150e5968fbeb75c0892","src/backend/linux_raw/io/poll_fd.rs":"9f5a15c80094cc3334acd171c0621d033b44d5d9a987a57acbdcd62cb17d871b","src/backend/linux_raw/io/syscalls.rs":"0a161b4f05c05c812fa1e511f3c4a8239c58941519a8d17f2f45a875166f2461","src/backend/linux_raw/io/types.rs":"babdfe55f4f2704559dc38e56bac55569d69c0911a906381c19cde3e1a2b420d","src/backend/linux_raw/io_uring/mod.rs":"2c6478857a0751625edabd61acb841819bfba1093b1faeded15693c805d84952","src/backend/linux_raw/io_uring/syscalls.rs":"c5bb6b93718a8b6db743209701b7f5713dae6514e822875d34609b881f3058af","src/backend/linux_raw/mm/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/backend/linux_raw/mm/syscalls.rs":"647c1846793c386f6babae898686604a4808344ec3e2d1e71071bbfd04079357","src/backend/linux_raw/mm/types.rs":"a5d0ea04a85df5e196d68a8524c4325963c7b2ded3d7d48713c8e855273b60d4","src/backend/linux_raw/mod.rs":"62db302236f6d07f2315956d7515a3347a0d3a08991b8ff308166a6f6d6d0707","src/backend/linux_raw/net/addr.rs":"b439d61da1356708987bf7de3dcb44ba45d58dbf8b2db1234b0fdcd88365078c","src/backend/linux_raw/net/mod.rs":"4ffd3f6f9cad722e4c29b9bad4912a69f521d737b9e637599a1c60436651d4ae","src/backend/linux_raw/net/read_sockaddr.rs":"0357ae643c384b08578aa0b148ac9b236953da9b36b2e387a40d5b87ae9eccef","src/backend/linux_raw/net/send_recv.rs":"42834cf8148abd02021115a61d57b23bb323dd8ad0d1b9a91d17fb8f7defab01","src/backend/linux_raw/net/syscalls.rs":"b989424fa6e181998c1c0c738069d7b98841acee4691454c2bb24588c2921994","src/backend/linux_raw/net/types.rs":"c61b689d7f4b9b68d065935d70926d47b5ac7246b2fbe4f20d144a0c2f417fc2","src/backend/linux_raw/net/write_sockaddr.rs":"ec0bf20a354cb86e2b5646bfc79297a378f11fcdf5641c16e4dd13e305011dc6","src/backend/linux_raw/param/auxv.rs":"da21efc4eb515dbf076e5011b88fb29e694cf17afd44e0f22ee6f182c89ade41","src/backend/linux_raw/param/libc_auxv.rs":"00a44c8593e55326386980c78e38029f43891dc47c7930243853ca6ceab1d46b","src/backend/linux_raw/param/mod.rs":"db21fc1b0ea5568b8649890fa38a878bfcdcf7398f6cf1640176b37bcc6ce990","src/backend/linux_raw/param/mustang_auxv.rs":"9ca4753766736ed6e9b2ec4464c4e9cb64e5f85a4f75fa928725814d1be02a79","src/backend/linux_raw/process/cpu_set.rs":"2c996e58b556d7528885bc5a8477846a60d0086f812364643db0d2ee6e99d9e4","src/backend/linux_raw/process/mod.rs":"fb393c70a9c63ef9a6bf1fb5a2dc94f07d6b0b6987cc5231c15c607015dafd68","src/backend/linux_raw/process/syscalls.rs":"542cea257842929ac2a668a44c045ed1d9893eaa2c4722a5a5a10659a8e40cae","src/backend/linux_raw/process/types.rs":"fba10dc8ca9eaf4d481cb82bd1540cf5c05620533c44f917c09a22ea55ef408c","src/backend/linux_raw/process/wait.rs":"81e20506feb1e6f90a1fe0cc01768d380e11e7f8afe5212e353030835dba2408","src/backend/linux_raw/rand/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/backend/linux_raw/rand/syscalls.rs":"b1d8b2fea0c792bd1e7c24ee59429d178dc0ad442ac817b12c7abcb38d71497b","src/backend/linux_raw/rand/types.rs":"271416d5241d70932b8a17f3b67eefd1b9c360f217f807de3d73192e9b620552","src/backend/linux_raw/reg.rs":"f9ab26b045150894b98c741f9e80ac2734bf7598f5cf166ab080938febe7af20","src/backend/linux_raw/runtime/mod.rs":"b2cae8cce3822c3c92942f06ea0b68464040dcac33c6f0f7ee392c6269993347","src/backend/linux_raw/runtime/syscalls.rs":"6488160051a991e6d385abbf8a08ccd6498acf525906d512b3f89bf3a33fca6a","src/backend/linux_raw/runtime/tls.rs":"c8e6c9a4277a4f50539ab8a666a59b78760ba3426c8cdd3046d8d5ac41a3d1cf","src/backend/linux_raw/termios/mod.rs":"8aa966faf3853d1a93d0ed91f7e5f4a53539b0287b25a5bfe489fa1d07f7cfd7","src/backend/linux_raw/termios/syscalls.rs":"e8a1855b5c171dcef67e98afc3d88092f723a1503d68b8ae9934359c9e2da264","src/backend/linux_raw/termios/types.rs":"f95e3c697156265612b02489cf5bf0e651bc6054ab97c5ba7b59b03b3c664470","src/backend/linux_raw/thread/futex.rs":"e4ca5be060c52538b97df3781d84e2eb4d8241a7f647b2874412bc0fe6061efa","src/backend/linux_raw/thread/mod.rs":"f7132a68c9db1b4a796781b9e8d0ac268a1ddb713e510bfd43425564ec9b39c4","src/backend/linux_raw/thread/syscalls.rs":"ba5c9659dbca75796c9161eb98f9548a7d5e0ba758ee8138f70e582123bdced6","src/backend/linux_raw/time/mod.rs":"672724f55b7b7be6a7452bb1cc2d28b5f0aaa840a2856fe363acce624e1beefc","src/backend/linux_raw/time/syscalls.rs":"184c1208a744e9859e98a7f3e1425db12b00594d2aed42f64a5964e184ef0f31","src/backend/linux_raw/time/types.rs":"865d968a6d2903344982f94c69868031cd1fea582318659ca4c69a11d8a53e33","src/backend/linux_raw/vdso.rs":"400af287fc77ab464489ce4db21c842a52a72977bbec285675f3eca98c4ab6d9","src/backend/linux_raw/vdso_wrappers.rs":"e49159aeef47f1bb1128f7a3c0aba1cc22f6ad7a9bd712ca1278ac2e18c83a9d","src/const_assert.rs":"ff08ab91f11f2ad29883096f4468bd9a65060d5a9e6681e9282bb081f8bdac27","src/cstr.rs":"e5db2aae8fcbad410218696e3e3b3a0da3cc17fc7f64360fc1127bc4e4deff76","src/ffi/mod.rs":"1990dae8190991142bef24220f02b99c96c5bfa7dda2a7974d9dcac265d58945","src/fs/abs.rs":"f30ccd2cea4a850250db931e416762f1d9727ab2839969f3f55825c13eabfea0","src/fs/at.rs":"0f3a7bd25c7dcda26f6327e2cb68307349e963b67ddb80633ee1861c39d91864","src/fs/constants.rs":"4692df5cdcaab06158be44c017b0baf4ec8a98d3636574468cd3bf086ff2ab5e","src/fs/copy_file_range.rs":"a48f5688a4697e0bcd3079f7dc75908e8d044bf479fecd97055c2efb56014671","src/fs/cwd.rs":"c7b98a4f1a49102c22ff587fd5aa9cd9b9bd3ba107d0337c58fa996b5521671e","src/fs/dir.rs":"c88832b426a731b26b8d307fb5bbcb41fa64346e31d700503af8539e492278be","src/fs/fadvise.rs":"beef66ebe1310fb92628240b2cde68f744c78e50f6ff61bb1404bd4868d9cae8","src/fs/fcntl.rs":"30ca419db650dcb266110f421bd89d9ce4a81365a7fc153aa00b2fa003a1d052","src/fs/fcntl_darwin.rs":"07f07b2ac75dc28bc9e08200f72eb95550a87ff3d69c1204f49ecb63a0c4fd20","src/fs/fcopyfile.rs":"ec95929cbbe02cf49233a785e5238931bb107b7903cc5bc95e4231de960995f2","src/fs/fd.rs":"a5f75172d7a304595aa85a8a04ce996272c15d232d60cce991bd4b23a2b491d9","src/fs/file_type.rs":"fefd865f91011f66126213b0994773d99e373b468c31e866002228c98c64ad85","src/fs/getpath.rs":"28f6970fc1bbc37bb35c84724b59eac436ea7407a4522e18c2bdacb1fdd2edd9","src/fs/makedev.rs":"85520b484cb7c15ab71ea1c368578ea3b7e484d82f8510db92b6ce9f7ca341ae","src/fs/memfd_create.rs":"3f1d809e81fe479a82a454a04ea1219a11969d75d0c8b9ddacb09c630a9af896","src/fs/mod.rs":"31527cb94628ae9695409d45efb2eacfd68c2d64baef4f54e0d1b8c90301ebba","src/fs/openat2.rs":"4a95c15dab533a41201b5fa25c8a212956b7571d58cad696bdaf45af8aef96db","src/fs/sendfile.rs":"ac053f03608656bb675228ba61079b774498c0233d17e5816ac72538bb12b70e","src/fs/statx.rs":"88d4c497a185201921884502c78ca5dcec51b0f4768f930dd3681f1d03de46e8","src/io/close.rs":"c59bf90183625da1b1e87975739469440dcddc7b5b2b6ff3a6fd12b2d399a783","src/io/dup.rs":"5dc927cc11bc74bc9d03944261379422ce684945209c16332bd6a9ea64e6c381","src/io/errno.rs":"733f8e9246a319db137740e8dca29d7b3c7474a715e066568b1dc82f0944f692","src/io/eventfd.rs":"163aebe29b5a0e21dd9d121d39c71e82bc6569a4bb658026cfef8ee61809066b","src/io/fcntl.rs":"4174010a26ecba74312cdf900e27594153cc7ea44e03664b21b6e304ec5382b9","src/io/fd/mod.rs":"a1eab9ce9a2c4454053afdfd3f3705e4cb971e94cc453e4f13690f2f0d83dc2c","src/io/fd/owned.rs":"b339000df323764414c71cbe60a7ce0d5e4222cb4c125c7ce40269defaec18af","src/io/fd/raw.rs":"9bcd00be7df3d9f4e6c49ca2d18ef25aee3d6f0ed5ee6b73df5a9beacefb6031","src/io/ioctl.rs":"705add2c90270980523ab31fd224dac4f0fa210d7475b1b3a2f31e1c0e2a818e","src/io/is_read_write.rs":"072b5ea6ddb2339fc6c7e90dfc5a0a5354d926d0f2ac4df06cadafe823425c47","src/io/mod.rs":"6b3d50275cbd5f67f87f17d3130dd1391366762cd27d2bd3f060d5040c366ff4","src/io/pipe.rs":"fabf1cfd5bb3bba5866f530503da9b10afbaa5f0ba33900e1b8cf05e57c3a361","src/io/poll.rs":"41dab55365df215739dcf71815bfc4c2344828d8056ab200564f75210dbc56bd","src/io/procfs.rs":"d7b21900416ca54b9bbe683257dd4da1857f56edc25dd78a954dbafed4914ab9","src/io/read_write.rs":"313aef278466ae546a0989ceaebc41a673f04ba59a21171175bc7ed415c2ffc2","src/io/seek_from.rs":"16072918edbb97e7ac92a0b38bcf0781ff9e968f77661df7778fa0154d2a105e","src/io/stdio.rs":"e9c970290d5a83666966b123755b92454670d4cc6eb03036344ce8ca2844aadb","src/io_uring.rs":"0c6e1531a03e5739de2423b6d49b5bece77b2bc179adf668193abf10f78fd004","src/lib.rs":"2cc7563fad063c99d12e32188adad782eea78976c4ced13b794f8dae780b85c1","src/mm/madvise.rs":"cdc61b39d8abeea184575ca21e14483c335ce373a86007439fad6e72f58e4e24","src/mm/mmap.rs":"988dc5e7ab116218e14c2c387f8eb90ab3031c2d65560a6fd0ff021666919db7","src/mm/mod.rs":"92d2cb7e8e27b8e6bf2e18e29137aa249935f9ae97ee48aa30fcbb1acd0f4b6e","src/mm/msync.rs":"a7f61abe4cb5e96f95ae8229c62b9ecc08382080ed99d76278be7001cfcf82f2","src/mm/userfaultfd.rs":"8073443bd181ff0b3ba4d0b1ae67370b4864035a0c8b4898cd709dc47c518ae7","src/net/addr.rs":"1d84310a4bb7e45f94a10b2cd2000f208db9e28e21bf051ad493261d4e46ae35","src/net/ip.rs":"92fa33205b9d955bf956b152ad283757f3526ec3d7cb9cd958ae460b3949619d","src/net/mod.rs":"cc99751c260f63d1d98bfd26c08ed71cb7fb1f9535c98af75965be25c81a1cf5","src/net/send_recv.rs":"f1fb0b9be750b1949b54054b3195904123cfb96f2ee0ebcedef86fc7175c63e9","src/net/socket.rs":"15840dcdabc1c5fe553f67aa29670f75fae3339b33d019613f2e1d9d573e7b8d","src/net/socket_addr_any.rs":"076d682aa000b2f4421c41f88824533dcee56c2fed874740b3c3cd7b2140564b","src/net/socketpair.rs":"b005b019f8ae0f022fd0e730dafb258606f1f537e4448078175fc192d002dc81","src/net/sockopt.rs":"5276668a1357b704681d33e999a65a91ed684e55024e54b33d55d64843f7b0ed","src/net/wsa.rs":"6e546b42f50a851fc833c57cda76cfb347203ed4b0dea574a3d325bf5a2ebf80","src/param/auxv.rs":"988872f9bec2e12f35765ae8963cbb9535d4acaedd4c9a4d07ced6feb70e0aaa","src/param/init.rs":"671d8974f0d9b82e79076d1f4deabe0273a874a329f74b8aad26e07b86791ba3","src/param/mod.rs":"57ba7d1c16cfc419409cfe73acc253723df79dd0caaf46864939f9aa0a7cfa50","src/path/arg.rs":"e137550750e3bef341579ceb2448c0e50a666ab614a49ad00bb9fdb1e3ead9dd","src/path/dec_int.rs":"6442d2b8fbb648cd4c50eca40daefac9422c306bebeb34de053a8c57989f1dab","src/path/mod.rs":"513fea21b1ba0226c3c5da769ded06a7cd7abe9f49cec9d165bc62a15da126a8","src/process/chdir.rs":"4c63c351e207b1bbefdd7c001e85fed383d5ac2147894d5a09fbd8b302d7c728","src/process/exit.rs":"79f6c0dd45dca0a2bea919ac920c4a56cea23608a345961e4d027aee6624783c","src/process/id.rs":"aab5ef5818e2b16cc4950a92a9c71e72be51a92cbc5778384399ea8ee2a872fa","src/process/kill.rs":"e4b4dcc7e5b2a1e3e68ce03ce9a5dde43108dae4ddbc443488c464194738d06f","src/process/membarrier.rs":"f35aeeb9ab4e1918f9606bf11e8c84db3d20362f01513103ce988d86b5481a7b","src/process/mod.rs":"727cf13a29f1af83949bff00df47d2ae0a92f922d147d5671aa8d0136d3dbb55","src/process/prctl.rs":"884d29ecc07513f02d6aa06a3a011319289829f2977f156ae262dd6ed68f8c6e","src/process/priority.rs":"653a1f525c18ef1de685a3c3307d5214b0d20e61dfd1d4f5065d9c08ebcb4185","src/process/procctl.rs":"5da78c978ae5e9c723efd338b4388ada25b4308ad16c78fdfa34c1ffd86f2132","src/process/rlimit.rs":"b030f3cf585f2eae210703eb01983b937797bdcb9b25a84d42c26711ce7e2221","src/process/sched.rs":"ea8b20942ef09dbcd7a54d8218435129dfece427e4960055bcdf81c997e80f5f","src/process/sched_yield.rs":"6565faa3928b66ddc74a65e893e15edfa4b9be4f7e5f5f68527501a7f6bc3350","src/process/uname.rs":"850f16288261ea8fa92714402a72e89ba2b7880ffea5a9ab9b4c1613b1642ad3","src/process/wait.rs":"6019bd90fd1f58f328099d484e54be49c4327b73bf21e35d071a0e3d1c22dd0c","src/rand/getrandom.rs":"7ad1be6a5b0dc25030bb2434bdc00f3a0c410b7ebc24c136b9839410bf6c5a97","src/rand/mod.rs":"9bde22996f417e84b54720a584b440b895f19ea4717a7638af98ff4c1485ca98","src/runtime.rs":"c6412d171458922f50a85a84900dd3ab7d8ba603b4c058eb9f9d70de52cac628","src/termios/cf.rs":"cb13ee88cba541cbd683c7a5da034a126fd9e09dc6b5f25c9f32382f8318ffc0","src/termios/constants.rs":"16747dc753fa85206953f297067d2eae3184b4e3681a9818f3fee67d206f7e89","src/termios/mod.rs":"284de815b9821350a86fa809e26fb888d2a46bcd56ebc25bfe53c04ddd8601a9","src/termios/tc.rs":"b1d4615a75dbf4d8bd34e705b86ef61a6c1078a099e0f70efaf7fcd86f96b1b2","src/termios/tty.rs":"6cf99ae9753e9faa18a899f17e5bc79d0de9ac1e68bed0e3658e3683062e317b","src/thread/clock.rs":"36b99ea79cfd39b3ec98ddef4625e7d0ba95df9db6d1475a53bc05b40791e00a","src/thread/futex.rs":"4e78c84589b535ca9ca633633696ef212393a98f2890b181acaa8f908fbc5ae2","src/thread/id.rs":"3a50734df74925222632e4b1217944ed3d7dd3075f997f4728b8309e64f49dfc","src/thread/mod.rs":"e7f67653b99329903a0e14d6fcd209acf492a8539071b2174204d401d679d590","src/thread/prctl.rs":"4c44e84060895213d8a2c7889fe3ad6dc214fa904c5e4ec203a78c0ab1e539a5","src/thread/setns.rs":"a2a80df6877f1a665b18a2a338052b1a97f6e13f913b55a690b3834f6afaa038","src/time/clock.rs":"56ab98ae8a637dc94fa70704aed1b9364a6bbdc0f6c16cd6d5f5c424a1fe5311","src/time/mod.rs":"9fc60d342eb166729729531cf88a3ec3e8baa71b6788f40aeef1351ee8b6c94d","src/time/timerfd.rs":"f17092b84553741aa2d2b44c6992b5d2c8c96cc2c2007fc9a2c6b2064485e53f","src/utils.rs":"6ed86e62ac05d6279b664a97fd62878a4c1811ab66a1a2920b169eb74c0c1fcd"},"package":"0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e"} \ No newline at end of file diff --git a/vendor/rustix/Cargo.lock b/vendor/rustix/Cargo.lock deleted file mode 100644 index 0f6929768..000000000 --- a/vendor/rustix/Cargo.lock +++ /dev/null @@ -1,1281 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "async-channel" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "once_cell", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8b508d585e01084059b60f06ade4cb7415cd2e4084b71dd1cb44e7d3fb9880" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" -dependencies = [ - "concurrent-queue", - "futures-lite", - "libc", - "log", - "once_cell", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "winapi", -] - -[[package]] -name = "async-lock" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-process" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" -dependencies = [ - "async-io", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "once_cell", - "signal-hook", - "winapi", -] - -[[package]] -name = "async-std" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52580991739c5cdb36cde8b2a516371c0a3b70dda36d916cc08b82372916808c" -dependencies = [ - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "num_cpus", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" - -[[package]] -name = "atomic-waker" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -dependencies = [ - "compiler_builtins", - "rustc-std-workspace-core", -] - -[[package]] -name = "blocking" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", -] - -[[package]] -name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - -[[package]] -name = "cast" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - -[[package]] -name = "compiler_builtins" -version = "0.1.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e3183e88f659a862835db8f4b67dbeed3d93e44dd4927eef78edb1c149d784" - -[[package]] -name = "concurrent-queue" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] - -[[package]] -name = "criterion" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.8", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - -[[package]] -name = "ctor" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "event-listener" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "fs-err" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd79fa345a495d3ae89fb7165fec01c0e72f41821d642dda363a1e97975652e" - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "gloo-timers" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62e69445763372c8b1bc117771b5a4a67fdcbb2ebc8e4508b92e63ed0ca6550" -dependencies = [ - "async-std", - "fs-err", - "mio", - "os_pipe", - "socket2", - "tokio", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "js-sys" -version = "0.3.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "linux-raw-sys" -version = "0.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" -dependencies = [ - "compiler_builtins", - "rustc-std-workspace-core", -] - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", - "value-bag", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mio" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "os_pipe" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c92f2b54f081d635c77e7120862d48db8e91f7f21cef23ab1b4fe9971c59f55" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "plotters" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" - -[[package]] -name = "plotters-svg" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "polling" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" -dependencies = [ - "cfg-if", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - -[[package]] -name = "regex-syntax" -version = "0.6.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "rustc-std-workspace-alloc" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff66d57013a5686e1917ed6a025d54dd591fcda71a41fe07edf4d16726aefa86" - -[[package]] -name = "rustc-std-workspace-core" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1956f5517128a2b6f23ab2dadf1a976f4f5b27962e7724c2bf3d45e539ec098c" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.35.6" -dependencies = [ - "bitflags", - "cc", - "compiler_builtins", - "criterion", - "ctor", - "errno", - "io-lifetimes", - "itoa 1.0.2", - "libc", - "linux-raw-sys", - "memoffset", - "once_cell", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", - "serial_test", - "tempfile", - "windows-sys", -] - -[[package]] -name = "rustversion" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "semver" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "itoa 1.0.2", - "ryu", - "serde", -] - -[[package]] -name = "serial_test" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5bcc41d18f7a1d50525d080fd3e953be87c4f9f1a974f3c21798ca00d54ec15" -dependencies = [ - "lazy_static", - "parking_lot", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2881bccd7d60fb32dfa3d7b3136385312f8ad75e2674aab2852867a09790cae8" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "signal-hook" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" - -[[package]] -name = "smallvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "syn" -version = "1.0.96" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "tokio" -version = "1.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" -dependencies = [ - "bytes", - "libc", - "mio", - "once_cell", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "winapi", -] - -[[package]] -name = "unicode-ident" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "value-bag" -version = "1.0.0-alpha.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" -dependencies = [ - "ctor", - "version_check", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" - -[[package]] -name = "web-sys" -version = "0.3.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" diff --git a/vendor/rustix/Cargo.toml b/vendor/rustix/Cargo.toml index 95221b2dd..25acf14fd 100644 --- a/vendor/rustix/Cargo.toml +++ b/vendor/rustix/Cargo.toml @@ -12,17 +12,23 @@ [package] edition = "2018" name = "rustix" -version = "0.35.6" +version = "0.36.3" authors = [ "Dan Gohman ", "Jakub Konka ", ] -exclude = [ - "/.*", - "test-crates", +include = [ + "src", + "build.rs", + "Cargo.toml", + "COPYRIGHT", + "LICENSE*", + "/*.md", + "benches", ] description = "Safe Rust bindings to POSIX/Unix/Linux/Winsock2-like syscalls" documentation = "https://docs.rs/rustix" +readme = "README.md" keywords = [ "api", "file", @@ -74,7 +80,8 @@ optional = true package = "rustc-std-workspace-core" [dependencies.io-lifetimes] -version = "0.7.0" +version = "1.0.0" +features = ["close"] optional = true default-features = false @@ -83,19 +90,24 @@ version = "1.0.1" optional = true default-features = false +[dev-dependencies.flate2] +version = "1.0" + [dev-dependencies.io-lifetimes] -version = "0.7.0" +version = "1.0.0" +features = ["close"] default-features = false [dev-dependencies.libc] -version = "0.2.126" +version = "0.2.133" [dev-dependencies.libc_errno] version = "0.2.8" +default-features = false package = "errno" [dev-dependencies.memoffset] -version = "0.6.5" +version = "0.7.1" [dev-dependencies.serial_test] version = "0.6" @@ -123,24 +135,20 @@ all-apis = [ "time", ] all-impls = [ - "async-std", - "tokio", "os_pipe", - "socket2", - "mio", "fs-err", ] -async-std = ["io-lifetimes/async-std"] -default = ["std"] +default = [ + "std", + "use-libc-auxv", +] fs = [] fs-err = ["io-lifetimes/fs-err"] io_uring = [ - "linux-raw-sys", "fs", "net", ] -mio = ["io-lifetimes/mio"] -mm = ["linux-raw-sys"] +mm = [] net = [] os_pipe = ["io-lifetimes/os_pipe"] param = [] @@ -148,6 +156,7 @@ process = [] procfs = [ "once_cell", "itoa", + "fs", ] rand = [] runtime = [] @@ -158,28 +167,26 @@ rustc-dep-of-std = [ "linux-raw-sys/rustc-dep-of-std", "bitflags/rustc-dep-of-std", ] -socket2 = ["io-lifetimes/socket2"] std = ["io-lifetimes"] termios = [] thread = [] time = [] -tokio = ["io-lifetimes/tokio"] use-libc = [ "libc_errno", "libc", ] +use-libc-auxv = ["libc"] [target."cfg(all(any(target_os = \"android\", target_os = \"linux\"), any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"), all(target_endian = \"little\", any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"powerpc64\", target_arch = \"riscv64\", target_arch = \"mips\", target_arch = \"mips64\"))))))))".dependencies.linux-raw-sys] -version = "0.0.46" +version = "0.1.2" features = [ "general", "no_std", ] -optional = true default-features = false [target."cfg(all(not(rustix_use_libc), not(miri), target_os = \"linux\", any(target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"), all(target_endian = \"little\", any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"powerpc64\", target_arch = \"riscv64\", target_arch = \"mips\", target_arch = \"mips64\")))))".dependencies.libc] -version = "0.2.126" +version = "0.2.133" features = ["extra_traits"] optional = true @@ -190,7 +197,7 @@ default-features = false package = "errno" [target."cfg(all(not(rustix_use_libc), not(miri), target_os = \"linux\", any(target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"), all(target_endian = \"little\", any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"powerpc64\", target_arch = \"riscv64\", target_arch = \"mips\", target_arch = \"mips64\")))))".dependencies.linux-raw-sys] -version = "0.0.46" +version = "0.1.2" features = [ "general", "errno", @@ -200,7 +207,7 @@ features = [ default-features = false [target."cfg(any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"), all(target_endian = \"little\", any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"powerpc64\", target_arch = \"riscv64\", target_arch = \"mips\", target_arch = \"mips64\")))))))".dependencies.libc] -version = "0.2.126" +version = "0.2.133" features = ["extra_traits"] [target."cfg(any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"), all(target_endian = \"little\", any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"powerpc64\", target_arch = \"riscv64\", target_arch = \"mips\", target_arch = \"mips64\")))))))".dependencies.libc_errno] @@ -213,10 +220,10 @@ version = "1.5.2" optional = true [target."cfg(not(target_os = \"emscripten\"))".dev-dependencies.criterion] -version = "0.3" +version = "0.4" [target."cfg(windows)".dependencies.windows-sys] -version = "0.36.0" +version = "0.42.0" features = [ "Win32_Foundation", "Win32_Networking_WinSock", diff --git a/vendor/rustix/README.md b/vendor/rustix/README.md index 4c49d1159..8ef865387 100644 --- a/vendor/rustix/README.md +++ b/vendor/rustix/README.md @@ -103,11 +103,11 @@ supported on Redox, such as `*at` functions like `openat`, which are important features for `rustix`. `rustix` has its own code for making direct syscalls, similar to the [`sc`] and -[`scall`] crates, though `rustix` can use either the unstable Rust `asm!` macro -or out-of-line `.s` files so it supports both Stable and Nightly Rust. `rustix` -can also use Linux's vDSO mechanism to optimize Linux `clock_gettime` on all -architectures, and all Linux system calls on x86. And `rustix`'s syscalls -report errors using an optimized `Errno` type. +[`scall`] crates, though `rustix` can use either the Rust `asm!` macro or +out-of-line `.s` files so it supports Rust versions from 1.48 though Nightly. +`rustix` can also use Linux's vDSO mechanism to optimize Linux `clock_gettime` +on all architectures, and all Linux system calls on x86. And `rustix`'s +syscalls report errors using an optimized `Errno` type. `rustix`'s `*at` functions are similar to the [`openat`] crate, but `rustix` provides them as free functions rather than associated functions of a `Dir` diff --git a/vendor/rustix/build.rs b/vendor/rustix/build.rs index f6fa64579..56c6b1557 100644 --- a/vendor/rustix/build.rs +++ b/vendor/rustix/build.rs @@ -4,7 +4,7 @@ use std::env::var; use std::io::Write; /// The directory for out-of-line ("outline") libraries. -const OUTLINE_PATH: &str = "src/imp/linux_raw/arch/outline"; +const OUTLINE_PATH: &str = "src/backend/linux_raw/arch/outline"; fn main() { // Don't rerun this on changes other than build.rs, as we only depend on @@ -101,6 +101,11 @@ fn main() { } } + // Detect whether the compiler requires us to use thumb mode on ARM. + if arch == "arm" && use_thumb_mode() { + use_feature("thumb_mode"); + } + println!("cargo:rerun-if-env-changed=CARGO_CFG_RUSTIX_USE_EXPERIMENTAL_ASM"); } @@ -151,6 +156,11 @@ fn link_in_librustix_outline(arch: &str, asm_name: &str) { } } +fn use_thumb_mode() -> bool { + // In thumb mode, r7 is reserved. + !can_compile("pub unsafe fn f() { core::arch::asm!(\"udf #16\", in(\"r7\") 0); }") +} + fn use_feature_or_nothing(feature: &str) { if has_feature(feature) { use_feature(feature); @@ -174,10 +184,13 @@ fn can_compile(code: &str) -> bool { use std::process::Stdio; let out_dir = var("OUT_DIR").unwrap(); let rustc = var("RUSTC").unwrap(); + let target = var("TARGET").unwrap(); let mut child = std::process::Command::new(rustc) .arg("--crate-type=rlib") // Don't require `main`. .arg("--emit=metadata") // Do as little as possible but still parse. + .arg("--target") + .arg(target) .arg("--out-dir") .arg(out_dir) // Put the output somewhere inconsequential. .arg("-") // Read from stdin. diff --git a/vendor/rustix/ci/getsockopt-timeouts.patch b/vendor/rustix/ci/getsockopt-timeouts.patch deleted file mode 100644 index a9a989325..000000000 --- a/vendor/rustix/ci/getsockopt-timeouts.patch +++ /dev/null @@ -1,80 +0,0 @@ -From: Dan Gohman -Subject: [PATCH] Avoid storing unexpected values for `SO_RCVTIMEO_NEW` etc. - -This issue is reported upstream [here]. - -[here]: https://gitlab.com/qemu-project/qemu/-/issues/885 - ---- - linux-user/generic/sockbits.h | 2 ++ - linux-user/mips/sockbits.h | 2 ++ - linux-user/sparc/sockbits.h | 2 ++ - linux-user/syscall.c | 6 ++++++ - 4 files changed, 12 insertions(+) - -diff --git a/linux-user/generic/sockbits.h b/linux-user/generic/sockbits.h -index b3b4a8e44c..f95747e3cc 100644 ---- a/linux-user/generic/sockbits.h -+++ b/linux-user/generic/sockbits.h -@@ -36,6 +36,8 @@ - #define TARGET_SO_SNDLOWAT 19 - #define TARGET_SO_RCVTIMEO 20 - #define TARGET_SO_SNDTIMEO 21 -+#define TARGET_SO_RCVTIMEO_NEW 66 -+#define TARGET_SO_SNDTIMEO_NEW 67 - - /* Security levels - as per NRL IPv6 - don't actually do anything */ - #define TARGET_SO_SECURITY_AUTHENTICATION 22 -diff --git a/linux-user/mips/sockbits.h b/linux-user/mips/sockbits.h -index 562cad88e2..4d411f7b61 100644 ---- a/linux-user/mips/sockbits.h -+++ b/linux-user/mips/sockbits.h -@@ -39,6 +39,8 @@ - #define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */ - #define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ - #define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ -+#define TARGET_SO_RCVTIMEO_NEW 66 -+#define TARGET_SO_SNDTIMEO_NEW 67 - #define TARGET_SO_ACCEPTCONN 0x1009 - #define TARGET_SO_PROTOCOL 0x1028 /* protocol type */ - #define TARGET_SO_DOMAIN 0x1029 /* domain/socket family */ -diff --git a/linux-user/sparc/sockbits.h b/linux-user/sparc/sockbits.h -index 0a822e3e1f..8420ef9953 100644 ---- a/linux-user/sparc/sockbits.h -+++ b/linux-user/sparc/sockbits.h -@@ -26,6 +26,8 @@ - #define TARGET_SO_SNDLOWAT 0x1000 - #define TARGET_SO_RCVTIMEO 0x2000 - #define TARGET_SO_SNDTIMEO 0x4000 -+#define TARGET_SO_RCVTIMEO_NEW 68 -+#define TARGET_SO_SNDTIMEO_NEW 69 - #define TARGET_SO_ACCEPTCONN 0x8000 - - #define TARGET_SO_SNDBUF 0x1001 -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index a8eae3c4ac..8326e03a19 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -2348,6 +2348,9 @@ set_timeout: - case TARGET_SO_SNDTIMEO: - optname = SO_SNDTIMEO; - goto set_timeout; -+ case TARGET_SO_RCVTIMEO_NEW: -+ case TARGET_SO_SNDTIMEO_NEW: -+ return -TARGET_ENOPROTOOPT; - case TARGET_SO_ATTACH_FILTER: - { - struct target_sock_fprog *tfprog; -@@ -2595,6 +2598,9 @@ get_timeout: - case TARGET_SO_SNDTIMEO: - optname = SO_SNDTIMEO; - goto get_timeout; -+ case TARGET_SO_RCVTIMEO_NEW: -+ case TARGET_SO_SNDTIMEO_NEW: -+ return -TARGET_ENOPROTOOPT; - case TARGET_SO_PEERCRED: { - struct ucred cr; - socklen_t crlen; --- -2.32.0 - diff --git a/vendor/rustix/ci/s390x-stat-have-nsec.patch b/vendor/rustix/ci/s390x-stat-have-nsec.patch deleted file mode 100644 index 1a4562298..000000000 --- a/vendor/rustix/ci/s390x-stat-have-nsec.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Dan Gohman -Subject: [PATCH] Define `TARGET_STAT_HAVE_NSEC` for s390x - -Without this, The `fstat` syscall sets `st_mtime_nsec` and the other `_nsec` -fields to 0. Libc `fstat` will sometimes use the `fstatat` or `fstat64` -syscalls instead, which aren't affected, but the libc `fstat` on ubuntu-20.04 -on Github Actions appears to be affected. - -This can be seen in the `st_mtime_nsec` assert in tests/fs/futimens.rs. - -It's not yet known why upstream qemu doesn't define this. - ---- - linux-user/generic/sockbits.h | 1 + - 1 files changed, 1 insertions(+) - -diff -ur a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h ---- a/linux-user/syscall_defs.h 2021-08-24 10:35:41.000000000 -0700 -+++ b/linux-user/syscall_defs.h 2022-04-12 13:23:25.291064887 -0700 -@@ -2040,6 +2040,7 @@ - abi_long __unused[3]; - }; - #elif defined(TARGET_S390X) -+#define TARGET_STAT_HAVE_NSEC - struct target_stat { - abi_ulong st_dev; - abi_ulong st_ino; diff --git a/vendor/rustix/ci/translate-errno.patch b/vendor/rustix/ci/translate-errno.patch deleted file mode 100644 index 6a4152038..000000000 --- a/vendor/rustix/ci/translate-errno.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Dan Gohman -Subject: [PATCH] Translate errno codes from host to target for `SO_ERROR`. - -This issue is reported upstream [here]. - -[here]: https://gitlab.com/qemu-project/qemu/-/issues/872 - ---- - linux-user/syscall.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index b9b18a7eaf..a8eae3c4ac 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -2767,6 +2767,9 @@ get_timeout: - if (optname == SO_TYPE) { - val = host_to_target_sock_type(val); - } -+ if (level == SOL_SOCKET && optname == SO_ERROR) { -+ val = host_to_target_errno(val); -+ } - if (len > lv) - len = lv; - if (len == 4) { --- -2.32.0 - diff --git a/vendor/rustix/examples/dup2_to_replace_stdio.rs b/vendor/rustix/examples/dup2_to_replace_stdio.rs deleted file mode 100644 index cc8565915..000000000 --- a/vendor/rustix/examples/dup2_to_replace_stdio.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! This is an example of how to use `dup2` to replace the stdin and stdout -//! file descriptors. - -#[cfg(not(windows))] -fn main() { - use rustix::io::{dup2, pipe}; - use std::io::{BufRead, BufReader}; - use std::mem::forget; - - // Create some new file descriptors that we'll use to replace stdio's file - // descriptors with. - let (reader, writer) = pipe().unwrap(); - - // Acquire `OwnedFd` instances for stdin and stdout. These APIs are `unsafe` - // because in general, with low-level APIs like this, libraries can't assume - // that stdin and stdout will be open or safe to use. It's ok here, because - // we're directly inside `main`, so we know that stdin and stdout haven't - // been closed and aren't being used for other purposes. - let (mut stdin, mut stdout) = unsafe { (rustix::io::take_stdin(), rustix::io::take_stdout()) }; - - // Use `dup2` to copy our new file descriptors over the stdio file descriptors. - // - // These take their second argument as an `&mut OwnedFd` rather than the - // usual `impl AsFd` because they conceptually do a `close` on the original - // file descriptor, which one shouldn't be able to do with just a - // `BorrowedFd`. - dup2(&reader, &mut stdin).unwrap(); - dup2(&writer, &mut stdout).unwrap(); - - // Then, forget the stdio `OwnedFd`s, because actually dropping them would - // close them. Here, we want stdin and stdout to remain open for the rest - // of the program. - forget(stdin); - forget(stdout); - - // We can also drop the original file descriptors now, since `dup2` creates - // new file descriptors with independent lifetimes. - drop(reader); - drop(writer); - - // Now we can print to "stdout" in the usual way, and it'll go to our pipe. - println!("hello, world!"); - - // And we can read from stdin, and it'll read from our pipe. It's a little - // silly that we connected our stdout to our own stdin, but it's just an - // example :-). - let mut s = String::new(); - BufReader::new(std::io::stdin()).read_line(&mut s).unwrap(); - assert_eq!(s, "hello, world!\n"); -} - -#[cfg(windows)] -fn main() { - unimplemented!() -} diff --git a/vendor/rustix/examples/hello.rs b/vendor/rustix/examples/hello.rs deleted file mode 100644 index 16ce69bd6..000000000 --- a/vendor/rustix/examples/hello.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! Hello world, via plain syscalls. - -#[cfg(all(feature = "std", not(windows)))] -fn main() -> std::io::Result<()> { - // The message to print. It includes an explicit newline because we're - // not using `println!`, so we have to include the newline manually. - let message = "Hello, world!\n"; - - // The bytes to print. The `write` syscall operates on byte buffers and - // returns a byte offset if it writes fewer bytes than requested, so we - // need the ability to compute substrings at arbitrary byte offsets. - let mut bytes = message.as_bytes(); - - // Safety: See [here] for the safety conditions for calling `stdout`. In - // this example, the code is inside `main` itself so we know how `stdout` - // is being used and we know that it's not dropped. - // - // [here]: https://docs.rs/rustix/*/rustix/io/fn.stdout.html#safety - let stdout = unsafe { rustix::io::stdout() }; - - while !bytes.is_empty() { - match rustix::io::write(&stdout, bytes) { - // `write` can write fewer bytes than requested. In that case, - // continue writing with the remainder of the bytes. - Ok(n) => bytes = &bytes[n..], - - // `write` can be interrupted before doing any work; if that - // happens, retry it. - Err(rustix::io::Errno::INTR) => (), - - // `write` can also fail for external reasons, such as running out - // of storage space. - Err(e) => return Err(e.into()), - } - } - - Ok(()) -} - -#[cfg(any(not(feature = "std"), windows))] -fn main() { - unimplemented!() -} diff --git a/vendor/rustix/examples/process.rs b/vendor/rustix/examples/process.rs deleted file mode 100644 index 49c6b8d9e..000000000 --- a/vendor/rustix/examples/process.rs +++ /dev/null @@ -1,105 +0,0 @@ -//! A command which prints out information about the process it runs in. - -use rustix::io; - -#[cfg(all(feature = "process", feature = "param"))] -#[cfg(not(windows))] -fn main() -> io::Result<()> { - use rustix::param::*; - use rustix::process::*; - - println!("Pid: {}", getpid().as_raw_nonzero()); - println!("Parent Pid: {}", Pid::as_raw(getppid())); - println!("Uid: {}", getuid().as_raw()); - println!("Gid: {}", getgid().as_raw()); - #[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", - ))] - { - let (a, b) = linux_hwcap(); - println!("Linux hwcap: {:#x}, {:#x}", a, b); - } - println!("Page size: {}", page_size()); - println!("Clock ticks/sec: {}", clock_ticks_per_second()); - println!("Uname: {:?}", uname()); - println!("Process group priority: {}", getpriority_pgrp(None)?); - println!("Process priority: {}", getpriority_process(None)?); - println!("User priority: {}", getpriority_user(Uid::ROOT)?); - println!( - "Current working directory: {}", - getcwd(Vec::new())?.to_string_lossy() - ); - println!("Cpu Limit: {:?}", getrlimit(Resource::Cpu)); - println!("Fsize Limit: {:?}", getrlimit(Resource::Fsize)); - println!("Data Limit: {:?}", getrlimit(Resource::Data)); - println!("Stack Limit: {:?}", getrlimit(Resource::Stack)); - println!("Core Limit: {:?}", getrlimit(Resource::Core)); - println!("Rss Limit: {:?}", getrlimit(Resource::Rss)); - println!("Nproc Limit: {:?}", getrlimit(Resource::Nproc)); - println!("Nofile Limit: {:?}", getrlimit(Resource::Nofile)); - println!("Memlock Limit: {:?}", getrlimit(Resource::Memlock)); - #[cfg(not(target_os = "openbsd"))] - println!("As Limit: {:?}", getrlimit(Resource::As)); - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - println!("Locks Limit: {:?}", getrlimit(Resource::Locks)); - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - println!("Sigpending Limit: {:?}", getrlimit(Resource::Sigpending)); - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - println!("Msgqueue Limit: {:?}", getrlimit(Resource::Msgqueue)); - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - println!("Nice Limit: {:?}", getrlimit(Resource::Nice)); - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - println!("Rtprio Limit: {:?}", getrlimit(Resource::Rtprio)); - #[cfg(not(any( - target_os = "android", - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - println!("Rttime Limit: {:?}", getrlimit(Resource::Rttime)); - #[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux" - ))] - println!("Execfn: {:?}", linux_execfn()); - Ok(()) -} - -#[cfg(any(windows, not(all(feature = "process", feature = "param"))))] -fn main() -> io::Result<()> { - unimplemented!() -} diff --git a/vendor/rustix/examples/stdio.rs b/vendor/rustix/examples/stdio.rs deleted file mode 100644 index 9e79d5356..000000000 --- a/vendor/rustix/examples/stdio.rs +++ /dev/null @@ -1,465 +0,0 @@ -//! A command which prints out information about the standard input, -//! output, and error streams provided to it. - -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - -#[cfg(not(windows))] -use rustix::fd::AsFd; -#[cfg(not(windows))] -use rustix::io::{self, stderr, stdin, stdout}; -#[cfg(feature = "termios")] -#[cfg(not(windows))] -use rustix::termios::isatty; -#[cfg(all(not(windows), feature = "termios", feature = "procfs"))] -use rustix::termios::ttyname; - -#[cfg(not(windows))] -fn main() -> io::Result<()> { - let (stdin, stdout, stderr) = unsafe { (stdin(), stdout(), stderr()) }; - - println!("Stdin:"); - show(&stdin)?; - - println!("Stdout:"); - show(&stdout)?; - - println!("Stderr:"); - show(&stderr)?; - - Ok(()) -} - -#[cfg(not(windows))] -fn show(fd: Fd) -> io::Result<()> { - let fd = fd.as_fd(); - println!(" - ready: {:?}", rustix::io::ioctl_fionread(fd)?); - - #[cfg(feature = "termios")] - if isatty(fd) { - #[cfg(feature = "procfs")] - println!(" - ttyname: {}", ttyname(fd, Vec::new())?.to_string_lossy()); - println!(" - process group: {:?}", rustix::termios::tcgetpgrp(fd)?); - println!(" - winsize: {:?}", rustix::termios::tcgetwinsize(fd)?); - - { - use rustix::termios::*; - let term = tcgetattr(fd)?; - - if let Some(speed) = speed_value(cfgetispeed(&term)) { - println!(" - ispeed: {}", speed); - } - if let Some(speed) = speed_value(cfgetospeed(&term)) { - println!(" - ospeed: {}", speed); - } - - print!(" - in flags:"); - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IGNBRK) != 0 { - print!(" IGNBRK"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & BRKINT) != 0 { - print!(" BRKINT"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IGNPAR) != 0 { - print!(" IGNPAR"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & PARMRK) != 0 { - print!(" PARMRK"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & INPCK) != 0 { - print!(" INPCK"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & ISTRIP) != 0 { - print!(" ISTRIP"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & INLCR) != 0 { - print!(" INLCR"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IGNCR) != 0 { - print!(" IGNCR"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & ICRNL) != 0 { - print!(" ICRNL"); - } - #[cfg(any( - linux_raw, - all( - libc, - any(target_os = "haiku", target_os = "illumos", target_os = "solaris"), - ) - ))] - if (term.c_iflag & IUCLC) != 0 { - print!(" IUCLC"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IXON) != 0 { - print!(" IXON"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IXANY) != 0 { - print!(" IXANY"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IXOFF) != 0 { - print!(" IXOFF"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_iflag & IMAXBEL) != 0 { - print!(" IMAXBEL"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_iflag & IUTF8) != 0 { - print!(" IUTF8"); - } - println!(); - - print!(" - out flags:"); - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_oflag & OPOST) != 0 { - print!(" OPOST"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "redox", - )))] - if (term.c_oflag & OLCUC) != 0 { - print!(" OLCUC"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_oflag & ONLCR) != 0 { - print!(" ONLCR"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_oflag & OCRNL) != 0 { - print!(" OCRNL"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_oflag & ONOCR) != 0 { - print!(" ONOCR"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_oflag & ONLRET) != 0 { - print!(" ONLRET"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - if (term.c_oflag & OFILL) != 0 { - print!(" OFILL"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - if (term.c_oflag & OFDEL) != 0 { - print!(" OFDEL"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_oflag & NLDLY) != 0 { - print!(" NLDLY"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_oflag & CRDLY) != 0 { - print!(" CRDLY"); - } - #[cfg(not(any( - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "illumos", - target_os = "redox", - )))] - if (term.c_oflag & TABDLY) != 0 { - print!(" TABDLY"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_oflag & BSDLY) != 0 { - print!(" BSDLY"); - } - #[cfg(not(any( - all(libc, target_env = "musl"), - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_oflag & VTDLY) != 0 { - print!(" VTDLY"); - } - #[cfg(not(any( - all(libc, target_env = "musl"), - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_oflag & FFDLY) != 0 { - print!(" FFDLY"); - } - println!(); - - print!(" - control flags:"); - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_cflag & CBAUD) != 0 { - print!(" CBAUD"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_cflag & CBAUDEX) != 0 { - print!(" CBAUDEX"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & CSIZE) != 0 { - print!(" CSIZE"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & CSTOPB) != 0 { - print!(" CSTOPB"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & CREAD) != 0 { - print!(" CREAD"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & PARENB) != 0 { - print!(" PARENB"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & PARODD) != 0 { - print!(" PARODD"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & HUPCL) != 0 { - print!(" HUPCL"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & CLOCAL) != 0 { - print!(" CLOCAL"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_cflag & CIBAUD) != 0 { - print!(" CIBAUD"); - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - if (term.c_cflag & CMSPAR) != 0 { - print!(" CMSPAR"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_cflag & CRTSCTS) != 0 { - print!(" CRTSCTS"); - } - println!(); - - print!(" - local flags:"); - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ISIG) != 0 { - print!(" ISIG"); - } - if (term.c_lflag & ICANON) != 0 { - print!(" ICANON"); - } - #[cfg(any(linux_raw, all(libc, any(target_arch = "s390x", target_os = "haiku"))))] - if (term.c_lflag & XCASE) != 0 { - print!(" XCASE"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHO) != 0 { - print!(" ECHO"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHOE) != 0 { - print!(" ECHOE"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHOK) != 0 { - print!(" ECHOK"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHONL) != 0 { - print!(" ECHONL"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHOCTL) != 0 { - print!(" ECHOCTL"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHOPRT) != 0 { - print!(" ECHOPRT"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & ECHOKE) != 0 { - print!(" ECHOKE"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & FLUSHO) != 0 { - print!(" FLUSHO"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & NOFLSH) != 0 { - print!(" NOFLSH"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & TOSTOP) != 0 { - print!(" TOSTOP"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & PENDIN) != 0 { - print!(" PENDIN"); - } - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - if (term.c_lflag & IEXTEN) != 0 { - print!(" IEXTEN"); - } - println!(); - - println!( - " - keys: INTR={} QUIT={} ERASE={} KILL={} EOF={} TIME={} MIN={} ", - key(term.c_cc[VINTR]), - key(term.c_cc[VQUIT]), - key(term.c_cc[VERASE]), - key(term.c_cc[VKILL]), - key(term.c_cc[VEOF]), - term.c_cc[VTIME], - term.c_cc[VMIN] - ); - println!( - " START={} STOP={} SUSP={} EOL={} REPRINT={} DISCARD={}", - key(term.c_cc[VSTART]), - key(term.c_cc[VSTOP]), - key(term.c_cc[VSUSP]), - key(term.c_cc[VEOL]), - key(term.c_cc[VREPRINT]), - key(term.c_cc[VDISCARD]) - ); - println!( - " WERASE={} LNEXT={} EOL2={}", - key(term.c_cc[VWERASE]), - key(term.c_cc[VLNEXT]), - key(term.c_cc[VEOL2]) - ); - } - } else { - println!(" - is not a tty"); - } - - println!(); - Ok(()) -} - -#[cfg(feature = "termios")] -#[cfg(not(windows))] -fn key(b: u8) -> String { - if b == 0 { - format!("") - } else if b < 0x20 { - format!("^{}", (b + 0x40) as char) - } else if b == 0x7f { - format!("^?") - } else { - format!("{}", b as char) - } -} - -#[cfg(windows)] -fn main() { - unimplemented!() -} diff --git a/vendor/rustix/examples/time.rs b/vendor/rustix/examples/time.rs deleted file mode 100644 index 3648336a7..000000000 --- a/vendor/rustix/examples/time.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! A command which prints the current values of the realtime and monotonic -//! clocks it's given. - -#[cfg(not(windows))] -#[cfg(feature = "time")] -fn main() { - println!( - "Real time: {:?}", - rustix::time::clock_gettime(rustix::time::ClockId::Realtime) - ); - println!( - "Monotonic time: {:?}", - rustix::time::clock_gettime(rustix::time::ClockId::Monotonic) - ); -} - -#[cfg(any(windows, not(feature = "time")))] -fn main() { - unimplemented!() -} diff --git a/vendor/rustix/src/backend/libc/conv.rs b/vendor/rustix/src/backend/libc/conv.rs new file mode 100644 index 000000000..1e74ea9ba --- /dev/null +++ b/vendor/rustix/src/backend/libc/conv.rs @@ -0,0 +1,222 @@ +//! Libc call arguments and return values are often things like `c_int`, +//! `c_uint`, or libc-specific pointer types. This module provides functions +//! for converting between rustix's types and libc types. + +#![allow(dead_code)] + +use super::c; +use super::fd::{AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, LibcFd, OwnedFd, RawFd}; +#[cfg(not(windows))] +#[cfg(feature = "fs")] +use super::offset::libc_off_t; +#[cfg(not(windows))] +use crate::ffi::CStr; +use crate::io; +#[cfg(windows)] +use core::convert::TryInto; + +#[cfg(not(windows))] +#[inline] +pub(super) fn c_str(c: &CStr) -> *const c::c_char { + c.as_ptr() +} + +#[cfg(not(windows))] +#[inline] +pub(super) fn no_fd() -> LibcFd { + -1 +} + +#[inline] +pub(super) fn borrowed_fd(fd: BorrowedFd<'_>) -> LibcFd { + fd.as_raw_fd() as LibcFd +} + +#[inline] +pub(super) fn owned_fd(fd: OwnedFd) -> LibcFd { + fd.into_raw_fd() as LibcFd +} + +#[inline] +pub(super) fn ret(raw: c::c_int) -> io::Result<()> { + if raw == 0 { + Ok(()) + } else { + Err(io::Errno::last_os_error()) + } +} + +#[inline] +pub(super) fn syscall_ret(raw: c::c_long) -> io::Result<()> { + if raw == 0 { + Ok(()) + } else { + Err(io::Errno::last_os_error()) + } +} + +#[inline] +pub(super) fn nonnegative_ret(raw: c::c_int) -> io::Result<()> { + if raw >= 0 { + Ok(()) + } else { + Err(io::Errno::last_os_error()) + } +} + +#[inline] +pub(super) unsafe fn ret_infallible(raw: c::c_int) { + debug_assert_eq!(raw, 0, "unexpected error: {:?}", io::Errno::last_os_error()); +} + +#[inline] +pub(super) fn ret_c_int(raw: c::c_int) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(raw) + } +} + +#[inline] +pub(super) fn ret_u32(raw: c::c_int) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(raw as u32) + } +} + +#[inline] +pub(super) fn ret_ssize_t(raw: c::ssize_t) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(raw) + } +} + +#[inline] +pub(super) fn syscall_ret_ssize_t(raw: c::c_long) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(raw as c::ssize_t) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(super) fn syscall_ret_u32(raw: c::c_long) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + let r32 = raw as u32; + + // Converting `raw` to `u32` should be lossless. + debug_assert_eq!(r32 as c::c_long, raw); + + Ok(r32) + } +} + +#[cfg(not(windows))] +#[cfg(feature = "fs")] +#[inline] +pub(super) fn ret_off_t(raw: libc_off_t) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(raw) + } +} + +#[cfg(not(windows))] +#[inline] +pub(super) fn ret_pid_t(raw: c::pid_t) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(raw) + } +} + +/// Convert a `c_int` returned from a libc function to an `OwnedFd`, if valid. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a libc function +/// which returns an owned file descriptor. +#[inline] +pub(super) unsafe fn ret_owned_fd(raw: LibcFd) -> io::Result { + if raw == !0 { + Err(io::Errno::last_os_error()) + } else { + Ok(OwnedFd::from_raw_fd(raw as RawFd)) + } +} + +#[inline] +pub(super) fn ret_discarded_fd(raw: LibcFd) -> io::Result<()> { + if raw == !0 { + Err(io::Errno::last_os_error()) + } else { + Ok(()) + } +} + +#[inline] +pub(super) fn ret_discarded_char_ptr(raw: *mut c::c_char) -> io::Result<()> { + if raw.is_null() { + Err(io::Errno::last_os_error()) + } else { + Ok(()) + } +} + +/// Convert a `c_long` returned from `syscall` to an `OwnedFd`, if valid. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a `syscall` call +/// which returns an owned file descriptor. +#[cfg(not(windows))] +#[inline] +pub(super) unsafe fn syscall_ret_owned_fd(raw: c::c_long) -> io::Result { + if raw == -1 { + Err(io::Errno::last_os_error()) + } else { + Ok(OwnedFd::from_raw_fd(raw as RawFd)) + } +} + +/// Convert the buffer-length argument value of a `send` or `recv` call. +#[cfg(not(windows))] +#[inline] +pub(super) fn send_recv_len(len: usize) -> usize { + len +} + +/// Convert the buffer-length argument value of a `send` or `recv` call. +#[cfg(windows)] +#[inline] +pub(super) fn send_recv_len(len: usize) -> i32 { + // On Windows, the length argument has type `i32`; saturate the length, + // since `send` and `recv` are allowed to send and recv less data than + // requested. + len.try_into().unwrap_or(i32::MAX) +} + +/// Convert the return value of a `send` or `recv` call. +#[cfg(not(windows))] +#[inline] +pub(super) fn ret_send_recv(len: isize) -> io::Result { + ret_ssize_t(len) +} + +/// Convert the return value of a `send` or `recv` call. +#[cfg(windows)] +#[inline] +pub(super) fn ret_send_recv(len: i32) -> io::Result { + ret_ssize_t(len as isize) +} diff --git a/vendor/rustix/src/backend/libc/fs/dir.rs b/vendor/rustix/src/backend/libc/fs/dir.rs new file mode 100644 index 000000000..8e5477401 --- /dev/null +++ b/vendor/rustix/src/backend/libc/fs/dir.rs @@ -0,0 +1,483 @@ +use super::super::c; +use super::super::conv::owned_fd; +#[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] +use super::types::FileType; +use crate::fd::{AsFd, BorrowedFd}; +use crate::ffi::CStr; +#[cfg(target_os = "wasi")] +use crate::ffi::CString; +use crate::fs::{fcntl_getfl, fstat, openat, Mode, OFlags, Stat}; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +use crate::fs::{fstatfs, StatFs}; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +use crate::fs::{fstatvfs, StatVfs}; +use crate::io; +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +use crate::process::fchdir; +#[cfg(target_os = "wasi")] +use alloc::borrow::ToOwned; +#[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", + target_os = "openbsd", +)))] +use c::dirent as libc_dirent; +#[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", +)))] +use c::readdir as libc_readdir; +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", +))] +use c::{dirent64 as libc_dirent, readdir64 as libc_readdir}; +use core::fmt; +use core::mem::zeroed; +use core::ptr::NonNull; +use libc_errno::{errno, set_errno, Errno}; + +/// `DIR*` +#[repr(transparent)] +pub struct Dir(NonNull); + +impl Dir { + /// Construct a `Dir` that reads entries from the given directory + /// file descriptor. + #[inline] + pub fn read_from(fd: Fd) -> io::Result { + Self::_read_from(fd.as_fd()) + } + + #[inline] + fn _read_from(fd: BorrowedFd<'_>) -> io::Result { + // Given an arbitrary `OwnedFd`, it's impossible to know whether the + // user holds a `dup`'d copy which could continue to modify the + // file description state, which would cause Undefined Behavior after + // our call to `fdopendir`. To prevent this, we obtain an independent + // `OwnedFd`. + let flags = fcntl_getfl(fd)?; + let fd_for_dir = openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; + + let raw = owned_fd(fd_for_dir); + unsafe { + let libc_dir = c::fdopendir(raw); + + if let Some(libc_dir) = NonNull::new(libc_dir) { + Ok(Self(libc_dir)) + } else { + let err = io::Errno::last_os_error(); + let _ = c::close(raw); + Err(err) + } + } + } + + /// `rewinddir(self)` + #[inline] + pub fn rewind(&mut self) { + unsafe { c::rewinddir(self.0.as_ptr()) } + } + + /// `readdir(self)`, where `None` means the end of the directory. + pub fn read(&mut self) -> Option> { + set_errno(Errno(0)); + let dirent_ptr = unsafe { libc_readdir(self.0.as_ptr()) }; + if dirent_ptr.is_null() { + let curr_errno = errno().0; + if curr_errno == 0 { + // We successfully reached the end of the stream. + None + } else { + // `errno` is unknown or non-zero, so an error occurred. + Some(Err(io::Errno(curr_errno))) + } + } else { + // We successfully read an entry. + unsafe { + // We have our own copy of OpenBSD's dirent; check that the + // layout minimally matches libc's. + #[cfg(target_os = "openbsd")] + check_dirent_layout(&*dirent_ptr); + + let result = DirEntry { + dirent: read_dirent(&*dirent_ptr.cast()), + + #[cfg(target_os = "wasi")] + name: CStr::from_ptr((*dirent_ptr).d_name.as_ptr()).to_owned(), + }; + + Some(Ok(result)) + } + } + } + + /// `fstat(self)` + #[inline] + pub fn stat(&self) -> io::Result { + fstat(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + } + + /// `fstatfs(self)` + #[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", + )))] + #[inline] + pub fn statfs(&self) -> io::Result { + fstatfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + } + + /// `fstatvfs(self)` + #[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", + )))] + #[inline] + pub fn statvfs(&self) -> io::Result { + fstatvfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + } + + /// `fchdir(self)` + #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] + #[inline] + pub fn chdir(&self) -> io::Result<()> { + fchdir(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) + } +} + +// A `dirent` pointer returned from `readdir` may not point to a full `dirent` +// struct, as the name is NUL-terminated and memory may not be allocated for +// the full extent of the struct. Copy the fields one at a time. +unsafe fn read_dirent(input: &libc_dirent) -> libc_dirent { + #[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "illumos", + target_os = "solaris" + )))] + let d_type = input.d_type; + + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "wasi", + )))] + let d_off = input.d_off; + + #[cfg(target_os = "aix")] + let d_offset = input.d_offset; + + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + )))] + let d_ino = input.d_ino; + + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + let d_fileno = input.d_fileno; + + #[cfg(not(any(target_os = "dragonfly", target_os = "wasi")))] + let d_reclen = input.d_reclen; + + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "ios", + target_os = "macos", + ))] + let d_namlen = input.d_namlen; + + #[cfg(any(target_os = "ios", target_os = "macos"))] + let d_seekoff = input.d_seekoff; + + #[cfg(target_os = "haiku")] + let d_dev = input.d_dev; + #[cfg(target_os = "haiku")] + let d_pdev = input.d_pdev; + #[cfg(target_os = "haiku")] + let d_pino = input.d_pino; + + // Construct the input. Rust will give us an error if any OS has a input + // with a field that we missed here. And we can avoid blindly copying the + // whole `d_name` field, which may not be entirely allocated. + #[cfg_attr(target_os = "wasi", allow(unused_mut))] + #[cfg(not(target_os = "dragonfly"))] + let mut dirent = libc_dirent { + #[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "illumos", + target_os = "solaris" + )))] + d_type, + #[cfg(not(any( + target_os = "aix", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "wasi", + )))] + d_off, + #[cfg(target_os = "aix")] + d_offset, + #[cfg(not(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))] + d_ino, + #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] + d_fileno, + #[cfg(not(target_os = "wasi"))] + d_reclen, + #[cfg(any( + target_os = "aix", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + d_namlen, + #[cfg(any(target_os = "ios", target_os = "macos"))] + d_seekoff, + // The `d_name` field is NUL-terminated, and we need to be careful not + // to read bytes past the NUL, even though they're within the nominal + // extent of the `struct dirent`, because they may not be allocated. So + // don't read it from `dirent_ptr`. + // + // In theory this could use `MaybeUninit::uninit().assume_init()`, but + // that [invokes undefined behavior]. + // + // [invokes undefined behavior]: https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#initialization-invariant + d_name: zeroed(), + #[cfg(target_os = "openbsd")] + __d_padding: zeroed(), + #[cfg(target_os = "haiku")] + d_dev, + #[cfg(target_os = "haiku")] + d_pdev, + #[cfg(target_os = "haiku")] + d_pino, + }; + /* + pub d_ino: ino_t, + pub d_pino: i64, + pub d_reclen: ::c_ushort, + pub d_name: [::c_char; 1024], // Max length is _POSIX_PATH_MAX + // */ + + // On dragonfly, `dirent` has some non-public padding fields so we can't + // directly initialize it. + #[cfg(target_os = "dragonfly")] + let mut dirent = unsafe { + let mut dirent: libc_dirent = zeroed(); + dirent.d_fileno = d_fileno; + dirent.d_namlen = d_namlen; + dirent.d_type = d_type; + dirent + }; + + // Copy from d_name, reading up to and including the first NUL. + #[cfg(not(target_os = "wasi"))] + { + let name_len = CStr::from_ptr(input.d_name.as_ptr()) + .to_bytes_with_nul() + .len(); + dirent.d_name[..name_len].copy_from_slice(&input.d_name[..name_len]); + } + + dirent +} + +/// `Dir` implements `Send` but not `Sync`, because we use `readdir` which is +/// not guaranteed to be thread-safe. Users can wrap this in a `Mutex` if they +/// need `Sync`, which is effectively what'd need to do to implement `Sync` +/// ourselves. +unsafe impl Send for Dir {} + +impl Drop for Dir { + #[inline] + fn drop(&mut self) { + unsafe { c::closedir(self.0.as_ptr()) }; + } +} + +impl Iterator for Dir { + type Item = io::Result; + + #[inline] + fn next(&mut self) -> Option { + Self::read(self) + } +} + +impl fmt::Debug for Dir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Dir") + .field("fd", unsafe { &c::dirfd(self.0.as_ptr()) }) + .finish() + } +} + +/// `struct dirent` +#[derive(Debug)] +pub struct DirEntry { + dirent: libc_dirent, + + #[cfg(target_os = "wasi")] + name: CString, +} + +impl DirEntry { + /// Returns the file name of this directory entry. + #[inline] + pub fn file_name(&self) -> &CStr { + #[cfg(not(target_os = "wasi"))] + unsafe { + CStr::from_ptr(self.dirent.d_name.as_ptr()) + } + + #[cfg(target_os = "wasi")] + &self.name + } + + /// Returns the type of this directory entry. + #[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "illumos", + target_os = "solaris" + )))] + #[inline] + pub fn file_type(&self) -> FileType { + FileType::from_dirent_d_type(self.dirent.d_type) + } + + /// Return the inode number of this directory entry. + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + )))] + #[inline] + pub fn ino(&self) -> u64 { + self.dirent.d_ino as u64 + } + + /// Return the inode number of this directory entry. + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + ))] + #[inline] + pub fn ino(&self) -> u64 { + #[allow(clippy::useless_conversion)] + self.dirent.d_fileno.into() + } +} + +/// libc's OpenBSD `dirent` has a private field so we can't construct it +/// directly, so we declare it ourselves to make all fields accessible. +#[cfg(target_os = "openbsd")] +#[repr(C)] +#[derive(Debug)] +struct libc_dirent { + d_fileno: c::ino_t, + d_off: c::off_t, + d_reclen: u16, + d_type: u8, + d_namlen: u8, + __d_padding: [u8; 4], + d_name: [c::c_char; 256], +} + +/// We have our own copy of OpenBSD's dirent; check that the layout +/// minimally matches libc's. +#[cfg(target_os = "openbsd")] +fn check_dirent_layout(dirent: &c::dirent) { + use crate::utils::as_ptr; + use core::mem::{align_of, size_of}; + + // Check that the basic layouts match. + assert_eq!(size_of::(), size_of::()); + assert_eq!(align_of::(), align_of::()); + + // Check that the field offsets match. + assert_eq!( + { + let z = libc_dirent { + d_fileno: 0_u64, + d_off: 0_i64, + d_reclen: 0_u16, + d_type: 0_u8, + d_namlen: 0_u8, + __d_padding: [0_u8; 4], + d_name: [0 as c::c_char; 256], + }; + let base = as_ptr(&z) as usize; + ( + (as_ptr(&z.d_fileno) as usize) - base, + (as_ptr(&z.d_off) as usize) - base, + (as_ptr(&z.d_reclen) as usize) - base, + (as_ptr(&z.d_type) as usize) - base, + (as_ptr(&z.d_namlen) as usize) - base, + (as_ptr(&z.d_name) as usize) - base, + ) + }, + { + let z = dirent; + let base = as_ptr(z) as usize; + ( + (as_ptr(&z.d_fileno) as usize) - base, + (as_ptr(&z.d_off) as usize) - base, + (as_ptr(&z.d_reclen) as usize) - base, + (as_ptr(&z.d_type) as usize) - base, + (as_ptr(&z.d_namlen) as usize) - base, + (as_ptr(&z.d_name) as usize) - base, + ) + } + ); +} diff --git a/vendor/rustix/src/backend/libc/fs/makedev.rs b/vendor/rustix/src/backend/libc/fs/makedev.rs new file mode 100644 index 000000000..08ecd872e --- /dev/null +++ b/vendor/rustix/src/backend/libc/fs/makedev.rs @@ -0,0 +1,90 @@ +#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] +use super::super::c; +use crate::fs::Dev; + +#[cfg(not(any(target_os = "android", target_os = "emscripten")))] +#[inline] +pub(crate) fn makedev(maj: u32, min: u32) -> Dev { + c::makedev(maj, min) +} + +#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] +#[inline] +pub(crate) fn makedev(maj: u32, min: u32) -> Dev { + // Android's `makedev` oddly has signed argument types. + c::makedev(maj, min) +} + +#[cfg(all(target_os = "android", target_pointer_width = "32"))] +#[inline] +pub(crate) fn makedev(maj: u32, min: u32) -> Dev { + // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, + // so we do it ourselves. + ((u64::from(maj) & 0xffff_f000_u64) << 32) + | ((u64::from(maj) & 0x0000_0fff_u64) << 8) + | ((u64::from(min) & 0xffff_ff00_u64) << 12) + | (u64::from(min) & 0x0000_00ff_u64) +} + +#[cfg(target_os = "emscripten")] +#[inline] +pub(crate) fn makedev(maj: u32, min: u32) -> Dev { + // Emscripten's `makedev` has a 32-bit return value. + Dev::from(c::makedev(maj, min)) +} + +#[cfg(not(any(target_os = "android", target_os = "emscripten")))] +#[inline] +pub(crate) fn major(dev: Dev) -> u32 { + unsafe { c::major(dev) } +} + +#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] +#[inline] +pub(crate) fn major(dev: Dev) -> u32 { + // Android's `major` oddly has signed return types. + (unsafe { c::major(dev) }) as u32 +} + +#[cfg(all(target_os = "android", target_pointer_width = "32"))] +#[inline] +pub(crate) fn major(dev: Dev) -> u32 { + // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, + // so we do it ourselves. + (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 +} + +#[cfg(target_os = "emscripten")] +#[inline] +pub(crate) fn major(dev: Dev) -> u32 { + // Emscripten's `major` has a 32-bit argument value. + unsafe { c::major(dev as u32) } +} + +#[cfg(not(any(target_os = "android", target_os = "emscripten")))] +#[inline] +pub(crate) fn minor(dev: Dev) -> u32 { + unsafe { c::minor(dev) } +} + +#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] +#[inline] +pub(crate) fn minor(dev: Dev) -> u32 { + // Android's `minor` oddly has signed return types. + (unsafe { c::minor(dev) }) as u32 +} + +#[cfg(all(target_os = "android", target_pointer_width = "32"))] +#[inline] +pub(crate) fn minor(dev: Dev) -> u32 { + // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, + // so we do it ourselves. + (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 +} + +#[cfg(target_os = "emscripten")] +#[inline] +pub(crate) fn minor(dev: Dev) -> u32 { + // Emscripten's `minor` has a 32-bit argument value. + unsafe { c::minor(dev as u32) } +} diff --git a/vendor/rustix/src/backend/libc/fs/mod.rs b/vendor/rustix/src/backend/libc/fs/mod.rs new file mode 100644 index 000000000..d0fc08765 --- /dev/null +++ b/vendor/rustix/src/backend/libc/fs/mod.rs @@ -0,0 +1,19 @@ +#[cfg(not(target_os = "redox"))] +pub(crate) mod dir; +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub(crate) mod makedev; +#[cfg(not(windows))] +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/fs/syscalls.rs b/vendor/rustix/src/backend/libc/fs/syscalls.rs new file mode 100644 index 000000000..1d1891f0f --- /dev/null +++ b/vendor/rustix/src/backend/libc/fs/syscalls.rs @@ -0,0 +1,1772 @@ +//! libc syscalls supporting `rustix::fs`. + +use super::super::c; +use super::super::conv::{ + borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd, ret_ssize_t, +}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::super::conv::{syscall_ret, syscall_ret_owned_fd, syscall_ret_ssize_t}; +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +use super::super::offset::libc_fallocate; +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +use super::super::offset::libc_posix_fadvise; +#[cfg(not(any( + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +use super::super::offset::libc_posix_fallocate; +use super::super::offset::{libc_fstat, libc_fstatat, libc_ftruncate, libc_lseek, libc_off_t}; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +use super::super::offset::{libc_fstatfs, libc_statfs}; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +use super::super::offset::{libc_fstatvfs, libc_statvfs}; +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +use super::super::time::types::LibcTimespec; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::ffi::CStr; +#[cfg(any(target_os = "ios", target_os = "macos"))] +use crate::ffi::CString; +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] +use crate::fs::Access; +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +use crate::fs::Advice; +#[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +use crate::fs::FallocateFlags; +#[cfg(not(any(target_os = "solaris", target_os = "wasi")))] +use crate::fs::FlockOperation; +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +use crate::fs::MemfdFlags; +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "linux", +))] +use crate::fs::SealFlags; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +use crate::fs::StatFs; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::fs::{cwd, RenameFlags, ResolveFlags, Statx, StatxFlags}; +#[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "wasi", +)))] +use crate::fs::{Dev, FileType}; +use crate::fs::{Mode, OFlags, Stat, Timestamps}; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +use crate::fs::{StatVfs, StatVfsMountFlags}; +use crate::io::{self, SeekFrom}; +#[cfg(not(target_os = "wasi"))] +use crate::process::{Gid, Uid}; +#[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +)))] +use crate::utils::as_ptr; +use core::convert::TryInto; +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", +))] +use core::mem::size_of; +use core::mem::MaybeUninit; +#[cfg(any(target_os = "android", target_os = "linux"))] +use core::ptr::null; +#[cfg(any( + target_os = "android", + target_os = "ios", + target_os = "linux", + target_os = "macos", +))] +use core::ptr::null_mut; +#[cfg(any(target_os = "ios", target_os = "macos"))] +use { + super::super::conv::nonnegative_ret, + crate::fs::{copyfile_state_t, CloneFlags, CopyfileFlags}, +}; +#[cfg(not(target_os = "redox"))] +use {super::super::offset::libc_openat, crate::fs::AtFlags}; + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +weak!(fn __utimensat64(c::c_int, *const c::c_char, *const LibcTimespec, c::c_int) -> c::c_int); +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +weak!(fn __futimens64(c::c_int, *const LibcTimespec) -> c::c_int); + +/// Use a direct syscall (via libc) for `openat`. +/// +/// This is only currently necessary as a workaround for old glibc; see below. +#[cfg(all(unix, target_env = "gnu"))] +fn openat_via_syscall( + dirfd: BorrowedFd<'_>, + path: &CStr, + oflags: OFlags, + mode: Mode, +) -> io::Result { + unsafe { + let dirfd = borrowed_fd(dirfd); + let path = c_str(path); + let oflags = oflags.bits(); + let mode = c::c_uint::from(mode.bits()); + ret_owned_fd(c::syscall( + c::SYS_openat, + c::c_long::from(dirfd), + path, + c::c_long::from(oflags), + mode as c::c_long, + ) as c::c_int) + } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn openat( + dirfd: BorrowedFd<'_>, + path: &CStr, + oflags: OFlags, + mode: Mode, +) -> io::Result { + // Work around . + // Basically old glibc versions don't handle O_TMPFILE correctly. + #[cfg(all(unix, target_env = "gnu"))] + if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { + return openat_via_syscall(dirfd, path, oflags, mode); + } + unsafe { + // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since + // `libc_openat` is declared as a variadic function and narrower + // arguments are promoted. + ret_owned_fd(libc_openat( + borrowed_fd(dirfd), + c_str(path), + oflags.bits(), + c::c_uint::from(mode.bits()), + )) + } +} + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[inline] +pub(crate) fn statfs(filename: &CStr) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(libc_statfs(c_str(filename), result.as_mut_ptr()))?; + Ok(result.assume_init()) + } +} + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[inline] +pub(crate) fn statvfs(filename: &CStr) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(libc_statvfs(c_str(filename), result.as_mut_ptr()))?; + Ok(libc_statvfs_to_statvfs(result.assume_init())) + } +} + +#[cfg(not(target_os = "redox"))] +#[inline] +pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result { + unsafe { + ret_ssize_t(c::readlinkat( + borrowed_fd(dirfd), + c_str(path), + buf.as_mut_ptr().cast::(), + buf.len(), + )) + .map(|nread| nread as usize) + } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { + unsafe { + ret(c::mkdirat( + borrowed_fd(dirfd), + c_str(path), + mode.bits() as c::mode_t, + )) + } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn linkat( + old_dirfd: BorrowedFd<'_>, + old_path: &CStr, + new_dirfd: BorrowedFd<'_>, + new_path: &CStr, + flags: AtFlags, +) -> io::Result<()> { + unsafe { + ret(c::linkat( + borrowed_fd(old_dirfd), + c_str(old_path), + borrowed_fd(new_dirfd), + c_str(new_path), + flags.bits(), + )) + } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { + unsafe { ret(c::unlinkat(borrowed_fd(dirfd), c_str(path), flags.bits())) } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn renameat( + old_dirfd: BorrowedFd<'_>, + old_path: &CStr, + new_dirfd: BorrowedFd<'_>, + new_path: &CStr, +) -> io::Result<()> { + unsafe { + ret(c::renameat( + borrowed_fd(old_dirfd), + c_str(old_path), + borrowed_fd(new_dirfd), + c_str(new_path), + )) + } +} + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub(crate) fn renameat2( + old_dirfd: BorrowedFd<'_>, + old_path: &CStr, + new_dirfd: BorrowedFd<'_>, + new_path: &CStr, + flags: RenameFlags, +) -> io::Result<()> { + // `getrandom` wasn't supported in glibc until 2.28. + weak_or_syscall! { + fn renameat2( + olddirfd: c::c_int, + oldpath: *const c::c_char, + newdirfd: c::c_int, + newpath: *const c::c_char, + flags: c::c_uint + ) via SYS_renameat2 -> c::c_int + } + + unsafe { + ret(renameat2( + borrowed_fd(old_dirfd), + c_str(old_path), + borrowed_fd(new_dirfd), + c_str(new_path), + flags.bits(), + )) + } +} + +/// At present, `libc` only has `renameat2` defined for glibc. On other +/// ABIs, `RenameFlags` has no flags defined, and we use plain `renameat`. +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "gnu")), +))] +#[inline] +pub(crate) fn renameat2( + old_dirfd: BorrowedFd<'_>, + old_path: &CStr, + new_dirfd: BorrowedFd<'_>, + new_path: &CStr, + flags: RenameFlags, +) -> io::Result<()> { + assert!(flags.is_empty()); + renameat(old_dirfd, old_path, new_dirfd, new_path) +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn symlinkat( + old_path: &CStr, + new_dirfd: BorrowedFd<'_>, + new_path: &CStr, +) -> io::Result<()> { + unsafe { + ret(c::symlinkat( + c_str(old_path), + borrowed_fd(new_dirfd), + c_str(new_path), + )) + } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result { + // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use + // `statx`. + #[cfg(all( + any(target_os = "android", target_os = "linux"), + any(target_pointer_width = "32", target_arch = "mips64"), + ))] + { + match statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { + Ok(x) => statx_to_stat(x), + Err(io::Errno::NOSYS) => statat_old(dirfd, path, flags), + Err(err) => Err(err), + } + } + + // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and + // there's nothing practical we can do. + #[cfg(not(all( + any(target_os = "android", target_os = "linux"), + any(target_pointer_width = "32", target_arch = "mips64"), + )))] + unsafe { + let mut stat = MaybeUninit::::uninit(); + ret(libc_fstatat( + borrowed_fd(dirfd), + c_str(path), + stat.as_mut_ptr(), + flags.bits(), + ))?; + Ok(stat.assume_init()) + } +} + +#[cfg(all( + any(target_os = "android", target_os = "linux"), + any(target_pointer_width = "32", target_arch = "mips64"), +))] +fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(libc_fstatat( + borrowed_fd(dirfd), + c_str(path), + result.as_mut_ptr(), + flags.bits(), + ))?; + stat64_to_stat(result.assume_init()) + } +} + +#[cfg(not(any( + target_os = "emscripten", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", +)))] +pub(crate) fn accessat( + dirfd: BorrowedFd<'_>, + path: &CStr, + access: Access, + flags: AtFlags, +) -> io::Result<()> { + unsafe { + ret(c::faccessat( + borrowed_fd(dirfd), + c_str(path), + access.bits(), + flags.bits(), + )) + } +} + +#[cfg(target_os = "emscripten")] +pub(crate) fn accessat( + _dirfd: BorrowedFd<'_>, + _path: &CStr, + _access: Access, + _flags: AtFlags, +) -> io::Result<()> { + Ok(()) +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn utimensat( + dirfd: BorrowedFd<'_>, + path: &CStr, + times: &Timestamps, + flags: AtFlags, +) -> io::Result<()> { + // 32-bit gnu version: libc has `utimensat` but it is not y2038 safe by + // default. + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_utimensat) = __utimensat64.get() { + let libc_times: [LibcTimespec; 2] = [ + times.last_access.clone().into(), + times.last_modification.clone().into(), + ]; + + ret(libc_utimensat( + borrowed_fd(dirfd), + c_str(path), + libc_times.as_ptr(), + flags.bits(), + )) + } else { + utimensat_old(dirfd, path, times, flags) + } + } + + // Main version: libc is y2038 safe and has `utimensat`. Or, the platform + // is not y2038 safe and there's nothing practical we can do. + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ) + )))] + unsafe { + // Assert that `Timestamps` has the expected layout. + let _ = core::mem::transmute::(times.clone()); + + ret(c::utimensat( + borrowed_fd(dirfd), + c_str(path), + as_ptr(times).cast(), + flags.bits(), + )) + } + + // `utimensat` was introduced in macOS 10.13. + #[cfg(any(target_os = "ios", target_os = "macos"))] + unsafe { + // ABI details + weak! { + fn utimensat( + c::c_int, + *const c::c_char, + *const c::timespec, + c::c_int + ) -> c::c_int + } + extern "C" { + fn setattrlist( + path: *const c::c_char, + attr_list: *const Attrlist, + attr_buf: *const c::c_void, + attr_buf_size: c::size_t, + options: c::c_ulong, + ) -> c::c_int; + } + const FSOPT_NOFOLLOW: c::c_ulong = 0x0000_0001; + + // If we have `utimensat`, use it. + if let Some(have_utimensat) = utimensat.get() { + // Assert that `Timestamps` has the expected layout. + let _ = core::mem::transmute::(times.clone()); + + return ret(have_utimensat( + borrowed_fd(dirfd), + c_str(path), + as_ptr(times).cast(), + flags.bits(), + )); + } + + // `setattrlistat` was introduced in 10.13 along with `utimensat`, so if + // we don't have `utimensat`, we don't have `setattrlistat` either. + // Emulate it using `fork`, and `fchdir` and [`setattrlist`]. + // + // [`setattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setattrlist.2.html + match c::fork() { + -1 => Err(io::Errno::IO), + 0 => { + if c::fchdir(borrowed_fd(dirfd)) != 0 { + let code = match libc_errno::errno().0 { + c::EACCES => 2, + c::ENOTDIR => 3, + _ => 1, + }; + c::_exit(code); + } + + let mut flags_arg = 0; + if flags.contains(AtFlags::SYMLINK_NOFOLLOW) { + flags_arg |= FSOPT_NOFOLLOW; + } + + let (attrbuf_size, times, attrs) = times_to_attrlist(times); + + if setattrlist( + c_str(path), + &attrs, + as_ptr(×).cast(), + attrbuf_size, + flags_arg, + ) != 0 + { + // Translate expected errno codes into ad-hoc integer + // values suitable for exit statuses. + let code = match libc_errno::errno().0 { + c::EACCES => 2, + c::ENOTDIR => 3, + c::EPERM => 4, + c::EROFS => 5, + c::ELOOP => 6, + c::ENOENT => 7, + c::ENAMETOOLONG => 8, + c::EINVAL => 9, + c::ESRCH => 10, + c::ENOTSUP => 11, + _ => 1, + }; + c::_exit(code); + } + + c::_exit(0); + } + child_pid => { + let mut wstatus = 0; + let _ = ret_c_int(c::waitpid(child_pid, &mut wstatus, 0))?; + if c::WIFEXITED(wstatus) { + // Translate our ad-hoc exit statuses back to errno codes. + match c::WEXITSTATUS(wstatus) { + 0 => Ok(()), + 2 => Err(io::Errno::ACCESS), + 3 => Err(io::Errno::NOTDIR), + 4 => Err(io::Errno::PERM), + 5 => Err(io::Errno::ROFS), + 6 => Err(io::Errno::LOOP), + 7 => Err(io::Errno::NOENT), + 8 => Err(io::Errno::NAMETOOLONG), + 9 => Err(io::Errno::INVAL), + 10 => Err(io::Errno::SRCH), + 11 => Err(io::Errno::NOTSUP), + _ => Err(io::Errno::IO), + } + } else { + Err(io::Errno::IO) + } + } + } + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +unsafe fn utimensat_old( + dirfd: BorrowedFd<'_>, + path: &CStr, + times: &Timestamps, + flags: AtFlags, +) -> io::Result<()> { + let old_times = [ + c::timespec { + tv_sec: times + .last_access + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: times.last_access.tv_nsec, + }, + c::timespec { + tv_sec: times + .last_modification + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: times.last_modification.tv_nsec, + }, + ]; + ret(c::utimensat( + borrowed_fd(dirfd), + c_str(path), + old_times.as_ptr(), + flags.bits(), + )) +} + +#[cfg(not(any( + target_os = "android", + target_os = "linux", + target_os = "redox", + target_os = "wasi", +)))] +pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { + unsafe { ret(c::fchmodat(borrowed_fd(dirfd), c_str(path), mode.bits(), 0)) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { + // Linux's `fchmodat` does not have a flags argument. + unsafe { + // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since + // `libc_openat` is declared as a variadic function and narrower + // arguments are promoted. + syscall_ret(c::syscall( + c::SYS_fchmodat, + borrowed_fd(dirfd), + c_str(path), + c::c_uint::from(mode.bits()), + )) + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn fclonefileat( + srcfd: BorrowedFd<'_>, + dst_dirfd: BorrowedFd<'_>, + dst: &CStr, + flags: CloneFlags, +) -> io::Result<()> { + syscall! { + fn fclonefileat( + srcfd: BorrowedFd<'_>, + dst_dirfd: BorrowedFd<'_>, + dst: *const c::c_char, + flags: c::c_int + ) via SYS_fclonefileat -> c::c_int + } + + unsafe { ret(fclonefileat(srcfd, dst_dirfd, c_str(dst), flags.bits())) } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn chownat( + dirfd: BorrowedFd<'_>, + path: &CStr, + owner: Option, + group: Option, + flags: AtFlags, +) -> io::Result<()> { + unsafe { + let (ow, gr) = crate::process::translate_fchown_args(owner, group); + ret(c::fchownat( + borrowed_fd(dirfd), + c_str(path), + ow, + gr, + flags.bits(), + )) + } +} + +#[cfg(not(any( + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "wasi", +)))] +pub(crate) fn mknodat( + dirfd: BorrowedFd<'_>, + path: &CStr, + file_type: FileType, + mode: Mode, + dev: Dev, +) -> io::Result<()> { + unsafe { + ret(c::mknodat( + borrowed_fd(dirfd), + c_str(path), + (mode.bits() | file_type.as_raw_mode()) as c::mode_t, + dev.try_into().map_err(|_e| io::Errno::PERM)?, + )) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn copy_file_range( + fd_in: BorrowedFd<'_>, + off_in: Option<&mut u64>, + fd_out: BorrowedFd<'_>, + off_out: Option<&mut u64>, + len: u64, +) -> io::Result { + assert_eq!(size_of::(), size_of::()); + + let mut off_in_val: c::loff_t = 0; + let mut off_out_val: c::loff_t = 0; + // Silently cast; we'll get `EINVAL` if the value is negative. + let off_in_ptr = if let Some(off_in) = &off_in { + off_in_val = (**off_in) as i64; + &mut off_in_val + } else { + null_mut() + }; + let off_out_ptr = if let Some(off_out) = &off_out { + off_out_val = (**off_out) as i64; + &mut off_out_val + } else { + null_mut() + }; + let len: usize = len.try_into().unwrap_or(usize::MAX); + let copied = unsafe { + syscall_ret_ssize_t(c::syscall( + c::SYS_copy_file_range, + borrowed_fd(fd_in), + off_in_ptr, + borrowed_fd(fd_out), + off_out_ptr, + len, + 0, // no flags are defined yet + ))? + }; + if let Some(off_in) = off_in { + *off_in = off_in_val as u64; + } + if let Some(off_out) = off_out { + *off_out = off_out_val as u64; + } + Ok(copied as u64) +} + +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub(crate) fn fadvise(fd: BorrowedFd<'_>, offset: u64, len: u64, advice: Advice) -> io::Result<()> { + let offset = offset as i64; + let len = len as i64; + + // FreeBSD returns `EINVAL` on invalid offsets; emulate the POSIX behavior. + #[cfg(target_os = "freebsd")] + let offset = if (offset as i64) < 0 { + i64::MAX + } else { + offset + }; + + // FreeBSD returns `EINVAL` on overflow; emulate the POSIX behavior. + #[cfg(target_os = "freebsd")] + let len = if len > 0 && offset.checked_add(len).is_none() { + i64::MAX - offset + } else { + len + }; + + let err = unsafe { libc_posix_fadvise(borrowed_fd(fd), offset, len, advice as c::c_int) }; + + // `posix_fadvise` returns its error status rather than using `errno`. + if err == 0 { + Ok(()) + } else { + Err(io::Errno(err)) + } +} + +pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result { + unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFL)).map(OFlags::from_bits_truncate) } +} + +pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { + unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFL, flags.bits())) } +} + +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "linux", +))] +pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GET_SEALS)) + .map(|flags| SealFlags::from_bits_unchecked(flags)) + } +} + +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "linux", +))] +pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { + unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_ADD_SEALS, seals.bits())) } +} + +pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { + let (whence, offset): (c::c_int, libc_off_t) = match pos { + SeekFrom::Start(pos) => { + let pos: u64 = pos; + // Silently cast; we'll get `EINVAL` if the value is negative. + (c::SEEK_SET, pos as i64) + } + SeekFrom::End(offset) => (c::SEEK_END, offset), + SeekFrom::Current(offset) => (c::SEEK_CUR, offset), + }; + let offset = unsafe { ret_off_t(libc_lseek(borrowed_fd(fd), offset, whence))? }; + Ok(offset as u64) +} + +pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result { + let offset = unsafe { ret_off_t(libc_lseek(borrowed_fd(fd), 0, c::SEEK_CUR))? }; + Ok(offset as u64) +} + +#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))] +pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { + unsafe { ret(c::fchmod(borrowed_fd(fd), mode.bits())) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { + // Use `c::syscall` rather than `c::fchmod` because some libc + // implementations, such as musl, add extra logic to `fchmod` to emulate + // support for `O_PATH`, which uses `/proc` outside our control and + // interferes with our own use of `O_PATH`. + unsafe { + syscall_ret(c::syscall( + c::SYS_fchmod, + borrowed_fd(fd), + c::c_uint::from(mode.bits()), + )) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option, group: Option) -> io::Result<()> { + // Use `c::syscall` rather than `c::fchown` because some libc + // implementations, such as musl, add extra logic to `fchown` to emulate + // support for `O_PATH`, which uses `/proc` outside our control and + // interferes with our own use of `O_PATH`. + unsafe { + let (ow, gr) = crate::process::translate_fchown_args(owner, group); + syscall_ret(c::syscall(c::SYS_fchown, borrowed_fd(fd), ow, gr)) + } +} + +#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))] +pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option, group: Option) -> io::Result<()> { + unsafe { + let (ow, gr) = crate::process::translate_fchown_args(owner, group); + ret(c::fchown(borrowed_fd(fd), ow, gr)) + } +} + +#[cfg(not(any(target_os = "solaris", target_os = "wasi")))] +pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { + unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) } +} + +pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { + // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use + // `statx`. + #[cfg(all( + any(target_os = "android", target_os = "linux"), + any(target_pointer_width = "32", target_arch = "mips64"), + ))] + { + match 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), + } + } + + // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and + // there's nothing practical we can do. + #[cfg(not(all( + any(target_os = "android", target_os = "linux"), + any(target_pointer_width = "32", target_arch = "mips64"), + )))] + unsafe { + let mut stat = MaybeUninit::::uninit(); + ret(libc_fstat(borrowed_fd(fd), stat.as_mut_ptr()))?; + Ok(stat.assume_init()) + } +} + +#[cfg(all( + any(target_os = "android", target_os = "linux"), + any(target_pointer_width = "32", target_arch = "mips64"), +))] +fn fstat_old(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(libc_fstat(borrowed_fd(fd), result.as_mut_ptr()))?; + stat64_to_stat(result.assume_init()) + } +} + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result { + let mut statfs = MaybeUninit::::uninit(); + unsafe { + ret(libc_fstatfs(borrowed_fd(fd), statfs.as_mut_ptr()))?; + Ok(statfs.assume_init()) + } +} + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub(crate) fn fstatvfs(fd: BorrowedFd<'_>) -> io::Result { + let mut statvfs = MaybeUninit::::uninit(); + unsafe { + ret(libc_fstatvfs(borrowed_fd(fd), statvfs.as_mut_ptr()))?; + Ok(libc_statvfs_to_statvfs(statvfs.assume_init())) + } +} + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi" +)))] +fn libc_statvfs_to_statvfs(from: libc_statvfs) -> StatVfs { + StatVfs { + f_bsize: from.f_bsize as u64, + f_frsize: from.f_frsize as u64, + f_blocks: from.f_blocks as u64, + f_bfree: from.f_bfree as u64, + f_bavail: from.f_bavail as u64, + f_files: from.f_files as u64, + f_ffree: from.f_ffree as u64, + f_favail: from.f_ffree as u64, + f_fsid: from.f_fsid as u64, + f_flag: unsafe { StatVfsMountFlags::from_bits_unchecked(from.f_flag as u64) }, + f_namemax: from.f_namemax as u64, + } +} + +pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { + // 32-bit gnu version: libc has `futimens` but it is not y2038 safe by default. + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_futimens) = __futimens64.get() { + let libc_times: [LibcTimespec; 2] = [ + times.last_access.clone().into(), + times.last_modification.clone().into(), + ]; + + ret(libc_futimens(borrowed_fd(fd), libc_times.as_ptr())) + } else { + futimens_old(fd, times) + } + } + + // Main version: libc is y2038 safe and has `futimens`. Or, the platform + // is not y2038 safe and there's nothing practical we can do. + #[cfg(not(any( + target_os = "ios", + target_os = "macos", + all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ) + )))] + unsafe { + // Assert that `Timestamps` has the expected layout. + let _ = core::mem::transmute::(times.clone()); + + ret(c::futimens(borrowed_fd(fd), as_ptr(times).cast())) + } + + // `futimens` was introduced in macOS 10.13. + #[cfg(any(target_os = "ios", target_os = "macos"))] + unsafe { + // ABI details. + weak! { + fn futimens(c::c_int, *const c::timespec) -> c::c_int + } + extern "C" { + fn fsetattrlist( + fd: c::c_int, + attr_list: *const Attrlist, + attr_buf: *const c::c_void, + attr_buf_size: c::size_t, + options: c::c_ulong, + ) -> c::c_int; + } + + // If we have `futimens`, use it. + if let Some(have_futimens) = futimens.get() { + // Assert that `Timestamps` has the expected layout. + let _ = core::mem::transmute::(times.clone()); + + return ret(have_futimens(borrowed_fd(fd), as_ptr(times).cast())); + } + + // Otherwise use `fsetattrlist`. + let (attrbuf_size, times, attrs) = times_to_attrlist(times); + + ret(fsetattrlist( + borrowed_fd(fd), + &attrs, + as_ptr(×).cast(), + attrbuf_size, + 0, + )) + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +unsafe fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { + let old_times = [ + c::timespec { + tv_sec: times + .last_access + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: times.last_access.tv_nsec, + }, + c::timespec { + tv_sec: times + .last_modification + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: times.last_modification.tv_nsec, + }, + ]; + + ret(c::futimens(borrowed_fd(fd), old_times.as_ptr())) +} + +#[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub(crate) fn fallocate( + fd: BorrowedFd<'_>, + mode: FallocateFlags, + offset: u64, + len: u64, +) -> io::Result<()> { + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + let len = len as i64; + + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + unsafe { + ret(libc_fallocate(borrowed_fd(fd), mode.bits(), offset, len)) + } + + #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))] + { + assert!(mode.is_empty()); + let err = unsafe { libc_posix_fallocate(borrowed_fd(fd), offset, len) }; + + // `posix_fallocate` returns its error status rather than using `errno`. + if err == 0 { + Ok(()) + } else { + Err(io::Errno(err)) + } + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn fallocate( + fd: BorrowedFd<'_>, + mode: FallocateFlags, + offset: u64, + len: u64, +) -> io::Result<()> { + let offset: i64 = offset.try_into().map_err(|_e| io::Errno::INVAL)?; + let len = len as i64; + + assert!(mode.is_empty()); + + let new_len = offset.checked_add(len).ok_or(io::Errno::FBIG)?; + let mut store = c::fstore_t { + fst_flags: c::F_ALLOCATECONTIG, + fst_posmode: c::F_PEOFPOSMODE, + fst_offset: 0, + fst_length: new_len, + fst_bytesalloc: 0, + }; + unsafe { + if c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store) == -1 { + store.fst_flags = c::F_ALLOCATEALL; + let _ = ret_c_int(c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store))?; + } + ret(c::ftruncate(borrowed_fd(fd), new_len)) + } +} + +pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::fsync(borrowed_fd(fd))) } +} + +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox", +)))] +pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::fdatasync(borrowed_fd(fd))) } +} + +pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { + let length = length.try_into().map_err(|_overflow_err| io::Errno::FBIG)?; + unsafe { ret(libc_ftruncate(borrowed_fd(fd), length)) } +} + +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result { + #[cfg(target_os = "freebsd")] + weakcall! { + fn memfd_create( + name: *const c::c_char, + flags: c::c_uint + ) -> c::c_int + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + weak_or_syscall! { + fn memfd_create( + name: *const c::c_char, + flags: c::c_uint + ) via SYS_memfd_create -> c::c_int + } + + unsafe { ret_owned_fd(memfd_create(c_str(path), flags.bits())) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn openat2( + dirfd: BorrowedFd<'_>, + path: &CStr, + oflags: OFlags, + mode: Mode, + resolve: ResolveFlags, +) -> io::Result { + let oflags: i32 = oflags.bits(); + let open_how = OpenHow { + oflag: u64::from(oflags as u32), + mode: u64::from(mode.bits()), + resolve: resolve.bits(), + }; + + unsafe { + syscall_ret_owned_fd(c::syscall( + SYS_OPENAT2, + borrowed_fd(dirfd), + c_str(path), + &open_how, + SIZEOF_OPEN_HOW, + )) + } +} +#[cfg(all( + target_pointer_width = "32", + any(target_os = "android", target_os = "linux"), +))] +const SYS_OPENAT2: i32 = 437; +#[cfg(all( + target_pointer_width = "64", + any(target_os = "android", target_os = "linux"), +))] +const SYS_OPENAT2: i64 = 437; + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[repr(C)] +#[derive(Debug)] +struct OpenHow { + oflag: u64, + mode: u64, + resolve: u64, +} +#[cfg(any(target_os = "android", target_os = "linux"))] +const SIZEOF_OPEN_HOW: usize = size_of::(); + +#[cfg(target_os = "linux")] +pub(crate) fn sendfile( + out_fd: BorrowedFd<'_>, + in_fd: BorrowedFd<'_>, + offset: Option<&mut u64>, + count: usize, +) -> io::Result { + unsafe { + let nsent = ret_ssize_t(c::sendfile64( + borrowed_fd(out_fd), + borrowed_fd(in_fd), + offset.map_or(null_mut(), crate::utils::as_mut_ptr).cast(), + count, + ))?; + Ok(nsent as usize) + } +} + +/// Convert from a Linux `statx` value to rustix's `Stat`. +#[cfg(all( + any(target_os = "android", target_os = "linux"), + target_pointer_width = "32", +))] +fn statx_to_stat(x: crate::fs::Statx) -> io::Result { + Ok(Stat { + st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor).into(), + st_mode: x.stx_mode.into(), + st_nlink: x.stx_nlink.into(), + st_uid: x.stx_uid.into(), + st_gid: x.stx_gid.into(), + st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor).into(), + st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blksize: x.stx_blksize.into(), + st_blocks: x.stx_blocks.into(), + st_atime: x + .stx_atime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_atime_nsec: x.stx_atime.tv_nsec as _, + st_mtime: x + .stx_mtime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_mtime_nsec: x.stx_mtime.tv_nsec as _, + st_ctime: x + .stx_ctime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ctime_nsec: x.stx_ctime.tv_nsec as _, + st_ino: x.stx_ino.into(), + }) +} + +/// Convert from a Linux `statx` value to rustix's `Stat`. +/// +/// mips64' `struct stat64` in libc has private fields, and `stx_blocks` +#[cfg(all( + any(target_os = "android", target_os = "linux"), + target_arch = "mips64", +))] +fn statx_to_stat(x: crate::fs::Statx) -> io::Result { + let mut result: Stat = unsafe { core::mem::zeroed() }; + + result.st_dev = crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor); + result.st_mode = x.stx_mode.into(); + result.st_nlink = x.stx_nlink.into(); + result.st_uid = x.stx_uid.into(); + result.st_gid = x.stx_gid.into(); + result.st_rdev = crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor); + result.st_size = x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_blksize = x.stx_blksize.into(); + result.st_blocks = x.stx_blocks.try_into().map_err(|_e| io::Errno::OVERFLOW)?; + result.st_atime = x + .stx_atime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?; + result.st_atime_nsec = x.stx_atime.tv_nsec as _; + result.st_mtime = x + .stx_mtime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?; + result.st_mtime_nsec = x.stx_mtime.tv_nsec as _; + result.st_ctime = x + .stx_ctime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?; + result.st_ctime_nsec = x.stx_ctime.tv_nsec as _; + result.st_ino = x.stx_ino.into(); + + Ok(result) +} + +/// Convert from a Linux `stat64` value to rustix's `Stat`. +#[cfg(all( + any(target_os = "android", target_os = "linux"), + target_pointer_width = "32", +))] +fn stat64_to_stat(s64: c::stat64) -> io::Result { + Ok(Stat { + st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_atime: s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_atime_nsec: s64 + .st_atime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_mtime: s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_mtime_nsec: s64 + .st_mtime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ctime: s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_ctime_nsec: s64 + .st_ctime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, + }) +} + +/// Convert from a Linux `stat64` value to rustix's `Stat`. +/// +/// mips64' `struct stat64` in libc has private fields, and `st_blocks` has +/// type `i64`. +#[cfg(all( + any(target_os = "android", target_os = "linux"), + target_arch = "mips64", +))] +fn stat64_to_stat(s64: c::stat64) -> io::Result { + let mut result: Stat = unsafe { core::mem::zeroed() }; + + result.st_dev = s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_mode = s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_nlink = s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_uid = s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_gid = s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_rdev = s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_size = s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_blksize = s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_blocks = s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_atime = s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_atime_nsec = s64 + .st_atime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?; + result.st_mtime = s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_mtime_nsec = s64 + .st_mtime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?; + result.st_ctime = s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?; + result.st_ctime_nsec = s64 + .st_ctime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?; + result.st_ino = s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?; + + Ok(result) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[allow(non_upper_case_globals)] +mod sys { + use super::{c, BorrowedFd, Statx}; + + #[cfg(all(target_os = "android", target_arch = "arm"))] + const SYS_statx: c::c_long = 397; + #[cfg(all(target_os = "android", target_arch = "x86"))] + const SYS_statx: c::c_long = 383; + #[cfg(all(target_os = "android", target_arch = "aarch64"))] + const SYS_statx: c::c_long = 291; + #[cfg(all(target_os = "android", target_arch = "x86_64"))] + const SYS_statx: c::c_long = 332; + + weak_or_syscall! { + pub(super) fn statx( + pirfd: BorrowedFd<'_>, + path: *const c::c_char, + flags: c::c_int, + mask: c::c_uint, + buf: *mut Statx + ) via SYS_statx -> c::c_int + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[allow(non_upper_case_globals)] +pub(crate) fn statx( + dirfd: BorrowedFd<'_>, + path: &CStr, + flags: AtFlags, + mask: StatxFlags, +) -> io::Result { + // If a future Linux kernel adds more fields to `struct statx` and users + // passing flags unknown to rustix in `StatxFlags`, we could end up + // writing outside of the buffer. To prevent this possibility, we mask off + // any flags that we don't know about. + // + // This includes `STATX__RESERVED`, which has a value that we know, but + // which could take on arbitrary new meaning in the future. Linux currently + // rejects this flag with `EINVAL`, so we do the same. + // + // This doesn't rely on `STATX_ALL` because [it's deprecated] and already + // doesn't represent all the known flags. + // + // [it's deprecated]: https://patchwork.kernel.org/project/linux-fsdevel/patch/20200505095915.11275-7-mszeredi@redhat.com/ + #[cfg(not(any(target_os = "android", target_env = "musl")))] + const STATX__RESERVED: u32 = libc::STATX__RESERVED as u32; + #[cfg(any(target_os = "android", target_env = "musl"))] + const STATX__RESERVED: u32 = linux_raw_sys::general::STATX__RESERVED; + if (mask.bits() & STATX__RESERVED) == STATX__RESERVED { + return Err(io::Errno::INVAL); + } + let mask = mask & StatxFlags::all(); + + let mut statx_buf = MaybeUninit::::uninit(); + unsafe { + ret(sys::statx( + dirfd, + c_str(path), + flags.bits(), + mask.bits(), + statx_buf.as_mut_ptr(), + ))?; + Ok(statx_buf.assume_init()) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn is_statx_available() -> bool { + unsafe { + // Call `statx` with null pointers so that if it fails for any reason + // other than `EFAULT`, we know it's not supported. + matches!( + ret(sys::statx(cwd(), null(), 0, 0, null_mut())), + Err(io::Errno::FAULT) + ) + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) unsafe fn fcopyfile( + from: BorrowedFd<'_>, + to: BorrowedFd<'_>, + state: copyfile_state_t, + flags: CopyfileFlags, +) -> io::Result<()> { + extern "C" { + fn fcopyfile( + from: c::c_int, + to: c::c_int, + state: copyfile_state_t, + flags: c::c_uint, + ) -> c::c_int; + } + + nonnegative_ret(fcopyfile( + borrowed_fd(from), + borrowed_fd(to), + state, + flags.bits(), + )) +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn copyfile_state_alloc() -> io::Result { + extern "C" { + fn copyfile_state_alloc() -> copyfile_state_t; + } + + let result = unsafe { copyfile_state_alloc() }; + if result.0.is_null() { + Err(io::Errno::last_os_error()) + } else { + Ok(result) + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { + extern "C" { + fn copyfile_state_free(state: copyfile_state_t) -> c::c_int; + } + + nonnegative_ret(copyfile_state_free(state)) +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +const COPYFILE_STATE_COPIED: u32 = 8; + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) unsafe fn copyfile_state_get_copied(state: copyfile_state_t) -> io::Result { + let mut copied = MaybeUninit::::uninit(); + copyfile_state_get(state, COPYFILE_STATE_COPIED, copied.as_mut_ptr().cast())?; + Ok(copied.assume_init()) +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) unsafe fn copyfile_state_get( + state: copyfile_state_t, + flag: u32, + dst: *mut c::c_void, +) -> io::Result<()> { + extern "C" { + fn copyfile_state_get(state: copyfile_state_t, flag: u32, dst: *mut c::c_void) -> c::c_int; + } + + nonnegative_ret(copyfile_state_get(state, flag, dst)) +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result { + // The use of PATH_MAX is generally not encouraged, but it + // is inevitable in this case because macOS defines `fcntl` with + // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no + // alternatives. If a better method is invented, it should be used + // instead. + let mut buf = alloc::vec![0; c::PATH_MAX as usize]; + + // From the [macOS `fcntl` man page]: + // `F_GETPATH` - Get the path of the file descriptor `Fildes`. The argument + // must be a buffer of size `MAXPATHLEN` or greater. + // + // [macOS `fcntl` man page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html + unsafe { + ret(c::fcntl(borrowed_fd(fd), c::F_GETPATH, buf.as_mut_ptr()))?; + } + + let l = buf.iter().position(|&c| c == 0).unwrap(); + buf.truncate(l); + + // TODO: On Rust 1.56, we can use `shrink_to` here. + //buf.shrink_to(l + 1); + buf.shrink_to_fit(); + + Ok(CString::new(buf).unwrap()) +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn fcntl_rdadvise(fd: BorrowedFd<'_>, offset: u64, len: u64) -> io::Result<()> { + // From the [macOS `fcntl` man page]: + // `F_RDADVISE` - Issue an advisory read async with no copy to user. + // + // The `F_RDADVISE` command operates on the following structure which holds + // information passed from the user to the system: + // + // ```c + // struct radvisory { + // off_t ra_offset; /* offset into the file */ + // int ra_count; /* size of the read */ + // }; + // ``` + // + // [macOS `fcntl` man page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html + let ra_offset = match offset.try_into() { + Ok(len) => len, + // If this conversion fails, the user is providing an offset outside + // any possible file extent, so just ignore it. + Err(_) => return Ok(()), + }; + let ra_count = match len.try_into() { + Ok(len) => len, + // If this conversion fails, the user is providing a dubiously large + // hint which is unlikely to improve performance. + Err(_) => return Ok(()), + }; + unsafe { + let radvisory = c::radvisory { + ra_offset, + ra_count, + }; + ret(c::fcntl(borrowed_fd(fd), c::F_RDADVISE, &radvisory)) + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn fcntl_fullfsync(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_FULLFSYNC)) } +} + +/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist` +/// arguments. +#[cfg(any(target_os = "ios", target_os = "macos"))] +fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrlist) { + // ABI details. + const ATTR_CMN_MODTIME: u32 = 0x0000_0400; + const ATTR_CMN_ACCTIME: u32 = 0x0000_1000; + const ATTR_BIT_MAP_COUNT: u16 = 5; + + let mut times = times.clone(); + + // If we have any `UTIME_NOW` elements, replace them with the current time. + if times.last_access.tv_nsec == c::UTIME_NOW || times.last_modification.tv_nsec == c::UTIME_NOW + { + let now = { + let mut tv = c::timeval { + tv_sec: 0, + tv_usec: 0, + }; + unsafe { + let r = c::gettimeofday(&mut tv, null_mut()); + assert_eq!(r, 0); + } + c::timespec { + tv_sec: tv.tv_sec, + tv_nsec: (tv.tv_usec * 1000) as _, + } + }; + if times.last_access.tv_nsec == c::UTIME_NOW { + times.last_access = now; + } + if times.last_modification.tv_nsec == c::UTIME_NOW { + times.last_modification = now; + } + } + + // Pack the return values following the rules for [`getattrlist`]. + // + // [`getattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getattrlist.2.html + let mut times_size = 0; + let mut attrs = Attrlist { + bitmapcount: ATTR_BIT_MAP_COUNT, + reserved: 0, + commonattr: 0, + volattr: 0, + dirattr: 0, + fileattr: 0, + forkattr: 0, + }; + let mut return_times = [c::timespec { + tv_sec: 0, + tv_nsec: 0, + }; 2]; + let mut times_index = 0; + if times.last_modification.tv_nsec != c::UTIME_OMIT { + attrs.commonattr |= ATTR_CMN_MODTIME; + return_times[times_index] = times.last_modification; + times_index += 1; + times_size += size_of::(); + } + if times.last_access.tv_nsec != c::UTIME_OMIT { + attrs.commonattr |= ATTR_CMN_ACCTIME; + return_times[times_index] = times.last_access; + times_size += size_of::(); + } + + (times_size, return_times, attrs) +} + +/// Support type for `Attrlist`. +#[cfg(any(target_os = "ios", target_os = "macos"))] +type Attrgroup = u32; + +/// Attribute list for use with `setattrlist`. +#[cfg(any(target_os = "ios", target_os = "macos"))] +#[repr(C)] +struct Attrlist { + bitmapcount: u16, + reserved: u16, + commonattr: Attrgroup, + volattr: Attrgroup, + dirattr: Attrgroup, + fileattr: Attrgroup, + forkattr: Attrgroup, +} diff --git a/vendor/rustix/src/backend/libc/fs/types.rs b/vendor/rustix/src/backend/libc/fs/types.rs new file mode 100644 index 000000000..8d8ec08bf --- /dev/null +++ b/vendor/rustix/src/backend/libc/fs/types.rs @@ -0,0 +1,1116 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `*_OK` constants for use with [`accessat`]. + /// + /// [`accessat`]: fn.accessat.html + pub struct Access: c::c_int { + /// `R_OK` + const READ_OK = c::R_OK; + + /// `W_OK` + const WRITE_OK = c::W_OK; + + /// `X_OK` + const EXEC_OK = c::X_OK; + + /// `F_OK` + const EXISTS = c::F_OK; + } +} + +#[cfg(not(target_os = "redox"))] +bitflags! { + /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` + /// functions. + /// + /// [`openat`]: crate::fs::openat + /// [`statat`]: crate::fs::statat + pub struct AtFlags: c::c_int { + /// `AT_REMOVEDIR` + const REMOVEDIR = c::AT_REMOVEDIR; + + /// `AT_SYMLINK_FOLLOW` + const SYMLINK_FOLLOW = c::AT_SYMLINK_FOLLOW; + + /// `AT_SYMLINK_NOFOLLOW` + const SYMLINK_NOFOLLOW = c::AT_SYMLINK_NOFOLLOW; + + /// `AT_EMPTY_PATH` + #[cfg(any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + ))] + const EMPTY_PATH = c::AT_EMPTY_PATH; + + /// `AT_EACCESS` + #[cfg(not(any(target_os = "emscripten", target_os = "android")))] + const EACCESS = c::AT_EACCESS; + + /// `AT_STATX_SYNC_AS_STAT` + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const STATX_SYNC_AS_STAT = c::AT_STATX_SYNC_AS_STAT; + + /// `AT_STATX_FORCE_SYNC` + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const STATX_FORCE_SYNC = c::AT_STATX_FORCE_SYNC; + + /// `AT_STATX_DONT_SYNC` + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const STATX_DONT_SYNC = c::AT_STATX_DONT_SYNC; + } +} + +bitflags! { + /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. + /// + /// [`openat`]: crate::fs::openat + /// [`chmodat`]: crate::fs::chmodat + /// [`fchmod`]: crate::fs::fchmod + pub struct Mode: RawMode { + /// `S_IRWXU` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const RWXU = c::S_IRWXU as RawMode; + + /// `S_IRUSR` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const RUSR = c::S_IRUSR as RawMode; + + /// `S_IWUSR` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const WUSR = c::S_IWUSR as RawMode; + + /// `S_IXUSR` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const XUSR = c::S_IXUSR as RawMode; + + /// `S_IRWXG` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const RWXG = c::S_IRWXG as RawMode; + + /// `S_IRGRP` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const RGRP = c::S_IRGRP as RawMode; + + /// `S_IWGRP` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const WGRP = c::S_IWGRP as RawMode; + + /// `S_IXGRP` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const XGRP = c::S_IXGRP as RawMode; + + /// `S_IRWXO` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const RWXO = c::S_IRWXO as RawMode; + + /// `S_IROTH` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const ROTH = c::S_IROTH as RawMode; + + /// `S_IWOTH` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const WOTH = c::S_IWOTH as RawMode; + + /// `S_IXOTH` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const XOTH = c::S_IXOTH as RawMode; + + /// `S_ISUID` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const SUID = c::S_ISUID as RawMode; + + /// `S_ISGID` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const SGID = c::S_ISGID as RawMode; + + /// `S_ISVTX` + #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. + const SVTX = c::S_ISVTX as RawMode; + } +} + +impl Mode { + /// Construct a `Mode` from the mode bits of the `st_mode` field of + /// a `Stat`. + #[inline] + pub const fn from_raw_mode(st_mode: RawMode) -> Self { + Self::from_bits_truncate(st_mode) + } + + /// Construct an `st_mode` value from `Stat`. + #[inline] + pub const fn as_raw_mode(self) -> RawMode { + self.bits() + } +} + +bitflags! { + /// `O_*` constants for use with [`openat`]. + /// + /// [`openat`]: crate::fs::openat + pub struct OFlags: c::c_int { + /// `O_ACCMODE` + const ACCMODE = c::O_ACCMODE; + + /// Similar to `ACCMODE`, but just includes the read/write flags, and + /// no other flags. + /// + /// Some implementations include `O_PATH` in `O_ACCMODE`, when + /// sometimes we really just want the read/write bits. Caution is + /// indicated, as the presence of `O_PATH` may mean that the read/write + /// bits don't have their usual meaning. + const RWMODE = c::O_RDONLY | c::O_WRONLY | c::O_RDWR; + + /// `O_APPEND` + const APPEND = c::O_APPEND; + + /// `O_CREAT` + #[doc(alias = "CREAT")] + const CREATE = c::O_CREAT; + + /// `O_DIRECTORY` + const DIRECTORY = c::O_DIRECTORY; + + /// `O_DSYNC` + #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "redox")))] + const DSYNC = c::O_DSYNC; + + /// `O_EXCL` + const EXCL = c::O_EXCL; + + /// `O_FSYNC` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + all(target_os = "linux", not(target_env = "musl")), + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + const FSYNC = c::O_FSYNC; + + /// `O_NOFOLLOW` + const NOFOLLOW = c::O_NOFOLLOW; + + /// `O_NONBLOCK` + const NONBLOCK = c::O_NONBLOCK; + + /// `O_RDONLY` + const RDONLY = c::O_RDONLY; + + /// `O_WRONLY` + const WRONLY = c::O_WRONLY; + + /// `O_RDWR` + const RDWR = c::O_RDWR; + + /// `O_NOCTTY` + #[cfg(not(target_os = "redox"))] + const NOCTTY = c::O_NOCTTY; + + /// `O_RSYNC` + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + ))] + const RSYNC = c::O_RSYNC; + + /// `O_SYNC` + #[cfg(not(target_os = "redox"))] + const SYNC = c::O_SYNC; + + /// `O_TRUNC` + const TRUNC = c::O_TRUNC; + + /// `O_PATH` + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux", + target_os = "redox", + ))] + const PATH = c::O_PATH; + + /// `O_CLOEXEC` + const CLOEXEC = c::O_CLOEXEC; + + /// `O_TMPFILE` + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux", + ))] + const TMPFILE = c::O_TMPFILE; + + /// `O_NOATIME` + #[cfg(any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux", + ))] + const NOATIME = c::O_NOATIME; + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +bitflags! { + /// `CLONE_*` constants for use with [`fclonefileat`]. + /// + /// [`fclonefileat`]: crate::fs::fclonefileat + pub struct CloneFlags: c::c_int { + /// `CLONE_NOFOLLOW` + const NOFOLLOW = 1; + + /// `CLONE_NOOWNERCOPY` + const NOOWNERCOPY = 2; + } +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +mod copyfile { + pub(super) const ACL: u32 = 1 << 0; + pub(super) const STAT: u32 = 1 << 1; + pub(super) const XATTR: u32 = 1 << 2; + pub(super) const DATA: u32 = 1 << 3; + pub(super) const SECURITY: u32 = STAT | ACL; + pub(super) const METADATA: u32 = SECURITY | XATTR; + pub(super) const ALL: u32 = METADATA | DATA; +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +bitflags! { + /// `COPYFILE_*` constants. + pub struct CopyfileFlags: c::c_uint { + /// `COPYFILE_ACL` + const ACL = copyfile::ACL; + + /// `COPYFILE_STAT` + const STAT = copyfile::STAT; + + /// `COPYFILE_XATTR` + const XATTR = copyfile::XATTR; + + /// `COPYFILE_DATA` + const DATA = copyfile::DATA; + + /// `COPYFILE_SECURITY` + const SECURITY = copyfile::SECURITY; + + /// `COPYFILE_METADATA` + const METADATA = copyfile::METADATA; + + /// `COPYFILE_ALL` + const ALL = copyfile::ALL; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `RESOLVE_*` constants for use with [`openat2`]. + /// + /// [`openat2`]: crate::fs::openat2 + #[derive(Default)] + pub struct ResolveFlags: u64 { + /// `RESOLVE_NO_XDEV` + const NO_XDEV = 0x01; + + /// `RESOLVE_NO_MAGICLINKS` + const NO_MAGICLINKS = 0x02; + + /// `RESOLVE_NO_SYMLINKS` + const NO_SYMLINKS = 0x04; + + /// `RESOLVE_BENEATH` + const BENEATH = 0x08; + + /// `RESOLVE_IN_ROOT` + const IN_ROOT = 0x10; + + /// `RESOLVE_CACHED` (since Linux 5.12) + const CACHED = 0x20; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `RENAME_*` constants for use with [`renameat_with`]. + /// + /// [`renameat_with`]: crate::fs::renameat_with + pub struct RenameFlags: c::c_uint { + /// `RENAME_EXCHANGE` + const EXCHANGE = c::RENAME_EXCHANGE as _; + + /// `RENAME_NOREPLACE` + const NOREPLACE = c::RENAME_NOREPLACE as _; + + /// `RENAME_WHITEOUT` + const WHITEOUT = c::RENAME_WHITEOUT as _; + } +} + +/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. +/// +/// [`mknodat`]: crate::fs::mknodat +/// [`Stat`]: crate::fs::Stat +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum FileType { + /// `S_IFREG` + RegularFile = c::S_IFREG as isize, + + /// `S_IFDIR` + Directory = c::S_IFDIR as isize, + + /// `S_IFLNK` + Symlink = c::S_IFLNK as isize, + + /// `S_IFIFO` + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. + #[doc(alias = "IFO")] + Fifo = c::S_IFIFO as isize, + + /// `S_IFSOCK` + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. + Socket = c::S_IFSOCK as isize, + + /// `S_IFCHR` + CharacterDevice = c::S_IFCHR as isize, + + /// `S_IFBLK` + BlockDevice = c::S_IFBLK as isize, + + /// An unknown filesystem object. + Unknown, +} + +impl FileType { + /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of + /// a `Stat`. + pub const fn from_raw_mode(st_mode: RawMode) -> Self { + match (st_mode as c::mode_t) & c::S_IFMT { + c::S_IFREG => Self::RegularFile, + c::S_IFDIR => Self::Directory, + c::S_IFLNK => Self::Symlink, + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. + c::S_IFIFO => Self::Fifo, + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. + c::S_IFSOCK => Self::Socket, + c::S_IFCHR => Self::CharacterDevice, + c::S_IFBLK => Self::BlockDevice, + _ => Self::Unknown, + } + } + + /// Construct an `st_mode` value from `Stat`. + pub const fn as_raw_mode(self) -> RawMode { + match self { + Self::RegularFile => c::S_IFREG as RawMode, + Self::Directory => c::S_IFDIR as RawMode, + Self::Symlink => c::S_IFLNK as RawMode, + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. + Self::Fifo => c::S_IFIFO as RawMode, + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. + Self::Socket => c::S_IFSOCK as RawMode, + Self::CharacterDevice => c::S_IFCHR as RawMode, + Self::BlockDevice => c::S_IFBLK as RawMode, + Self::Unknown => c::S_IFMT as RawMode, + } + } + + /// Construct a `FileType` from the `d_type` field of a `c::dirent`. + #[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris" + )))] + pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { + match d_type { + c::DT_REG => Self::RegularFile, + c::DT_DIR => Self::Directory, + c::DT_LNK => Self::Symlink, + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_SOCK`. + c::DT_SOCK => Self::Socket, + #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_FIFO`. + c::DT_FIFO => Self::Fifo, + c::DT_CHR => Self::CharacterDevice, + c::DT_BLK => Self::BlockDevice, + // c::DT_UNKNOWN | + _ => Self::Unknown, + } + } +} + +/// `POSIX_FADV_*` constants for use with [`fadvise`]. +/// +/// [`fadvise`]: crate::fs::fadvise +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(u32)] +pub enum Advice { + /// `POSIX_FADV_NORMAL` + Normal = c::POSIX_FADV_NORMAL as c::c_uint, + + /// `POSIX_FADV_SEQUENTIAL` + Sequential = c::POSIX_FADV_SEQUENTIAL as c::c_uint, + + /// `POSIX_FADV_RANDOM` + Random = c::POSIX_FADV_RANDOM as c::c_uint, + + /// `POSIX_FADV_NOREUSE` + NoReuse = c::POSIX_FADV_NOREUSE as c::c_uint, + + /// `POSIX_FADV_WILLNEED` + WillNeed = c::POSIX_FADV_WILLNEED as c::c_uint, + + /// `POSIX_FADV_DONTNEED` + DontNeed = c::POSIX_FADV_DONTNEED as c::c_uint, +} + +#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] +bitflags! { + /// `MFD_*` constants for use with [`memfd_create`]. + /// + /// [`memfd_create`]: crate::fs::memfd_create + pub struct MemfdFlags: c::c_uint { + /// `MFD_CLOEXEC` + const CLOEXEC = c::MFD_CLOEXEC; + + /// `MFD_ALLOW_SEALING` + const ALLOW_SEALING = c::MFD_ALLOW_SEALING; + + /// `MFD_HUGETLB` (since Linux 4.14) + const HUGETLB = c::MFD_HUGETLB; + + /// `MFD_HUGE_64KB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_64KB = c::MFD_HUGE_64KB; + /// `MFD_HUGE_512JB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_512KB = c::MFD_HUGE_512KB; + /// `MFD_HUGE_1MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_1MB = c::MFD_HUGE_1MB; + /// `MFD_HUGE_2MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_2MB = c::MFD_HUGE_2MB; + /// `MFD_HUGE_8MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_8MB = c::MFD_HUGE_8MB; + /// `MFD_HUGE_16MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_16MB = c::MFD_HUGE_16MB; + /// `MFD_HUGE_32MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_32MB = c::MFD_HUGE_32MB; + /// `MFD_HUGE_256MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_256MB = c::MFD_HUGE_256MB; + /// `MFD_HUGE_512MB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_512MB = c::MFD_HUGE_512MB; + /// `MFD_HUGE_1GB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_1GB = c::MFD_HUGE_1GB; + /// `MFD_HUGE_2GB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_2GB = c::MFD_HUGE_2GB; + /// `MFD_HUGE_16GB` + #[cfg(any(target_os = "android", target_os = "linux"))] + const HUGE_16GB = c::MFD_HUGE_16GB; + } +} + +#[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "linux", +))] +bitflags! { + /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and + /// [`fcntl_get_seals`]. + /// + /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals + /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals + pub struct SealFlags: i32 { + /// `F_SEAL_SEAL`. + const SEAL = c::F_SEAL_SEAL; + /// `F_SEAL_SHRINK`. + const SHRINK = c::F_SEAL_SHRINK; + /// `F_SEAL_GROW`. + const GROW = c::F_SEAL_GROW; + /// `F_SEAL_WRITE`. + const WRITE = c::F_SEAL_WRITE; + /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) + #[cfg(any(target_os = "android", target_os = "linux"))] + const FUTURE_WRITE = c::F_SEAL_FUTURE_WRITE; + } +} + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +bitflags! { + /// `STATX_*` constants for use with [`statx`]. + /// + /// [`statx`]: crate::fs::statx + pub struct StatxFlags: u32 { + /// `STATX_TYPE` + const TYPE = c::STATX_TYPE; + + /// `STATX_MODE` + const MODE = c::STATX_MODE; + + /// `STATX_NLINK` + const NLINK = c::STATX_NLINK; + + /// `STATX_UID` + const UID = c::STATX_UID; + + /// `STATX_GID` + const GID = c::STATX_GID; + + /// `STATX_ATIME` + const ATIME = c::STATX_ATIME; + + /// `STATX_MTIME` + const MTIME = c::STATX_MTIME; + + /// `STATX_CTIME` + const CTIME = c::STATX_CTIME; + + /// `STATX_INO` + const INO = c::STATX_INO; + + /// `STATX_SIZE` + const SIZE = c::STATX_SIZE; + + /// `STATX_BLOCKS` + const BLOCKS = c::STATX_BLOCKS; + + /// `STATX_BASIC_STATS` + const BASIC_STATS = c::STATX_BASIC_STATS; + + /// `STATX_BTIME` + const BTIME = c::STATX_BTIME; + + /// `STATX_MNT_ID` (since Linux 5.8) + const MNT_ID = c::STATX_MNT_ID; + + /// `STATX_ALL` + const ALL = c::STATX_ALL; + } +} + +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "gnu")), +))] +bitflags! { + /// `STATX_*` constants for use with [`statx`]. + /// + /// [`statx`]: crate::fs::statx + pub struct StatxFlags: u32 { + /// `STATX_TYPE` + const TYPE = 0x0001; + + /// `STATX_MODE` + const MODE = 0x0002; + + /// `STATX_NLINK` + const NLINK = 0x0004; + + /// `STATX_UID` + const UID = 0x0008; + + /// `STATX_GID` + const GID = 0x0010; + + /// `STATX_ATIME` + const ATIME = 0x0020; + + /// `STATX_MTIME` + const MTIME = 0x0040; + + /// `STATX_CTIME` + const CTIME = 0x0080; + + /// `STATX_INO` + const INO = 0x0100; + + /// `STATX_SIZE` + const SIZE = 0x0200; + + /// `STATX_BLOCKS` + const BLOCKS = 0x0400; + + /// `STATX_BASIC_STATS` + const BASIC_STATS = 0x07ff; + + /// `STATX_BTIME` + const BTIME = 0x800; + + /// `STATX_MNT_ID` (since Linux 5.8) + const MNT_ID = 0x1000; + + /// `STATX_ALL` + const ALL = 0xfff; + } +} + +#[cfg(not(any( + target_os = "aix", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +bitflags! { + /// `FALLOC_FL_*` constants for use with [`fallocate`]. + /// + /// [`fallocate`]: crate::fs::fallocate + pub struct FallocateFlags: i32 { + /// `FALLOC_FL_KEEP_SIZE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + const KEEP_SIZE = c::FALLOC_FL_KEEP_SIZE; + /// `FALLOC_FL_PUNCH_HOLE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + const PUNCH_HOLE = c::FALLOC_FL_PUNCH_HOLE; + /// `FALLOC_FL_NO_HIDE_STALE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "wasi", + )))] + const NO_HIDE_STALE = c::FALLOC_FL_NO_HIDE_STALE; + /// `FALLOC_FL_COLLAPSE_RANGE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "emscripten", + target_os = "wasi", + )))] + const COLLAPSE_RANGE = c::FALLOC_FL_COLLAPSE_RANGE; + /// `FALLOC_FL_ZERO_RANGE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "emscripten", + target_os = "wasi", + )))] + const ZERO_RANGE = c::FALLOC_FL_ZERO_RANGE; + /// `FALLOC_FL_INSERT_RANGE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "emscripten", + target_os = "wasi", + )))] + const INSERT_RANGE = c::FALLOC_FL_INSERT_RANGE; + /// `FALLOC_FL_UNSHARE_RANGE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "emscripten", + target_os = "wasi", + )))] + const UNSHARE_RANGE = c::FALLOC_FL_UNSHARE_RANGE; + } +} + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +bitflags! { + /// `ST_*` constants for use with [`StatVfs`]. + pub struct StatVfsMountFlags: u64 { + /// `ST_MANDLOCK` + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + const MANDLOCK = libc::ST_MANDLOCK as u64; + + /// `ST_NOATIME` + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + const NOATIME = libc::ST_NOATIME as u64; + + /// `ST_NODEV` + #[cfg(any(target_os = "aix", target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + const NODEV = libc::ST_NODEV as u64; + + /// `ST_NODIRATIME` + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + const NODIRATIME = libc::ST_NODIRATIME as u64; + + /// `ST_NOEXEC` + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + const NOEXEC = libc::ST_NOEXEC as u64; + + /// `ST_NOSUID` + const NOSUID = libc::ST_NOSUID as u64; + + /// `ST_RDONLY` + const RDONLY = libc::ST_RDONLY as u64; + + /// `ST_RELATIME` + #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] + const RELATIME = libc::ST_RELATIME as u64; + + /// `ST_SYNCHRONOUS` + #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", target_os = "linux"))] + const SYNCHRONOUS = libc::ST_SYNCHRONOUS as u64; + } +} + +/// `LOCK_*` constants for use with [`flock`] +/// +/// [`flock`]: crate::fs::flock +#[cfg(not(any(target_os = "solaris", target_os = "wasi")))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(i32)] +pub enum FlockOperation { + /// `LOCK_SH` + LockShared = c::LOCK_SH, + /// `LOCK_EX` + LockExclusive = c::LOCK_EX, + /// `LOCK_UN` + Unlock = c::LOCK_UN, + /// `LOCK_SH | LOCK_NB` + NonBlockingLockShared = c::LOCK_SH | c::LOCK_NB, + /// `LOCK_EX | LOCK_NB` + NonBlockingLockExclusive = c::LOCK_EX | c::LOCK_NB, + /// `LOCK_UN | LOCK_NB` + NonBlockingUnlock = c::LOCK_UN | c::LOCK_NB, +} + +/// `struct stat` for use with [`statat`] and [`fstat`]. +/// +/// [`statat`]: crate::fs::statat +/// [`fstat`]: crate::fs::fstat +#[cfg(not(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +)))] +pub type Stat = c::stat; + +/// `struct stat` for use with [`statat`] and [`fstat`]. +/// +/// [`statat`]: crate::fs::statat +/// [`fstat`]: crate::fs::fstat +#[cfg(any( + all( + any(target_os = "android", target_os = "linux"), + target_pointer_width = "64", + ), + target_os = "emscripten", + target_os = "l4re", +))] +pub type Stat = c::stat64; + +/// `struct stat` for use with [`statat`] and [`fstat`]. +/// +/// [`statat`]: crate::fs::statat +/// [`fstat`]: crate::fs::fstat +// On 32-bit, Linux's `struct stat64` has a 32-bit `st_mtime` and friends, so +// we use our own struct, populated from `statx` where possible, to avoid the +// y2038 bug. +#[cfg(all( + any(target_os = "android", target_os = "linux"), + target_pointer_width = "32", +))] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[allow(missing_docs)] +pub struct Stat { + pub st_dev: u64, + pub st_mode: u32, + pub st_nlink: u32, + pub st_uid: u32, + pub st_gid: u32, + pub st_rdev: u64, + pub st_size: i64, + pub st_blksize: u32, + pub st_blocks: u64, + pub st_atime: u64, + pub st_atime_nsec: u32, + pub st_mtime: u64, + pub st_mtime_nsec: u32, + pub st_ctime: u64, + pub st_ctime_nsec: u32, + pub st_ino: u64, +} + +/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. +/// +/// [`statfs`]: crate::fs::statfs +/// [`fstatfs`]: crate::fs::fstatfs +#[cfg(not(any( + target_os = "android", + target_os = "emscripten", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "l4re", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[allow(clippy::module_name_repetitions)] +pub type StatFs = c::statfs; + +/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. +/// +/// [`statfs`]: crate::fs::statfs +/// [`fstatfs`]: crate::fs::fstatfs +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +))] +pub type StatFs = c::statfs64; + +/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`]. +/// +/// [`statvfs`]: crate::fs::statvfs +/// [`fstatvfs`]: crate::fs::fstatvfs +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[allow(missing_docs)] +pub struct StatVfs { + pub f_bsize: u64, + pub f_frsize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: u64, + pub f_flag: StatVfsMountFlags, + pub f_namemax: u64, +} + +/// `struct statx` for use with [`statx`]. +/// +/// [`statx`]: crate::fs::statx +#[cfg(all(target_os = "linux", target_env = "gnu"))] +// Use the glibc `struct statx`. +pub type Statx = c::statx; + +/// `struct statx_timestamp` for use with [`Statx`]. +#[cfg(all(target_os = "linux", target_env = "gnu"))] +// Use the glibc `struct statx_timestamp`. +pub type StatxTimestamp = c::statx; + +/// `struct statx` for use with [`statx`]. +/// +/// [`statx`]: crate::fs::statx +// Non-glibc ABIs don't currently declare a `struct statx`, so we declare it +// ourselves. +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "gnu")), +))] +#[repr(C)] +#[allow(missing_docs)] +pub struct Statx { + pub stx_mask: u32, + pub stx_blksize: u32, + pub stx_attributes: u64, + pub stx_nlink: u32, + pub stx_uid: u32, + pub stx_gid: u32, + pub stx_mode: u16, + __statx_pad1: [u16; 1], + pub stx_ino: u64, + pub stx_size: u64, + pub stx_blocks: u64, + pub stx_attributes_mask: u64, + pub stx_atime: StatxTimestamp, + pub stx_btime: StatxTimestamp, + pub stx_ctime: StatxTimestamp, + pub stx_mtime: StatxTimestamp, + pub stx_rdev_major: u32, + pub stx_rdev_minor: u32, + pub stx_dev_major: u32, + pub stx_dev_minor: u32, + pub stx_mnt_id: u64, + __statx_pad2: u64, + __statx_pad3: [u64; 12], +} + +/// `struct statx_timestamp` for use with [`Statx`]. +// Non-glibc ABIs don't currently declare a `struct statx_timestamp`, so we +// declare it ourselves. +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "gnu")), +))] +#[repr(C)] +#[allow(missing_docs)] +pub struct StatxTimestamp { + pub tv_sec: i64, + pub tv_nsec: u32, + pub __statx_timestamp_pad1: [i32; 1], +} + +/// `mode_t` +#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] +pub type RawMode = c::mode_t; + +/// `mode_t` +#[cfg(all(target_os = "android", target_pointer_width = "32"))] +pub type RawMode = c::c_uint; + +/// `dev_t` +#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] +pub type Dev = c::dev_t; + +/// `dev_t` +#[cfg(all(target_os = "android", target_pointer_width = "32"))] +pub type Dev = c::c_ulonglong; + +/// `__fsword_t` +#[cfg(all( + target_os = "linux", + not(target_env = "musl"), + not(target_arch = "s390x"), +))] +pub type FsWord = c::__fsword_t; + +/// `__fsword_t` +#[cfg(all( + any(target_os = "android", all(target_os = "linux", target_env = "musl")), + target_pointer_width = "32", +))] +pub type FsWord = u32; + +/// `__fsword_t` +#[cfg(all( + any(target_os = "android", all(target_os = "linux", target_env = "musl")), + not(target_arch = "s390x"), + target_pointer_width = "64", +))] +pub type FsWord = u64; + +/// `__fsword_t` +// s390x uses `u32` for `statfs` entries, even though `__fsword_t` is `u64`. +#[cfg(all(target_os = "linux", target_arch = "s390x"))] +pub type FsWord = u32; + +#[cfg(not(target_os = "redox"))] +pub use c::{UTIME_NOW, UTIME_OMIT}; + +/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. +#[cfg(all( + any(target_os = "android", target_os = "linux"), + not(target_env = "musl"), +))] +pub const PROC_SUPER_MAGIC: FsWord = c::PROC_SUPER_MAGIC as FsWord; + +/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. +#[cfg(all( + any(target_os = "android", target_os = "linux"), + not(target_env = "musl"), +))] +pub const NFS_SUPER_MAGIC: FsWord = c::NFS_SUPER_MAGIC as FsWord; + +/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. +#[cfg(all(any(target_os = "android", target_os = "linux"), target_env = "musl"))] +pub const PROC_SUPER_MAGIC: FsWord = 0x0000_9fa0; + +/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. +#[cfg(all(any(target_os = "android", target_os = "linux"), target_env = "musl"))] +pub const NFS_SUPER_MAGIC: FsWord = 0x0000_6969; + +/// `copyfile_state_t`—State for use with [`fcopyfile`]. +/// +/// [`fcopyfile`]: crate::fs::fcopyfile +#[cfg(any(target_os = "ios", target_os = "macos"))] +#[allow(non_camel_case_types)] +#[repr(transparent)] +#[derive(Copy, Clone)] +pub struct copyfile_state_t(pub(crate) *mut c::c_void); diff --git a/vendor/rustix/src/backend/libc/io/epoll.rs b/vendor/rustix/src/backend/libc/io/epoll.rs new file mode 100644 index 000000000..3205a613f --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/epoll.rs @@ -0,0 +1,573 @@ +//! epoll support. +//! +//! This is an experiment, and it isn't yet clear whether epoll is the right +//! level of abstraction at which to introduce safety. But it works fairly well +//! in simple examples 🙂. +//! +//! # Examples +//! +//! ```rust,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::{self, Epoll}; +//! use rustix::io::{ioctl_fionbio, read, write}; +//! use rustix::net::{ +//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4, +//! SocketType, +//! }; +//! use std::os::unix::io::AsRawFd; +//! +//! // Create a socket and listen on it. +//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; +//! 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::new(epoll::CreateFlags::CLOEXEC, epoll::Owning::new())?; +//! +//! // Remember the socket raw fd, which we use for comparisons only. +//! let raw_listen_sock = listen_sock.as_fd().as_raw_fd(); +//! +//! // Register the socket with the epoll object. +//! epoll.add(listen_sock, epoll::EventFlags::IN)?; +//! +//! // Process events. +//! let mut event_list = epoll::EventVec::with_capacity(4); +//! loop { +//! epoll.wait(&mut event_list, -1)?; +//! for (_event_flags, target) in &event_list { +//! if target.as_raw_fd() == raw_listen_sock { +//! // 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(&*target)?; +//! ioctl_fionbio(&conn_sock, true)?; +//! epoll.add(conn_sock, epoll::EventFlags::OUT | epoll::EventFlags::ET)?; +//! } else { +//! // Write a message to the stream and then unregister it. +//! write(&*target, b"hello\n")?; +//! let _ = epoll.del(target)?; +//! } +//! } +//! } +//! # } +//! # #[cfg(not(feature = "net"))] +//! # fn main() {} +//! ``` + +use super::super::c; +use super::super::conv::{ret, ret_owned_fd, ret_u32}; +use crate::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}; +#[cfg(not(feature = "rustc-dep-of-std"))] +use crate::fd::{FromRawFd, IntoRawFd}; +use crate::io; +use alloc::vec::Vec; +use bitflags::bitflags; +use core::convert::TryInto; +use core::fmt; +use core::marker::PhantomData; +use core::ops::Deref; +use core::ptr::{null, null_mut}; + +bitflags! { + /// `EPOLL_*` for use with [`Epoll::new`]. + pub struct CreateFlags: c::c_int { + /// `EPOLL_CLOEXEC` + const CLOEXEC = c::EPOLL_CLOEXEC; + } +} + +bitflags! { + /// `EPOLL*` for use with [`Epoll::add`]. + #[derive(Default)] + pub struct EventFlags: u32 { + /// `EPOLLIN` + const IN = c::EPOLLIN as u32; + + /// `EPOLLOUT` + const OUT = c::EPOLLOUT as u32; + + /// `EPOLLPRI` + const PRI = c::EPOLLPRI as u32; + + /// `EPOLLERR` + const ERR = c::EPOLLERR as u32; + + /// `EPOLLHUP` + const HUP = c::EPOLLHUP as u32; + + /// `EPOLLET` + const ET = c::EPOLLET as u32; + + /// `EPOLLONESHOT` + const ONESHOT = c::EPOLLONESHOT as u32; + + /// `EPOLLWAKEUP` + const WAKEUP = c::EPOLLWAKEUP as u32; + + /// `EPOLLEXCLUSIVE` + #[cfg(not(target_os = "android"))] + const EXCLUSIVE = c::EPOLLEXCLUSIVE as u32; + } +} + +/// A reference to a `T`. +pub struct Ref<'a, T> { + t: T, + _phantom: PhantomData<&'a T>, +} + +impl<'a, T> Ref<'a, T> { + #[inline] + fn new(t: T) -> Self { + Self { + t, + _phantom: PhantomData, + } + } + + #[inline] + fn consume(self) -> T { + self.t + } +} + +impl<'a, T> Deref for Ref<'a, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.t + } +} + +impl<'a, T: fmt::Debug> fmt::Debug for Ref<'a, T> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.t.fmt(fmt) + } +} + +/// A trait for data stored within an [`Epoll`] instance. +pub trait Context { + /// The type of an element owned by this context. + type Data; + + /// The type of a value used to refer to an element owned by this context. + type Target: AsFd; + + /// Assume ownership of `data`, and returning a `Target`. + fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target>; + + /// Encode `target` as a `u64`. The only requirement on this value is that + /// it be decodable by `decode`. + fn encode(&self, target: Ref<'_, Self::Target>) -> u64; + + /// Decode `raw`, which is a value encoded by `encode`, into a `Target`. + /// + /// # Safety + /// + /// `raw` must be a `u64` value returned from `encode`, from the same + /// context, and within the context's lifetime. + unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target>; + + /// Release ownership of the value referred to by `target` and return it. + fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data; +} + +/// A type implementing [`Context`] where the `Data` type is `BorrowedFd<'a>`. +pub struct Borrowing<'a> { + _phantom: PhantomData>, +} + +impl<'a> Context for Borrowing<'a> { + type Data = BorrowedFd<'a>; + type Target = BorrowedFd<'a>; + + #[inline] + fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { + Ref::new(data) + } + + #[inline] + fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { + target.as_raw_fd() as u64 + } + + #[inline] + unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { + Ref::new(BorrowedFd::<'a>::borrow_raw(raw as RawFd)) + } + + #[inline] + fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { + target.consume() + } +} + +/// A type implementing [`Context`] where the `Data` type is `T`, a type +/// implementing `From` and `From for OwnedFd`. +/// +/// This may be used with [`OwnedFd`], or higher-level types like +/// [`std::fs::File`] or [`std::net::TcpStream`]. +#[cfg(not(feature = "rustc-dep-of-std"))] +pub struct Owning<'context, T: Into + From> { + _phantom: PhantomData<&'context T>, +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: Into + From> Owning<'context, T> { + /// Creates a new empty `Owning`. + #[allow(clippy::new_without_default)] // This is a specialized type that doesn't need to be generically constructible. + #[inline] + pub fn new() -> Self { + Self { + _phantom: PhantomData, + } + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> Context for Owning<'context, T> { + type Data = T; + type Target = BorrowedFd<'context>; + + #[inline] + fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { + let fd: OwnedFd = data.into(); + let raw_fd = fd.into_raw_fd(); + // Safety: `epoll` will assign ownership of the file descriptor to the + // kernel epoll object. We use `Into`+`IntoRawFd` to consume + // the `Data` and extract the raw file descriptor and then "borrow" it + // with `borrow_raw` knowing that the borrow won't outlive the + // kernel epoll object. + unsafe { Ref::new(BorrowedFd::<'context>::borrow_raw(raw_fd)) } + } + + #[inline] + fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { + target.as_fd().as_raw_fd() as u64 + } + + #[inline] + unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { + Ref::new(BorrowedFd::<'context>::borrow_raw(raw as RawFd)) + } + + #[inline] + fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { + // The file descriptor was held by the kernel epoll object and is now + // being released, so we can create a new `OwnedFd` that assumes + // ownership. + let raw_fd = target.consume().as_raw_fd(); + unsafe { T::from(OwnedFd::from_raw_fd(raw_fd).into()) } + } +} + +/// An "epoll", an interface to an OS object allowing one to repeatedly wait +/// for events from a set of file descriptors efficiently. +pub struct Epoll { + epoll_fd: OwnedFd, + context: Context, +} + +impl Epoll { + /// `epoll_create1(flags)`—Creates a new `Epoll`. + /// + /// 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 new(flags: CreateFlags, context: Context) -> io::Result { + // Safety: We're calling `epoll_create1` via FFI and we know how it + // behaves. + unsafe { + Ok(Self { + epoll_fd: ret_owned_fd(c::epoll_create1(flags.bits()))?, + context, + }) + } + } + + /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an + /// `Epoll`. + /// + /// This registers interest in any of the events set in `events` occurring + /// on the file descriptor associated with `data`. + #[doc(alias = "epoll_ctl")] + pub fn add( + &self, + data: Context::Data, + event_flags: EventFlags, + ) -> io::Result> { + // Safety: We're calling `epoll_ctl` via FFI and we know how it + // behaves. + unsafe { + let target = self.context.acquire(data); + let raw_fd = target.as_fd().as_raw_fd(); + let encoded = self.context.encode(target); + ret(c::epoll_ctl( + self.epoll_fd.as_fd().as_raw_fd(), + c::EPOLL_CTL_ADD, + raw_fd, + &mut c::epoll_event { + events: event_flags.bits(), + r#u64: encoded, + }, + ))?; + Ok(self.context.decode(encoded)) + } + } + + /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in + /// this `Epoll`. + /// + /// This sets the events of interest with `target` to `events`. + #[doc(alias = "epoll_ctl")] + pub fn mod_( + &self, + target: Ref<'_, Context::Target>, + event_flags: EventFlags, + ) -> io::Result<()> { + let raw_fd = target.as_fd().as_raw_fd(); + let encoded = self.context.encode(target); + // Safety: We're calling `epoll_ctl` via FFI and we know how it + // behaves. + unsafe { + ret(c::epoll_ctl( + self.epoll_fd.as_fd().as_raw_fd(), + c::EPOLL_CTL_MOD, + raw_fd, + &mut c::epoll_event { + events: event_flags.bits(), + r#u64: encoded, + }, + )) + } + } + + /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in + /// this `Epoll`. + /// + /// This also returns the owning `Data`. + #[doc(alias = "epoll_ctl")] + pub fn del(&self, target: Ref<'_, Context::Target>) -> io::Result { + // Safety: We're calling `epoll_ctl` via FFI and we know how it + // behaves. + unsafe { + let raw_fd = target.as_fd().as_raw_fd(); + ret(c::epoll_ctl( + self.epoll_fd.as_fd().as_raw_fd(), + c::EPOLL_CTL_DEL, + raw_fd, + null_mut(), + ))?; + } + Ok(self.context.release(target)) + } + + /// `epoll_wait(self, events, timeout)`—Waits for registered events of + /// interest. + /// + /// For each event of interest, an element is written to `events`. On + /// success, this returns the number of written elements. + #[doc(alias = "epoll_wait")] + pub fn wait<'context>( + &'context self, + event_list: &mut EventVec<'context, Context>, + timeout: c::c_int, + ) -> io::Result<()> { + // Safety: We're calling `epoll_wait` via FFI and we know how it + // behaves. + unsafe { + event_list.events.set_len(0); + let nfds = ret_u32(c::epoll_wait( + self.epoll_fd.as_fd().as_raw_fd(), + event_list.events.as_mut_ptr().cast::(), + event_list.events.capacity().try_into().unwrap_or(i32::MAX), + timeout, + ))?; + event_list.events.set_len(nfds as usize); + event_list.context = &self.context; + } + + Ok(()) + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> AsRawFd for Epoll> { + fn as_raw_fd(&self) -> RawFd { + self.epoll_fd.as_raw_fd() + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> IntoRawFd for Epoll> { + fn into_raw_fd(self) -> RawFd { + self.epoll_fd.into_raw_fd() + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> FromRawFd for Epoll> { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + Self { + epoll_fd: OwnedFd::from_raw_fd(fd), + context: Owning::new(), + } + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> AsFd for Epoll> { + fn as_fd(&self) -> BorrowedFd<'_> { + self.epoll_fd.as_fd() + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> From>> + for OwnedFd +{ + fn from(epoll: Epoll>) -> Self { + epoll.epoll_fd + } +} + +#[cfg(not(feature = "rustc-dep-of-std"))] +impl<'context, T: AsFd + Into + From> From + for Epoll> +{ + fn from(fd: OwnedFd) -> Self { + Self { + epoll_fd: fd, + context: Owning::new(), + } + } +} + +/// An iterator over the `Event`s in an `EventVec`. +pub struct Iter<'context, Context: self::Context> { + iter: core::slice::Iter<'context, Event>, + context: *const Context, + _phantom: PhantomData<&'context Context>, +} + +impl<'context, Context: self::Context> Iterator for Iter<'context, Context> { + type Item = (EventFlags, Ref<'context, Context::Target>); + + fn next(&mut self) -> Option { + // Safety: `self.context` is guaranteed to be valid because we hold + // `'context` for it. And we know this event is associated with this + // context because `wait` sets both. + self.iter.next().map(|event| { + (event.event_flags, unsafe { + (*self.context).decode(event.encoded) + }) + }) + } +} + +/// A record of an event that occurred. +#[repr(C)] +#[cfg_attr( + any( + all( + target_arch = "x86", + not(target_env = "musl"), + not(target_os = "android"), + ), + target_arch = "x86_64", + ), + repr(packed) +)] +struct Event { + // Match the layout of `c::epoll_event`. We just use a `u64` instead of + // the full union; `Context` implementations will simply need to deal with + // casting the value into and out of the `u64` themselves. + event_flags: EventFlags, + encoded: u64, +} + +/// A vector of `Event`s, plus context for interpreting them. +pub struct EventVec<'context, Context: self::Context> { + events: Vec, + context: *const Context, + _phantom: PhantomData<&'context Context>, +} + +impl<'context, Context: self::Context> EventVec<'context, Context> { + /// Constructs an `EventVec` with memory for `capacity` `Event`s. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + Self { + events: Vec::with_capacity(capacity), + context: null(), + _phantom: PhantomData, + } + } + + /// Returns the current `Event` capacity of this `EventVec`. + #[inline] + pub fn capacity(&self) -> usize { + self.events.capacity() + } + + /// Reserves enough memory for at least `additional` more `Event`s. + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.events.reserve(additional); + } + + /// Reserves enough memory for exactly `additional` more `Event`s. + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + self.events.reserve_exact(additional); + } + + /// Clears all the `Events` out of this `EventVec`. + #[inline] + pub fn clear(&mut self) { + self.events.clear(); + } + + /// Shrinks the capacity of this `EventVec` as much as possible. + #[inline] + pub fn shrink_to_fit(&mut self) { + self.events.shrink_to_fit(); + } + + /// Returns an iterator over the `Event`s in this `EventVec`. + #[inline] + pub fn iter(&self) -> Iter<'_, Context> { + Iter { + iter: self.events.iter(), + context: self.context, + _phantom: PhantomData, + } + } + + /// Returns the number of `Event`s logically contained in this `EventVec`. + #[inline] + pub fn len(&mut self) -> usize { + self.events.len() + } + + /// Tests whether this `EventVec` is logically empty. + #[inline] + pub fn is_empty(&mut self) -> bool { + self.events.is_empty() + } +} + +impl<'context, Context: self::Context> IntoIterator for &'context EventVec<'context, Context> { + type IntoIter = Iter<'context, Context>; + type Item = (EventFlags, Ref<'context, Context::Target>); + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} diff --git a/vendor/rustix/src/backend/libc/io/errno.rs b/vendor/rustix/src/backend/libc/io/errno.rs new file mode 100644 index 000000000..131709e0c --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/errno.rs @@ -0,0 +1,1106 @@ +//! The `rustix` `Errno` type. +//! +//! This type holds an OS error code, which conceptually corresponds to an +//! `errno` value. + +use super::super::c; +use libc_errno::errno; + +/// The error type for `rustix` APIs. +/// +/// This is similar to `std::io::Error`, but only holds an OS error code, +/// and no extra error value. +#[repr(transparent)] +#[doc(alias = "errno")] +#[derive(Eq, PartialEq, Hash, Copy, Clone)] +pub struct Errno(pub(crate) c::c_int); + +impl Errno { + /// `EACCES` + #[doc(alias = "ACCES")] + pub const ACCESS: Self = Self(c::EACCES); + /// `EADDRINUSE` + pub const ADDRINUSE: Self = Self(c::EADDRINUSE); + /// `EADDRNOTAVAIL` + pub const ADDRNOTAVAIL: Self = Self(c::EADDRNOTAVAIL); + /// `EADV` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const ADV: Self = Self(c::EADV); + /// `EAFNOSUPPORT` + pub const AFNOSUPPORT: Self = Self(c::EAFNOSUPPORT); + /// `EAGAIN` + pub const AGAIN: Self = Self(c::EAGAIN); + /// `EALREADY` + pub const ALREADY: Self = Self(c::EALREADY); + /// `EAUTH` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const AUTH: Self = Self(c::EAUTH); + /// `EBADE` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const BADE: Self = Self(c::EBADE); + /// `EBADF` + pub const BADF: Self = Self(c::EBADF); + /// `EBADFD` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const BADFD: Self = Self(c::EBADFD); + /// `EBADMSG` + #[cfg(not(windows))] + pub const BADMSG: Self = Self(c::EBADMSG); + /// `EBADR` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const BADR: Self = Self(c::EBADR); + /// `EBADRPC` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const BADRPC: Self = Self(c::EBADRPC); + /// `EBADRQC` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const BADRQC: Self = Self(c::EBADRQC); + /// `EBADSLT` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const BADSLT: Self = Self(c::EBADSLT); + /// `EBFONT` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const BFONT: Self = Self(c::EBFONT); + /// `EBUSY` + #[cfg(not(windows))] + pub const BUSY: Self = Self(c::EBUSY); + /// `ECANCELED` + pub const CANCELED: Self = Self(c::ECANCELED); + /// `ECAPMODE` + #[cfg(any(target_os = "freebsd"))] + pub const CAPMODE: Self = Self(c::ECAPMODE); + /// `ECHILD` + #[cfg(not(windows))] + pub const CHILD: Self = Self(c::ECHILD); + /// `ECHRNG` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const CHRNG: Self = Self(c::ECHRNG); + /// `ECOMM` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const COMM: Self = Self(c::ECOMM); + /// `ECONNABORTED` + pub const CONNABORTED: Self = Self(c::ECONNABORTED); + /// `ECONNREFUSED` + pub const CONNREFUSED: Self = Self(c::ECONNREFUSED); + /// `ECONNRESET` + pub const CONNRESET: Self = Self(c::ECONNRESET); + /// `EDEADLK` + #[cfg(not(windows))] + pub const DEADLK: Self = Self(c::EDEADLK); + /// `EDEADLOCK` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const DEADLOCK: Self = Self(c::EDEADLOCK); + /// `EDESTADDRREQ` + pub const DESTADDRREQ: Self = Self(c::EDESTADDRREQ); + /// `EDISCON` + #[cfg(windows)] + pub const DISCON: Self = Self(c::EDISCON); + /// `EDOM` + #[cfg(not(windows))] + pub const DOM: Self = Self(c::EDOM); + /// `EDOOFUS` + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + pub const DOOFUS: Self = Self(c::EDOOFUS); + /// `EDOTDOT` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const DOTDOT: Self = Self(c::EDOTDOT); + /// `EDQUOT` + pub const DQUOT: Self = Self(c::EDQUOT); + /// `EEXIST` + #[cfg(not(windows))] + pub const EXIST: Self = Self(c::EEXIST); + /// `EFAULT` + pub const FAULT: Self = Self(c::EFAULT); + /// `EFBIG` + #[cfg(not(windows))] + pub const FBIG: Self = Self(c::EFBIG); + /// `EFTYPE` + #[cfg(any( + target_env = "newlib", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const FTYPE: Self = Self(c::EFTYPE); + /// `EHOSTDOWN` + #[cfg(not(target_os = "wasi"))] + pub const HOSTDOWN: Self = Self(c::EHOSTDOWN); + /// `EHOSTUNREACH` + pub const HOSTUNREACH: Self = Self(c::EHOSTUNREACH); + /// `EHWPOISON` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", + )))] + pub const HWPOISON: Self = Self(c::EHWPOISON); + /// `EIDRM` + #[cfg(not(windows))] + pub const IDRM: Self = Self(c::EIDRM); + /// `EILSEQ` + #[cfg(not(windows))] + pub const ILSEQ: Self = Self(c::EILSEQ); + /// `EINPROGRESS` + pub const INPROGRESS: Self = Self(c::EINPROGRESS); + /// `EINTR` + /// + /// For a convenient way to retry system calls that exit with `INTR`, use + /// [`retry_on_intr`]. + /// + /// [`retry_on_intr`]: crate::io::retry_on_intr + pub const INTR: Self = Self(c::EINTR); + /// `EINVAL` + pub const INVAL: Self = Self(c::EINVAL); + /// `EINVALIDPROCTABLE` + #[cfg(windows)] + pub const INVALIDPROCTABLE: Self = Self(c::EINVALIDPROCTABLE); + /// `EINVALIDPROVIDER` + #[cfg(windows)] + pub const INVALIDPROVIDER: Self = Self(c::EINVALIDPROVIDER); + /// `EIO` + #[cfg(not(windows))] + pub const IO: Self = Self(c::EIO); + /// `EISCONN` + pub const ISCONN: Self = Self(c::EISCONN); + /// `EISDIR` + #[cfg(not(windows))] + pub const ISDIR: Self = Self(c::EISDIR); + /// `EISNAM` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const ISNAM: Self = Self(c::EISNAM); + /// `EKEYEXPIRED` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const KEYEXPIRED: Self = Self(c::EKEYEXPIRED); + /// `EKEYREJECTED` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const KEYREJECTED: Self = Self(c::EKEYREJECTED); + /// `EKEYREVOKED` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const KEYREVOKED: Self = Self(c::EKEYREVOKED); + /// `EL2HLT` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const L2HLT: Self = Self(c::EL2HLT); + /// `EL2NSYNC` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const L2NSYNC: Self = Self(c::EL2NSYNC); + /// `EL3HLT` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const L3HLT: Self = Self(c::EL3HLT); + /// `EL3RST` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const L3RST: Self = Self(c::EL3RST); + /// `ELIBACC` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const LIBACC: Self = Self(c::ELIBACC); + /// `ELIBBAD` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const LIBBAD: Self = Self(c::ELIBBAD); + /// `ELIBEXEC` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const LIBEXEC: Self = Self(c::ELIBEXEC); + /// `ELIBMAX` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const LIBMAX: Self = Self(c::ELIBMAX); + /// `ELIBSCN` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const LIBSCN: Self = Self(c::ELIBSCN); + /// `ELNRNG` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const LNRNG: Self = Self(c::ELNRNG); + /// `ELOOP` + pub const LOOP: Self = Self(c::ELOOP); + /// `EMEDIUMTYPE` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const MEDIUMTYPE: Self = Self(c::EMEDIUMTYPE); + /// `EMFILE` + pub const MFILE: Self = Self(c::EMFILE); + /// `EMLINK` + #[cfg(not(windows))] + pub const MLINK: Self = Self(c::EMLINK); + /// `EMSGSIZE` + pub const MSGSIZE: Self = Self(c::EMSGSIZE); + /// `EMULTIHOP` + #[cfg(not(any(windows, target_os = "openbsd")))] + pub const MULTIHOP: Self = Self(c::EMULTIHOP); + /// `ENAMETOOLONG` + pub const NAMETOOLONG: Self = Self(c::ENAMETOOLONG); + /// `ENAVAIL` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const NAVAIL: Self = Self(c::ENAVAIL); + /// `ENEEDAUTH` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const NEEDAUTH: Self = Self(c::ENEEDAUTH); + /// `ENETDOWN` + pub const NETDOWN: Self = Self(c::ENETDOWN); + /// `ENETRESET` + pub const NETRESET: Self = Self(c::ENETRESET); + /// `ENETUNREACH` + pub const NETUNREACH: Self = Self(c::ENETUNREACH); + /// `ENFILE` + #[cfg(not(windows))] + pub const NFILE: Self = Self(c::ENFILE); + /// `ENOANO` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NOANO: Self = Self(c::ENOANO); + /// `ENOATTR` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const NOATTR: Self = Self(c::ENOATTR); + /// `ENOBUFS` + pub const NOBUFS: Self = Self(c::ENOBUFS); + /// `ENOCSI` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NOCSI: Self = Self(c::ENOCSI); + /// `ENODATA` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NODATA: Self = Self(c::ENODATA); + /// `ENODEV` + #[cfg(not(windows))] + pub const NODEV: Self = Self(c::ENODEV); + /// `ENOENT` + #[cfg(not(windows))] + pub const NOENT: Self = Self(c::ENOENT); + /// `ENOEXEC` + #[cfg(not(windows))] + pub const NOEXEC: Self = Self(c::ENOEXEC); + /// `ENOKEY` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const NOKEY: Self = Self(c::ENOKEY); + /// `ENOLCK` + #[cfg(not(windows))] + pub const NOLCK: Self = Self(c::ENOLCK); + /// `ENOLINK` + #[cfg(not(any(windows, target_os = "openbsd")))] + pub const NOLINK: Self = Self(c::ENOLINK); + /// `ENOMEDIUM` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const NOMEDIUM: Self = Self(c::ENOMEDIUM); + /// `ENOMEM` + #[cfg(not(windows))] + pub const NOMEM: Self = Self(c::ENOMEM); + /// `ENOMORE` + #[cfg(windows)] + pub const NOMORE: Self = Self(c::ENOMORE); + /// `ENOMSG` + #[cfg(not(windows))] + pub const NOMSG: Self = Self(c::ENOMSG); + /// `ENONET` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NONET: Self = Self(c::ENONET); + /// `ENOPKG` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NOPKG: Self = Self(c::ENOPKG); + /// `ENOPROTOOPT` + pub const NOPROTOOPT: Self = Self(c::ENOPROTOOPT); + /// `ENOSPC` + #[cfg(not(windows))] + pub const NOSPC: Self = Self(c::ENOSPC); + /// `ENOSR` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NOSR: Self = Self(c::ENOSR); + /// `ENOSTR` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NOSTR: Self = Self(c::ENOSTR); + /// `ENOSYS` + #[cfg(not(windows))] + pub const NOSYS: Self = Self(c::ENOSYS); + /// `ENOTBLK` + #[cfg(not(any(windows, target_os = "haiku", target_os = "wasi")))] + pub const NOTBLK: Self = Self(c::ENOTBLK); + /// `ENOTCAPABLE` + #[cfg(any(target_os = "freebsd", target_os = "wasi"))] + pub const NOTCAPABLE: Self = Self(c::ENOTCAPABLE); + /// `ENOTCONN` + pub const NOTCONN: Self = Self(c::ENOTCONN); + /// `ENOTDIR` + #[cfg(not(windows))] + pub const NOTDIR: Self = Self(c::ENOTDIR); + /// `ENOTEMPTY` + pub const NOTEMPTY: Self = Self(c::ENOTEMPTY); + /// `ENOTNAM` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const NOTNAM: Self = Self(c::ENOTNAM); + /// `ENOTRECOVERABLE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "haiku", + target_os = "netbsd" + )))] + pub const NOTRECOVERABLE: Self = Self(c::ENOTRECOVERABLE); + /// `ENOTSOCK` + pub const NOTSOCK: Self = Self(c::ENOTSOCK); + /// `ENOTSUP` + #[cfg(not(any(windows, target_os = "haiku", target_os = "redox")))] + pub const NOTSUP: Self = Self(c::ENOTSUP); + /// `ENOTTY` + #[cfg(not(windows))] + pub const NOTTY: Self = Self(c::ENOTTY); + /// `ENOTUNIQ` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const NOTUNIQ: Self = Self(c::ENOTUNIQ); + /// `ENXIO` + #[cfg(not(windows))] + pub const NXIO: Self = Self(c::ENXIO); + /// `EOPNOTSUPP` + pub const OPNOTSUPP: Self = Self(c::EOPNOTSUPP); + /// `EOVERFLOW` + #[cfg(not(windows))] + pub const OVERFLOW: Self = Self(c::EOVERFLOW); + /// `EOWNERDEAD` + #[cfg(not(any( + windows, + target_os = "haiku", + target_os = "dragonfly", + target_os = "netbsd" + )))] + pub const OWNERDEAD: Self = Self(c::EOWNERDEAD); + /// `EPERM` + #[cfg(not(windows))] + pub const PERM: Self = Self(c::EPERM); + /// `EPFNOSUPPORT` + #[cfg(not(target_os = "wasi"))] + pub const PFNOSUPPORT: Self = Self(c::EPFNOSUPPORT); + /// `EPIPE` + #[cfg(not(windows))] + pub const PIPE: Self = Self(c::EPIPE); + /// `EPROCLIM` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const PROCLIM: Self = Self(c::EPROCLIM); + /// `EPROCUNAVAIL` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const PROCUNAVAIL: Self = Self(c::EPROCUNAVAIL); + /// `EPROGMISMATCH` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const PROGMISMATCH: Self = Self(c::EPROGMISMATCH); + /// `EPROGUNAVAIL` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const PROGUNAVAIL: Self = Self(c::EPROGUNAVAIL); + /// `EPROTO` + #[cfg(not(windows))] + pub const PROTO: Self = Self(c::EPROTO); + /// `EPROTONOSUPPORT` + pub const PROTONOSUPPORT: Self = Self(c::EPROTONOSUPPORT); + /// `EPROTOTYPE` + pub const PROTOTYPE: Self = Self(c::EPROTOTYPE); + /// `EPROVIDERFAILEDINIT` + #[cfg(windows)] + pub const PROVIDERFAILEDINIT: Self = Self(c::EPROVIDERFAILEDINIT); + /// `ERANGE` + #[cfg(not(windows))] + pub const RANGE: Self = Self(c::ERANGE); + /// `EREFUSED` + #[cfg(windows)] + pub const REFUSED: Self = Self(c::EREFUSED); + /// `EREMCHG` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const REMCHG: Self = Self(c::EREMCHG); + /// `EREMOTE` + #[cfg(not(any(target_os = "haiku", target_os = "wasi")))] + pub const REMOTE: Self = Self(c::EREMOTE); + /// `EREMOTEIO` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const REMOTEIO: Self = Self(c::EREMOTEIO); + /// `ERESTART` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const RESTART: Self = Self(c::ERESTART); + /// `ERFKILL` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", + )))] + pub const RFKILL: Self = Self(c::ERFKILL); + /// `EROFS` + #[cfg(not(windows))] + pub const ROFS: Self = Self(c::EROFS); + /// `ERPCMISMATCH` + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + pub const RPCMISMATCH: Self = Self(c::ERPCMISMATCH); + /// `ESHUTDOWN` + #[cfg(not(target_os = "wasi"))] + pub const SHUTDOWN: Self = Self(c::ESHUTDOWN); + /// `ESOCKTNOSUPPORT` + #[cfg(not(any(target_os = "haiku", target_os = "wasi")))] + pub const SOCKTNOSUPPORT: Self = Self(c::ESOCKTNOSUPPORT); + /// `ESPIPE` + #[cfg(not(windows))] + pub const SPIPE: Self = Self(c::ESPIPE); + /// `ESRCH` + #[cfg(not(windows))] + pub const SRCH: Self = Self(c::ESRCH); + /// `ESRMNT` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const SRMNT: Self = Self(c::ESRMNT); + /// `ESTALE` + pub const STALE: Self = Self(c::ESTALE); + /// `ESTRPIPE` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const STRPIPE: Self = Self(c::ESTRPIPE); + /// `ETIME` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const TIME: Self = Self(c::ETIME); + /// `ETIMEDOUT` + pub const TIMEDOUT: Self = Self(c::ETIMEDOUT); + /// `E2BIG` + #[cfg(not(windows))] + #[doc(alias = "2BIG")] + pub const TOOBIG: Self = Self(c::E2BIG); + /// `ETOOMANYREFS` + #[cfg(not(any(target_os = "haiku", target_os = "wasi")))] + pub const TOOMANYREFS: Self = Self(c::ETOOMANYREFS); + /// `ETXTBSY` + #[cfg(not(windows))] + pub const TXTBSY: Self = Self(c::ETXTBSY); + /// `EUCLEAN` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "wasi", + )))] + pub const UCLEAN: Self = Self(c::EUCLEAN); + /// `EUNATCH` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const UNATCH: Self = Self(c::EUNATCH); + /// `EUSERS` + #[cfg(not(any(target_os = "haiku", target_os = "wasi")))] + pub const USERS: Self = Self(c::EUSERS); + /// `EWOULDBLOCK` + pub const WOULDBLOCK: Self = Self(c::EWOULDBLOCK); + /// `EXDEV` + #[cfg(not(windows))] + pub const XDEV: Self = Self(c::EXDEV); + /// `EXFULL` + #[cfg(not(any( + windows, + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "wasi", + )))] + pub const XFULL: Self = Self(c::EXFULL); +} + +impl Errno { + /// Extract an `Errno` value from a `std::io::Error`. + /// + /// This isn't a `From` conversion because it's expected to be relatively + /// uncommon. + #[cfg(feature = "std")] + #[inline] + pub fn from_io_error(io_err: &std::io::Error) -> Option { + io_err + .raw_os_error() + .and_then(|raw| if raw != 0 { Some(Self(raw)) } else { None }) + } + + /// Extract the raw OS error number from this error. + #[inline] + pub const fn raw_os_error(self) -> i32 { + self.0 + } + + /// Construct an `Errno` from a raw OS error number. + #[inline] + pub const fn from_raw_os_error(raw: i32) -> Self { + Self(raw) + } + + pub(crate) fn last_os_error() -> Self { + Self(errno().0) + } +} diff --git a/vendor/rustix/src/backend/libc/io/io_slice.rs b/vendor/rustix/src/backend/libc/io/io_slice.rs new file mode 100644 index 000000000..de1ef434c --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/io_slice.rs @@ -0,0 +1,87 @@ +//! The following is derived from Rust's +//! library/std/src/sys/unix/io.rs +//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. + +#![allow(missing_docs)] + +use super::super::c; +use core::marker::PhantomData; +use core::slice; + +#[derive(Copy, Clone)] +#[repr(transparent)] +pub struct IoSlice<'a> { + vec: c::iovec, + _p: PhantomData<&'a [u8]>, +} + +impl<'a> IoSlice<'a> { + #[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(), + }, + _p: PhantomData, + } + } + + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.iov_len < n { + panic!("advancing IoSlice beyond its length"); + } + + unsafe { + self.vec.iov_len -= n; + self.vec.iov_base = self.vec.iov_base.add(n); + } + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } + } +} + +#[repr(transparent)] +pub struct IoSliceMut<'a> { + vec: c::iovec, + _p: PhantomData<&'a mut [u8]>, +} + +impl<'a> IoSliceMut<'a> { + #[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(), + }, + _p: PhantomData, + } + } + + #[inline] + pub fn advance(&mut self, n: usize) { + if self.vec.iov_len < n { + panic!("advancing IoSliceMut beyond its length"); + } + + unsafe { + self.vec.iov_len -= n; + self.vec.iov_base = self.vec.iov_base.add(n); + } + } + + #[inline] + pub fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } + } + + #[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) } + } +} diff --git a/vendor/rustix/src/backend/libc/io/mod.rs b/vendor/rustix/src/backend/libc/io/mod.rs new file mode 100644 index 000000000..1378adf3d --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/mod.rs @@ -0,0 +1,13 @@ +pub(crate) mod errno; +#[cfg(not(windows))] +#[cfg(not(feature = "std"))] +pub(crate) mod io_slice; +pub(crate) mod poll_fd; +#[cfg(not(windows))] +pub(crate) mod types; + +#[cfg_attr(windows, path = "windows_syscalls.rs")] +pub(crate) mod syscalls; + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub mod epoll; diff --git a/vendor/rustix/src/backend/libc/io/poll_fd.rs b/vendor/rustix/src/backend/libc/io/poll_fd.rs new file mode 100644 index 000000000..c516a9309 --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/poll_fd.rs @@ -0,0 +1,136 @@ +use super::super::c; +use super::super::conv::borrowed_fd; +#[cfg(windows)] +use super::super::fd::RawFd; +use super::super::fd::{AsFd, AsRawFd, BorrowedFd, LibcFd}; +use bitflags::bitflags; +use core::marker::PhantomData; +#[cfg(windows)] +use std::fmt; + +bitflags! { + /// `POLL*` flags for use with [`poll`]. + /// + /// [`poll`]: crate::io::poll + pub struct PollFlags: c::c_short { + /// `POLLIN` + const IN = c::POLLIN; + /// `POLLPRI` + #[cfg(not(target_os = "wasi"))] + const PRI = c::POLLPRI; + /// `POLLOUT` + const OUT = c::POLLOUT; + /// `POLLRDNORM` + #[cfg(not(target_os = "redox"))] + const RDNORM = c::POLLRDNORM; + /// `POLLWRNORM` + #[cfg(not(target_os = "redox"))] + const WRNORM = c::POLLWRNORM; + /// `POLLRDBAND` + #[cfg(not(any(target_os = "redox", target_os = "wasi")))] + const RDBAND = c::POLLRDBAND; + /// `POLLWRBAND` + #[cfg(not(any(target_os = "redox", target_os = "wasi")))] + const WRBAND = c::POLLWRBAND; + /// `POLLERR` + const ERR = c::POLLERR; + /// `POLLHUP` + const HUP = c::POLLHUP; + /// `POLLNVAL` + const NVAL = c::POLLNVAL; + /// `POLLRDHUP` + #[cfg(all( + any(target_os = "android", target_os = "linux"), + not(any(target_arch = "sparc", target_arch = "sparc64"))), + )] + const RDHUP = c::POLLRDHUP; + } +} + +/// `struct pollfd`—File descriptor and flags for use with [`poll`]. +/// +/// [`poll`]: crate::io::poll +#[doc(alias = "pollfd")] +#[derive(Clone)] +#[cfg_attr(not(windows), derive(Debug))] +#[repr(transparent)] +pub struct PollFd<'fd> { + pollfd: c::pollfd, + _phantom: PhantomData>, +} + +#[cfg(windows)] +impl<'fd> fmt::Debug for PollFd<'fd> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("pollfd") + .field("fd", &self.pollfd.fd) + .field("events", &self.pollfd.events) + .field("revents", &self.pollfd.revents) + .finish() + } +} + +impl<'fd> PollFd<'fd> { + /// Constructs a new `PollFd` holding `fd` and `events`. + #[inline] + pub fn new(fd: &'fd Fd, events: PollFlags) -> Self { + Self::from_borrowed_fd(fd.as_fd(), events) + } + + /// Sets the contained file descriptor to `fd`. + #[inline] + pub fn set_fd(&mut self, fd: &'fd Fd) { + self.pollfd.fd = fd.as_fd().as_raw_fd() as LibcFd; + } + + /// Clears the ready events. + #[inline] + pub fn clear_revents(&mut self) { + self.pollfd.revents = 0; + } + + /// Constructs a new `PollFd` holding `fd` and `events`. + /// + /// This is the same as `new`, but can be used to avoid borrowing the + /// `BorrowedFd`, which can be tricky in situations where the `BorrowedFd` + /// is a temporary. + #[inline] + pub fn from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self { + Self { + pollfd: c::pollfd { + fd: borrowed_fd(fd), + events: events.bits(), + revents: 0, + }, + _phantom: PhantomData, + } + } + + /// Returns the ready events. + #[inline] + pub fn revents(&self) -> PollFlags { + // Use `unwrap()` here because in theory we know we know all the bits + // the OS might set here, but OS's have added extensions in the past. + PollFlags::from_bits(self.pollfd.revents).unwrap() + } +} + +#[cfg(not(windows))] +impl<'fd> AsFd for PollFd<'fd> { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + // Safety: Our constructors and `set_fd` require `pollfd.fd` to be + // valid for the `fd lifetime. + unsafe { BorrowedFd::borrow_raw(self.pollfd.fd) } + } +} + +#[cfg(windows)] +impl<'fd> io_lifetimes::AsSocket for PollFd<'fd> { + #[inline] + fn as_socket(&self) -> BorrowedFd<'_> { + // Safety: Our constructors and `set_fd` require `pollfd.fd` to be + // valid for the `fd lifetime. + unsafe { BorrowedFd::borrow_raw(self.pollfd.fd as RawFd) } + } +} diff --git a/vendor/rustix/src/backend/libc/io/syscalls.rs b/vendor/rustix/src/backend/libc/io/syscalls.rs new file mode 100644 index 000000000..3774e700a --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/syscalls.rs @@ -0,0 +1,533 @@ +//! libc syscalls supporting `rustix::io`. + +use super::super::c; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::super::conv::syscall_ret_owned_fd; +use super::super::conv::{ + borrowed_fd, ret, ret_c_int, ret_discarded_fd, ret_owned_fd, ret_ssize_t, +}; +use super::super::offset::{libc_pread, libc_pwrite}; +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))] +use super::super::offset::{libc_preadv, libc_pwritev}; +#[cfg(all(target_os = "linux", target_env = "gnu"))] +use super::super::offset::{libc_preadv2, libc_pwritev2}; +use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; +#[cfg(not(any(target_os = "aix", target_os = "wasi")))] +use crate::io::DupFlags; +#[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "wasi" +)))] +use crate::io::PipeFlags; +use crate::io::{self, FdFlags, IoSlice, IoSliceMut, PollFd}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::io::{EventfdFlags, IoSliceRaw, ReadWriteFlags, SpliceFlags}; +use core::cmp::min; +use core::convert::TryInto; +use core::mem::MaybeUninit; +#[cfg(any(target_os = "android", target_os = "linux"))] +use core::ptr; +#[cfg(all(feature = "fs", feature = "net"))] +use libc_errno::errno; + +pub(crate) fn read(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { + let nread = unsafe { + ret_ssize_t(c::read( + borrowed_fd(fd), + buf.as_mut_ptr().cast(), + min(buf.len(), READ_LIMIT), + ))? + }; + Ok(nread as usize) +} + +pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result { + let nwritten = unsafe { + ret_ssize_t(c::write( + borrowed_fd(fd), + buf.as_ptr().cast(), + min(buf.len(), READ_LIMIT), + ))? + }; + Ok(nwritten as usize) +} + +pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Result { + let len = min(buf.len(), READ_LIMIT); + + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + + let nread = unsafe { + ret_ssize_t(libc_pread( + borrowed_fd(fd), + buf.as_mut_ptr().cast(), + len, + offset, + ))? + }; + Ok(nread as usize) +} + +pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result { + let len = min(buf.len(), READ_LIMIT); + + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + + let nwritten = unsafe { + ret_ssize_t(libc_pwrite( + borrowed_fd(fd), + buf.as_ptr().cast(), + len, + offset, + ))? + }; + Ok(nwritten as usize) +} + +pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut]) -> io::Result { + let nread = unsafe { + ret_ssize_t(c::readv( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()) as c::c_int, + ))? + }; + Ok(nread as usize) +} + +pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice]) -> io::Result { + let nwritten = unsafe { + ret_ssize_t(c::writev( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()) as c::c_int, + ))? + }; + Ok(nwritten as usize) +} + +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))] +pub(crate) fn preadv( + fd: BorrowedFd<'_>, + bufs: &mut [IoSliceMut], + offset: u64, +) -> io::Result { + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + let nread = unsafe { + ret_ssize_t(libc_preadv( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()) as c::c_int, + offset, + ))? + }; + Ok(nread as usize) +} + +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))] +pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice], offset: u64) -> io::Result { + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + let nwritten = unsafe { + ret_ssize_t(libc_pwritev( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()) as c::c_int, + offset, + ))? + }; + Ok(nwritten as usize) +} + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub(crate) fn preadv2( + fd: BorrowedFd<'_>, + bufs: &mut [IoSliceMut], + offset: u64, + flags: ReadWriteFlags, +) -> io::Result { + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + let nread = unsafe { + ret_ssize_t(libc_preadv2( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()) as c::c_int, + offset, + flags.bits(), + ))? + }; + Ok(nread as usize) +} + +/// At present, `libc` only has `preadv2` defined for glibc. On other +/// ABIs, `ReadWriteFlags` has no flags defined, and we use plain `preadv`. +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "gnu")), +))] +#[inline] +pub(crate) fn preadv2( + fd: BorrowedFd<'_>, + bufs: &mut [IoSliceMut], + offset: u64, + flags: ReadWriteFlags, +) -> io::Result { + assert!(flags.is_empty()); + preadv(fd, bufs, offset) +} + +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub(crate) fn pwritev2( + fd: BorrowedFd<'_>, + bufs: &[IoSlice], + offset: u64, + flags: ReadWriteFlags, +) -> io::Result { + // Silently cast; we'll get `EINVAL` if the value is negative. + let offset = offset as i64; + let nwritten = unsafe { + ret_ssize_t(libc_pwritev2( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()) as c::c_int, + offset, + flags.bits(), + ))? + }; + Ok(nwritten as usize) +} + +/// At present, `libc` only has `pwritev2` defined for glibc. On other +/// ABIs, `ReadWriteFlags` has no flags defined, and we use plain `pwritev`. +#[cfg(any( + target_os = "android", + all(target_os = "linux", not(target_env = "gnu")), +))] +#[inline] +pub(crate) fn pwritev2( + fd: BorrowedFd<'_>, + bufs: &[IoSlice], + offset: u64, + flags: ReadWriteFlags, +) -> io::Result { + assert!(flags.is_empty()); + pwritev(fd, bufs, offset) +} + +// These functions are derived from Rust's library/std/src/sys/unix/fd.rs at +// revision a77da2d454e6caa227a85b16410b95f93495e7e0. + +// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`, with the +// man page quoting that if the count of bytes to read is greater than +// `SSIZE_MAX` the result is "unspecified". +// +// On macOS, however, apparently the 64-bit libc is either buggy or +// intentionally showing odd behavior by rejecting any read with a size larger +// than or equal to `INT_MAX`. To handle both of these the read size is capped +// on both platforms. +#[cfg(target_os = "macos")] +const READ_LIMIT: usize = c::c_int::MAX as usize - 1; +#[cfg(not(target_os = "macos"))] +const READ_LIMIT: usize = c::ssize_t::MAX as usize; + +#[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +))] +const fn max_iov() -> usize { + c::IOV_MAX as usize +} + +#[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))] +const fn max_iov() -> usize { + c::UIO_MAXIOV as usize +} + +#[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +)))] +const fn max_iov() -> usize { + 16 // The minimum value required by POSIX. +} + +pub(crate) unsafe fn close(raw_fd: RawFd) { + let _ = c::close(raw_fd as c::c_int); +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result { + unsafe { syscall_ret_owned_fd(c::syscall(c::SYS_eventfd2, initval, flags.bits())) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result { + let mut result = MaybeUninit::::uninit(); + unsafe { + ret(c::ioctl(borrowed_fd(fd), c::BLKSSZGET, result.as_mut_ptr()))?; + Ok(result.assume_init() as u32) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result { + let mut result = MaybeUninit::::uninit(); + unsafe { + ret(c::ioctl( + borrowed_fd(fd), + c::BLKPBSZGET, + result.as_mut_ptr(), + ))?; + Ok(result.assume_init() as u32) + } +} + +#[cfg(not(target_os = "redox"))] +pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result { + let mut nread = MaybeUninit::::uninit(); + unsafe { + ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?; + // `FIONREAD` returns the number of bytes silently casted to a `c_int`, + // even when this is lossy. The best we can do is convert it back to a + // `u64` without sign-extending it back first. + Ok(u64::from(nread.assume_init() as c::c_uint)) + } +} + +pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + unsafe { + let data = value as c::c_int; + ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &data)) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +#[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)?; + let mut not_socket = false; + if read { + // Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates + // the read side is shut down; an `EWOULDBLOCK` indicates the read + // side is still open. + match unsafe { + c::recv( + borrowed_fd(fd), + MaybeUninit::<[u8; 1]>::uninit() + .as_mut_ptr() + .cast::(), + 1, + c::MSG_PEEK | c::MSG_DONTWAIT, + ) + } { + 0 => read = false, + -1 => { + #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` + match errno().0 { + c::EAGAIN | c::EWOULDBLOCK => (), + c::ENOTSOCK => not_socket = true, + err => return Err(io::Errno(err)), + } + } + _ => (), + } + } + if write && !not_socket { + // Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates + // the write side is shut down. + if unsafe { c::send(borrowed_fd(fd), [].as_ptr(), 0, c::MSG_DONTWAIT) } == -1 { + #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` + match errno().0 { + c::EAGAIN | c::EWOULDBLOCK => (), + c::ENOTSOCK => (), + c::EPIPE => write = false, + err => return Err(io::Errno(err)), + } + } + } + Ok((read, write)) +} + +#[cfg(target_os = "wasi")] +#[cfg(all(feature = "fs", feature = "net"))] +pub(crate) fn is_read_write(_fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { + todo!("Implement is_read_write for WASI in terms of fd_fdstat_get"); +} + +pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result { + unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFD)).map(FdFlags::from_bits_truncate) } +} + +pub(crate) fn fcntl_setfd(fd: BorrowedFd<'_>, flags: FdFlags) -> io::Result<()> { + unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFD, flags.bits())) } +} + +#[cfg(not(target_os = "wasi"))] +pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result { + unsafe { ret_owned_fd(c::fcntl(borrowed_fd(fd), c::F_DUPFD_CLOEXEC, min)) } +} + +#[cfg(not(target_os = "wasi"))] +pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result { + unsafe { ret_owned_fd(c::dup(borrowed_fd(fd))) } +} + +#[cfg(not(target_os = "wasi"))] +pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { + unsafe { ret_discarded_fd(c::dup2(borrowed_fd(fd), borrowed_fd(new.as_fd()))) } +} + +#[cfg(not(any( + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "wasi", +)))] +pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { + unsafe { + ret_discarded_fd(c::dup3( + borrowed_fd(fd), + borrowed_fd(new.as_fd()), + flags.bits(), + )) + } +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox", +))] +pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, _flags: DupFlags) -> io::Result<()> { + // Android 5.0 has `dup3`, but libc doesn't have bindings. Emulate it + // using `dup2`. We don't need to worry about the difference between + // `dup2` and `dup3` when the file descriptors are equal because we + // have an `&mut OwnedFd` which means `fd` doesn't alias it. + dup2(fd, new) +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(crate) fn ioctl_fioclex(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::FIOCLEX)) } +} + +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] +pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCEXCL as _)) } +} + +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] +pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCNXCL as _)) } +} + +#[cfg(not(target_os = "wasi"))] +pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { + unsafe { + let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(c::pipe(result.as_mut_ptr().cast::()))?; + let [p0, p1] = result.assume_init(); + Ok((p0, p1)) + } +} + +#[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "wasi" +)))] +pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { + unsafe { + let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(c::pipe2(result.as_mut_ptr().cast::(), flags.bits()))?; + let [p0, p1] = result.assume_init(); + Ok((p0, p1)) + } +} + +#[inline] +pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result { + let nfds = fds + .len() + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + + ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) + .map(|nready| nready as usize) +} + +#[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 { + let off_in = off_in + .map(|off| (off as *mut u64).cast()) + .unwrap_or(ptr::null_mut()); + + let off_out = off_out + .map(|off| (off as *mut u64).cast()) + .unwrap_or(ptr::null_mut()); + + ret_ssize_t(unsafe { + c::splice( + borrowed_fd(fd_in), + off_in, + borrowed_fd(fd_out), + off_out, + len, + flags.bits(), + ) + }) + .map(|spliced| spliced as usize) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub unsafe fn vmsplice( + fd: BorrowedFd, + bufs: &[IoSliceRaw], + flags: SpliceFlags, +) -> io::Result { + ret_ssize_t(c::vmsplice( + borrowed_fd(fd), + bufs.as_ptr().cast::(), + min(bufs.len(), max_iov()), + flags.bits(), + )) + .map(|spliced| spliced as usize) +} diff --git a/vendor/rustix/src/backend/libc/io/types.rs b/vendor/rustix/src/backend/libc/io/types.rs new file mode 100644 index 000000000..46d5f6332 --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/types.rs @@ -0,0 +1,164 @@ +use super::super::c; +use bitflags::bitflags; +#[cfg(any(target_os = "android", target_os = "linux"))] +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 + pub struct FdFlags: c::c_int { + /// `FD_CLOEXEC` + const CLOEXEC = c::FD_CLOEXEC; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`]. + /// + /// [`preadv2`]: crate::io::preadv2 + /// [`pwritev2`]: crate::io::pwritev + pub struct ReadWriteFlags: c::c_int { + /// `RWF_DSYNC` (since Linux 4.7) + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const DSYNC = c::RWF_DSYNC; + /// `RWF_HIPRI` (since Linux 4.6) + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const HIPRI = c::RWF_HIPRI; + /// `RWF_SYNC` (since Linux 4.7) + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const SYNC = c::RWF_SYNC; + /// `RWF_NOWAIT` (since Linux 4.14) + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const NOWAIT = c::RWF_NOWAIT; + /// `RWF_APPEND` (since Linux 4.16) + #[cfg(all(target_os = "linux", target_env = "gnu"))] + const APPEND = c::RWF_APPEND; + } +} + +#[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 = c::SPLICE_F_MOVE; + /// `SPLICE_F_NONBLOCK` + const NONBLOCK = c::SPLICE_F_NONBLOCK; + /// `SPLICE_F_MORE` + const MORE = c::SPLICE_F_MORE; + /// `SPLICE_F_GIFT` + const GIFT = c::SPLICE_F_GIFT; + } +} + +#[cfg(not(target_os = "wasi"))] +bitflags! { + /// `O_*` constants for use with [`dup2`]. + /// + /// [`dup2`]: crate::io::dup2 + pub struct DupFlags: c::c_int { + /// `O_CLOEXEC` + #[cfg(not(any( + target_os = "android", + target_os = "ios", + target_os = "macos", + target_os = "redox", + )))] // Android 5.0 has dup3, but libc doesn't have bindings + const CLOEXEC = c::O_CLOEXEC; + } +} + +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))] +bitflags! { + /// `O_*` constants for use with [`pipe_with`]. + /// + /// [`pipe_with`]: crate::io::pipe_with + pub struct PipeFlags: c::c_int { + /// `O_CLOEXEC` + const CLOEXEC = c::O_CLOEXEC; + /// `O_DIRECT` + #[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const DIRECT = c::O_DIRECT; + /// `O_NONBLOCK` + const NONBLOCK = c::O_NONBLOCK; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `EFD_*` flags for use with [`eventfd`]. + /// + /// [`eventfd`]: crate::io::eventfd + pub struct EventfdFlags: c::c_int { + /// `EFD_CLOEXEC` + const CLOEXEC = c::EFD_CLOEXEC; + /// `EFD_NONBLOCK` + const NONBLOCK = c::EFD_NONBLOCK; + /// `EFD_SEMAPHORE` + const SEMAPHORE = c::EFD_SEMAPHORE; + } +} + +/// `PIPE_BUF`—The maximum size of a write to a pipe guaranteed to be atomic. +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub const PIPE_BUF: usize = c::PIPE_BUF; + +#[cfg(not(any(windows, target_os = "redox")))] +pub(crate) const AT_FDCWD: c::c_int = c::AT_FDCWD; +#[cfg(not(windows))] +pub(crate) const STDIN_FILENO: c::c_int = c::STDIN_FILENO; +#[cfg(not(windows))] +pub(crate) const STDOUT_FILENO: c::c_int = c::STDOUT_FILENO; +#[cfg(not(windows))] +pub(crate) const STDERR_FILENO: c::c_int = c::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. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[repr(transparent)] +pub struct IoSliceRaw<'a> { + _buf: c::iovec, + _lifetime: PhantomData<&'a ()>, +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +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/libc/io/windows_syscalls.rs b/vendor/rustix/src/backend/libc/io/windows_syscalls.rs new file mode 100644 index 000000000..4c6e86f94 --- /dev/null +++ b/vendor/rustix/src/backend/libc/io/windows_syscalls.rs @@ -0,0 +1,39 @@ +//! Windows system calls in the `io` module. + +use super::super::c; +use super::super::conv::{borrowed_fd, ret, ret_c_int}; +use super::super::fd::LibcFd; +use crate::fd::{BorrowedFd, RawFd}; +use crate::io; +use crate::io::PollFd; +use core::convert::TryInto; +use core::mem::MaybeUninit; + +pub(crate) unsafe fn close(raw_fd: RawFd) { + let _ = c::close(raw_fd as LibcFd); +} + +pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result { + let mut nread = MaybeUninit::::uninit(); + unsafe { + ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?; + Ok(u64::from(nread.assume_init())) + } +} + +pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + unsafe { + let mut data = value as c::c_uint; + ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &mut data)) + } +} + +pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result { + let nfds = fds + .len() + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + + ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) + .map(|nready| nready as usize) +} diff --git a/vendor/rustix/src/backend/libc/io_lifetimes.rs b/vendor/rustix/src/backend/libc/io_lifetimes.rs new file mode 100644 index 000000000..2dcd772e8 --- /dev/null +++ b/vendor/rustix/src/backend/libc/io_lifetimes.rs @@ -0,0 +1,77 @@ +//! `io_lifetimes` types for Windows assuming that Fd is Socket. +//! +//! We can make this assumption since `rustix` supports only `rustix::net` on +//! Windows. + +pub use io_lifetimes::{BorrowedSocket as BorrowedFd, OwnedSocket as OwnedFd}; +#[cfg(feature = "std")] +pub use std::os::windows::io::RawSocket as RawFd; +pub(crate) use windows_sys::Win32::Networking::WinSock::SOCKET as LibcFd; + +// Re-export the `Socket` traits so that users can implement them. +pub use io_lifetimes::AsSocket; + +/// A version of [`AsRawFd`] for use with Winsock2 API. +/// +/// [`AsRawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsRawFd.html +pub trait AsRawFd { + /// A version of [`as_raw_fd`] for use with Winsock2 API. + /// + /// [`as_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.as_raw_fd + fn as_raw_fd(&self) -> RawFd; +} +#[cfg(feature = "std")] +impl AsRawFd for T { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.as_raw_socket() + } +} + +/// A version of [`IntoRawFd`] for use with Winsock2 API. +/// +/// [`IntoRawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.IntoRawFd.html +pub trait IntoRawFd { + /// A version of [`into_raw_fd`] for use with Winsock2 API. + /// + /// [`into_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.into_raw_fd + fn into_raw_fd(self) -> RawFd; +} +#[cfg(feature = "std")] +impl IntoRawFd for T { + #[inline] + fn into_raw_fd(self) -> RawFd { + self.into_raw_socket() + } +} + +/// A version of [`FromRawFd`] for use with Winsock2 API. +/// +/// [`FromRawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html +pub trait FromRawFd { + /// A version of [`from_raw_fd`] for use with Winsock2 API. + /// + /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.from_raw_fd + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self; +} +#[cfg(feature = "std")] +impl FromRawFd for T { + #[inline] + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + Self::from_raw_socket(raw_fd) + } +} + +/// A version of [`AsFd`] for use with Winsock2 API. +/// +/// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html +pub trait AsFd { + /// An `as_fd` function for Winsock2, where a `Fd` is a `Socket`. + fn as_fd(&self) -> BorrowedFd; +} +impl AsFd for T { + #[inline] + fn as_fd(&self) -> BorrowedFd { + self.as_socket() + } +} diff --git a/vendor/rustix/src/backend/libc/io_uring/mod.rs b/vendor/rustix/src/backend/libc/io_uring/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/libc/io_uring/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/io_uring/syscalls.rs b/vendor/rustix/src/backend/libc/io_uring/syscalls.rs new file mode 100644 index 000000000..31fcec3db --- /dev/null +++ b/vendor/rustix/src/backend/libc/io_uring/syscalls.rs @@ -0,0 +1,55 @@ +//! libc syscalls supporting `rustix::io_uring`. + +use super::super::c; +use super::super::conv::{borrowed_fd, syscall_ret, syscall_ret_owned_fd, syscall_ret_u32}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterOp}; +use linux_raw_sys::general::{__NR_io_uring_enter, __NR_io_uring_register, __NR_io_uring_setup}; + +#[inline] +pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result { + unsafe { + syscall_ret_owned_fd(c::syscall( + __NR_io_uring_setup as _, + entries as usize, + params, + )) + } +} + +#[inline] +pub(crate) unsafe fn io_uring_register( + fd: BorrowedFd<'_>, + opcode: IoringRegisterOp, + arg: *const c::c_void, + nr_args: u32, +) -> io::Result<()> { + syscall_ret(c::syscall( + __NR_io_uring_register as _, + borrowed_fd(fd), + opcode as u32 as usize, + arg, + nr_args as usize, + )) +} + +#[inline] +pub(crate) unsafe fn io_uring_enter( + fd: BorrowedFd<'_>, + to_submit: u32, + min_complete: u32, + flags: IoringEnterFlags, + arg: *const c::c_void, + size: usize, +) -> io::Result { + syscall_ret_u32(c::syscall( + __NR_io_uring_enter as _, + borrowed_fd(fd), + to_submit as usize, + min_complete as usize, + flags.bits() as usize, + arg, + size, + )) +} diff --git a/vendor/rustix/src/backend/libc/mm/mod.rs b/vendor/rustix/src/backend/libc/mm/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/libc/mm/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/mm/syscalls.rs b/vendor/rustix/src/backend/libc/mm/syscalls.rs new file mode 100644 index 000000000..a1d2df1af --- /dev/null +++ b/vendor/rustix/src/backend/libc/mm/syscalls.rs @@ -0,0 +1,218 @@ +//! libc syscalls supporting `rustix::mm`. + +use super::super::c; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::super::conv::syscall_ret_owned_fd; +use super::super::conv::{borrowed_fd, no_fd, ret}; +use super::super::offset::libc_mmap; +#[cfg(not(target_os = "redox"))] +use super::types::Advice; +#[cfg(target_os = "linux")] +use super::types::MremapFlags; +use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::types::{MlockFlags, UserfaultfdFlags}; +use crate::fd::BorrowedFd; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::fd::OwnedFd; +use crate::io; + +#[cfg(not(target_os = "redox"))] +pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { + // On Linux platforms, `MADV_DONTNEED` has the same value as + // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different + // value, and check for it here. + #[cfg(target_os = "linux")] + if let Advice::LinuxDontNeed = advice { + return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) }; + } + + #[cfg(not(target_os = "android"))] + { + let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) }; + + // `posix_madvise` returns its error status rather than using `errno`. + if err == 0 { + Ok(()) + } else { + Err(io::Errno(err)) + } + } + + #[cfg(target_os = "android")] + { + if let Advice::DontNeed = advice { + // Do nothing. Linux's `MADV_DONTNEED` isn't the same as + // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`. + Ok(()) + } else { + unsafe { ret(c::madvise(addr, len, advice as c::c_int)) } + } + } +} + +pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { + let err = c::msync(addr, len, flags.bits()); + + // `msync` returns its error status rather than using `errno`. + if err == 0 { + Ok(()) + } else { + Err(io::Errno(err)) + } +} + +/// # Safety +/// +/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working +/// with memory pointed to by raw pointers is unsafe. +pub(crate) unsafe fn mmap( + ptr: *mut c::c_void, + len: usize, + prot: ProtFlags, + flags: MapFlags, + fd: BorrowedFd<'_>, + offset: u64, +) -> io::Result<*mut c::c_void> { + let res = libc_mmap( + ptr, + len, + prot.bits(), + flags.bits(), + borrowed_fd(fd), + offset as i64, + ); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +/// # Safety +/// +/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working +/// with memory pointed to by raw pointers is unsafe. +pub(crate) unsafe fn mmap_anonymous( + ptr: *mut c::c_void, + len: usize, + prot: ProtFlags, + flags: MapFlags, +) -> io::Result<*mut c::c_void> { + let res = libc_mmap( + ptr, + len, + prot.bits(), + flags.bits() | c::MAP_ANONYMOUS, + no_fd(), + 0, + ); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +pub(crate) unsafe fn mprotect( + ptr: *mut c::c_void, + len: usize, + flags: MprotectFlags, +) -> io::Result<()> { + ret(c::mprotect(ptr, len, flags.bits())) +} + +pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> { + ret(c::munmap(ptr, len)) +} + +/// # Safety +/// +/// `mremap` is primarily unsafe due to the `old_address` parameter, as +/// anything working with memory pointed to by raw pointers is unsafe. +#[cfg(target_os = "linux")] +pub(crate) unsafe fn mremap( + old_address: *mut c::c_void, + old_size: usize, + new_size: usize, + flags: MremapFlags, +) -> io::Result<*mut c::c_void> { + let res = c::mremap(old_address, old_size, new_size, flags.bits()); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +/// # Safety +/// +/// `mremap_fixed` is primarily unsafe due to the `old_address` and +/// `new_address` parameters, as anything working with memory pointed to by raw +/// pointers is unsafe. +#[cfg(target_os = "linux")] +pub(crate) unsafe fn mremap_fixed( + old_address: *mut c::c_void, + old_size: usize, + new_size: usize, + flags: MremapFlags, + new_address: *mut c::c_void, +) -> io::Result<*mut c::c_void> { + let res = c::mremap( + old_address, + old_size, + new_size, + flags.bits() | c::MAP_FIXED, + new_address, + ); + if res == c::MAP_FAILED { + Err(io::Errno::last_os_error()) + } else { + Ok(res) + } +} + +/// # Safety +/// +/// `mlock` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(c::mlock(addr, length)) +} + +/// # Safety +/// +/// `mlock_with` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) unsafe fn mlock_with( + addr: *mut c::c_void, + length: usize, + flags: MlockFlags, +) -> io::Result<()> { + weak_or_syscall! { + fn mlock2( + addr: *const c::c_void, + len: c::size_t, + flags: c::c_int + ) via SYS_mlock2 -> c::c_int + } + + ret(mlock2(addr, length, flags.bits())) +} + +/// # Safety +/// +/// `munlock` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(c::munlock(addr, length)) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result { + syscall_ret_owned_fd(c::syscall(c::SYS_userfaultfd, flags.bits())) +} diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs new file mode 100644 index 000000000..11ab708cf --- /dev/null +++ b/vendor/rustix/src/backend/libc/mm/types.rs @@ -0,0 +1,428 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `PROT_*` flags for use with [`mmap`]. + /// + /// For `PROT_NONE`, use `ProtFlags::empty()`. + /// + /// [`mmap`]: crate::io::mmap + pub struct ProtFlags: c::c_int { + /// `PROT_READ` + const READ = c::PROT_READ; + /// `PROT_WRITE` + const WRITE = c::PROT_WRITE; + /// `PROT_EXEC` + const EXEC = c::PROT_EXEC; + } +} + +bitflags! { + /// `PROT_*` flags for use with [`mprotect`]. + /// + /// For `PROT_NONE`, use `MprotectFlags::empty()`. + /// + /// [`mprotect`]: crate::io::mprotect + pub struct MprotectFlags: c::c_int { + /// `PROT_READ` + const READ = c::PROT_READ; + /// `PROT_WRITE` + const WRITE = c::PROT_WRITE; + /// `PROT_EXEC` + const EXEC = c::PROT_EXEC; + /// `PROT_GROWSUP` + #[cfg(any(target_os = "android", target_os = "linux"))] + const GROWSUP = c::PROT_GROWSUP; + /// `PROT_GROWSDOWN` + #[cfg(any(target_os = "android", target_os = "linux"))] + const GROWSDOWN = c::PROT_GROWSDOWN; + } +} + +bitflags! { + /// `MAP_*` flags for use with [`mmap`]. + /// + /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. + /// + /// [`mmap`]: crate::io::mmap + /// [`mmap_anonymous`]: crates::io::mmap_anonymous + pub struct MapFlags: c::c_int { + /// `MAP_SHARED` + const SHARED = c::MAP_SHARED; + /// `MAP_SHARED_VALIDATE` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const SHARED_VALIDATE = c::MAP_SHARED_VALIDATE; + /// `MAP_PRIVATE` + const PRIVATE = c::MAP_PRIVATE; + /// `MAP_DENYWRITE` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const DENYWRITE = c::MAP_DENYWRITE; + /// `MAP_FIXED` + const FIXED = c::MAP_FIXED; + /// `MAP_FIXED_NOREPLACE` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const FIXED_NOREPLACE = c::MAP_FIXED_NOREPLACE; + /// `MAP_GROWSDOWN` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const GROWSDOWN = c::MAP_GROWSDOWN; + /// `MAP_HUGETLB` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const HUGETLB = c::MAP_HUGETLB; + /// `MAP_HUGE_2MB` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const HUGE_2MB = c::MAP_HUGE_2MB; + /// `MAP_HUGE_1GB` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const HUGE_1GB = c::MAP_HUGE_1GB; + /// `MAP_LOCKED` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const LOCKED = c::MAP_LOCKED; + /// `MAP_NOCORE` + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + const NOCORE = c::MAP_NOCORE; + /// `MAP_NORESERVE` + #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "redox")))] + const NORESERVE = c::MAP_NORESERVE; + /// `MAP_NOSYNC` + #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] + const NOSYNC = c::MAP_NOSYNC; + /// `MAP_POPULATE` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + const POPULATE = c::MAP_POPULATE; + /// `MAP_STACK` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + )))] + const STACK = c::MAP_STACK; + /// `MAP_PREFAULT_READ` + #[cfg(target_os = "freebsd")] + const PREFAULT_READ = c::MAP_PREFAULT_READ; + /// `MAP_SYNC` + #[cfg(not(any( + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + all( + any(target_os = "android", target_os = "linux"), + any(target_arch = "mips", target_arch = "mips64"), + ) + )))] + const SYNC = c::MAP_SYNC; + /// `MAP_UNINITIALIZED` + #[cfg(any())] + const UNINITIALIZED = c::MAP_UNINITIALIZED; + } +} + +#[cfg(target_os = "linux")] +bitflags! { + /// `MREMAP_*` flags for use with [`mremap`]. + /// + /// For `MREMAP_FIXED`, see [`mremap_fixed`]. + /// + /// [`mremap`]: crate::io::mremap + /// [`mremap_fixed`]: crate::io::mremap_fixed + pub struct MremapFlags: i32 { + /// `MREMAP_MAYMOVE` + const MAYMOVE = c::MREMAP_MAYMOVE; + } +} + +bitflags! { + /// `MS_*` flags for use with [`msync`]. + /// + /// [`msync`]: crate::io::msync + pub struct MsyncFlags: i32 { + /// `MS_SYNC`—Requests an update and waits for it to complete. + const SYNC = c::MS_SYNC; + /// `MS_ASYNC`—Specifies that an update be scheduled, but the call + /// returns immediately. + const ASYNC = c::MS_ASYNC; + /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same + /// file (so that they can be updated with the fresh values just + /// written). + const INVALIDATE = c::MS_INVALIDATE; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `MLOCK_*` flags for use with [`mlock_with`]. + /// + /// [`mlock_with`]: crate::io::mlock_with + pub struct MlockFlags: i32 { + /// `MLOCK_ONFAULT` + const ONFAULT = c::MLOCK_ONFAULT as _; + } +} + +/// `POSIX_MADV_*` constants for use with [`madvise`]. +/// +/// [`madvise`]: crate::mm::madvise +#[cfg(not(target_os = "redox"))] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(i32)] +#[non_exhaustive] +pub enum Advice { + /// `POSIX_MADV_NORMAL` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + Normal = c::POSIX_MADV_NORMAL, + + /// `POSIX_MADV_NORMAL` + #[cfg(any(target_os = "android", target_os = "haiku"))] + Normal = c::MADV_NORMAL, + + /// `POSIX_MADV_SEQUENTIAL` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + Sequential = c::POSIX_MADV_SEQUENTIAL, + + /// `POSIX_MADV_SEQUENTIAL` + #[cfg(any(target_os = "android", target_os = "haiku"))] + Sequential = c::MADV_SEQUENTIAL, + + /// `POSIX_MADV_RANDOM` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + Random = c::POSIX_MADV_RANDOM, + + /// `POSIX_MADV_RANDOM` + #[cfg(any(target_os = "android", target_os = "haiku"))] + Random = c::MADV_RANDOM, + + /// `POSIX_MADV_WILLNEED` + #[cfg(not(any(target_os = "android", target_os = "haiku")))] + WillNeed = c::POSIX_MADV_WILLNEED, + + /// `POSIX_MADV_WILLNEED` + #[cfg(any(target_os = "android", target_os = "haiku"))] + WillNeed = c::MADV_WILLNEED, + + /// `POSIX_MADV_DONTNEED` + #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "haiku")))] + DontNeed = c::POSIX_MADV_DONTNEED, + + /// `POSIX_MADV_DONTNEED` + #[cfg(any(target_os = "android", target_os = "haiku"))] + DontNeed = i32::MAX - 1, + + /// `MADV_DONTNEED` + // `MADV_DONTNEED` has the same value as `POSIX_MADV_DONTNEED`. We don't + // have a separate `posix_madvise` from `madvise`, so we expose a special + // value which we special-case. + #[cfg(target_os = "linux")] + LinuxDontNeed = i32::MAX, + + /// `MADV_DONTNEED` + #[cfg(target_os = "android")] + LinuxDontNeed = c::MADV_DONTNEED, + /// `MADV_FREE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxFree = c::MADV_FREE, + /// `MADV_REMOVE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxRemove = c::MADV_REMOVE, + /// `MADV_DONTFORK` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDontFork = c::MADV_DONTFORK, + /// `MADV_DOFORK` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDoFork = c::MADV_DOFORK, + /// `MADV_HWPOISON` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxHwPoison = c::MADV_HWPOISON, + /// `MADV_SOFT_OFFLINE` + #[cfg(all( + any(target_os = "android", target_os = "linux"), + not(any(target_arch = "mips", target_arch = "mips64")), + ))] + LinuxSoftOffline = c::MADV_SOFT_OFFLINE, + /// `MADV_MERGEABLE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxMergeable = c::MADV_MERGEABLE, + /// `MADV_UNMERGEABLE` + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxUnmergeable = c::MADV_UNMERGEABLE, + /// `MADV_HUGEPAGE` (since Linux 2.6.38) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxHugepage = c::MADV_HUGEPAGE, + /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxNoHugepage = c::MADV_NOHUGEPAGE, + /// `MADV_DONTDUMP` (since Linux 3.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDontDump = c::MADV_DONTDUMP, + /// `MADV_DODUMP` (since Linux 3.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + LinuxDoDump = c::MADV_DODUMP, + /// `MADV_WIPEONFORK` (since Linux 4.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK as i32, + /// `MADV_KEEPONFORK` (since Linux 4.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK as i32, + /// `MADV_COLD` (since Linux 5.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxCold = linux_raw_sys::general::MADV_COLD as i32, + /// `MADV_PAGEOUT` (since Linux 5.4) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT as i32, + /// `MADV_POPULATE_READ` (since Linux 5.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ as i32, + /// `MADV_POPULATE_WRITE` (since Linux 5.14) + #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(feature = "mm")] + LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE as i32, +} + +#[cfg(target_os = "emscripten")] +impl Advice { + /// `POSIX_MADV_DONTNEED` + #[allow(non_upper_case_globals)] + pub const DontNeed: Self = Self::Normal; +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags! { + /// `O_*` flags for use with [`userfaultfd`]. + /// + /// [`userfaultfd`]: crate::io::userfaultfd + pub struct UserfaultfdFlags: c::c_int { + /// `O_CLOEXEC` + const CLOEXEC = c::O_CLOEXEC; + /// `O_NONBLOCK` + const NONBLOCK = c::O_NONBLOCK; + } +} diff --git a/vendor/rustix/src/backend/libc/mod.rs b/vendor/rustix/src/backend/libc/mod.rs new file mode 100644 index 000000000..16d21b657 --- /dev/null +++ b/vendor/rustix/src/backend/libc/mod.rs @@ -0,0 +1,111 @@ +//! The libc backend. +//! +//! On most platforms, this uses the `libc` crate to make system calls. On +//! Windows, this uses the Winsock2 API in `windows-sys`, which can be adapted +//! to have a very `libc`-like interface. + +// Every FFI call requires an unsafe block, and there are a lot of FFI +// calls. For now, set this to allow for the libc backend. +#![allow(clippy::undocumented_unsafe_blocks)] +// Lots of libc types vary between platforms, so we often need a `.into()` on +// one platform where it's redundant on another. +#![allow(clippy::useless_conversion)] + +#[cfg(not(any(windows, target_os = "wasi")))] +#[macro_use] +mod weak; + +mod conv; +mod offset; + +#[cfg(windows)] +mod io_lifetimes; +#[cfg(not(windows))] +#[cfg(not(feature = "std"))] +pub(crate) mod fd { + pub(crate) use super::c::c_int as LibcFd; + pub use crate::io::fd::*; +} +#[cfg(windows)] +pub(crate) mod fd { + pub use super::io_lifetimes::*; +} +#[cfg(not(windows))] +#[cfg(feature = "std")] +pub(crate) mod fd { + pub use io_lifetimes::*; + + #[cfg(target_os = "wasi")] + #[allow(unused_imports)] + pub(crate) use super::c::c_int as LibcFd; + #[cfg(unix)] + #[allow(unused_imports)] + pub(crate) use std::os::unix::io::RawFd as LibcFd; + #[cfg(unix)] + pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; + #[cfg(target_os = "wasi")] + pub use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +} + +// On Windows we emulate selected libc-compatible interfaces. On non-Windows, +// we just use libc here, since this is the libc backend. +#[cfg(windows)] +#[path = "winsock_c.rs"] +pub(crate) mod c; +#[cfg(not(windows))] +pub(crate) use libc as c; + +#[cfg(not(windows))] +#[cfg(feature = "fs")] +pub(crate) mod fs; +pub(crate) mod io; +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(feature = "io_uring")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))] +pub(crate) mod io_uring; +#[cfg(not(any(windows, target_os = "wasi")))] +#[cfg(feature = "mm")] +pub(crate) mod mm; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +#[cfg(feature = "net")] +pub(crate) mod net; +#[cfg(not(windows))] +#[cfg(any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86", +))] +pub(crate) mod param; +#[cfg(not(windows))] +pub(crate) mod process; +#[cfg(not(windows))] +#[cfg(feature = "rand")] +pub(crate) mod rand; +#[cfg(not(any(windows, target_os = "wasi")))] +#[cfg(feature = "termios")] +pub(crate) mod termios; +#[cfg(not(windows))] +#[cfg(feature = "thread")] +pub(crate) mod thread; +#[cfg(not(windows))] +pub(crate) mod time; + +/// If the host libc is glibc, return `true` if it is less than version 2.25. +/// +/// To restate and clarify, this function returning true does not mean the libc +/// is glibc just that if it is glibc, it is less than version 2.25. +/// +/// For now, this function is only available on Linux, but if it ends up being +/// used beyond that, this could be changed to e.g. `#[cfg(unix)]`. +#[cfg(all(unix, target_env = "gnu"))] +pub(crate) fn if_glibc_is_less_than_2_25() -> bool { + // This is also defined inside `weak_or_syscall!` in + // backend/libc/rand/syscalls.rs, but it's not convenient to re-export the weak + // symbol from that macro, so we duplicate it at a small cost here. + weak! { fn getrandom(*mut c::c_void, c::size_t, c::c_uint) -> c::ssize_t } + + // glibc 2.25 has `getrandom`, which is how we satisfy the API contract of + // this function. But, there are likely other libc versions which have it. + getrandom.get().is_none() +} diff --git a/vendor/rustix/src/backend/libc/net/addr.rs b/vendor/rustix/src/backend/libc/net/addr.rs new file mode 100644 index 000000000..ba64ed279 --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/addr.rs @@ -0,0 +1,330 @@ +//! IPv4, IPv6, and Socket addresses. + +use super::super::c; +#[cfg(unix)] +use crate::ffi::CStr; +#[cfg(unix)] +use crate::io; +#[cfg(unix)] +use crate::path; +#[cfg(not(windows))] +use core::convert::TryInto; +#[cfg(unix)] +use core::fmt; +#[cfg(unix)] +use core::slice; + +/// `struct sockaddr_un` +#[cfg(unix)] +#[derive(Clone)] +#[doc(alias = "sockaddr_un")] +pub struct SocketAddrUnix { + pub(crate) unix: c::sockaddr_un, + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + len: c::socklen_t, +} + +#[cfg(unix)] +impl SocketAddrUnix { + /// Construct a new Unix-domain address from a filesystem path. + #[inline] + pub fn new(path: P) -> io::Result { + path.into_with_c_str(Self::_new) + } + + #[inline] + fn _new(path: &CStr) -> io::Result { + let mut unix = Self::init(); + let bytes = path.to_bytes_with_nul(); + if bytes.len() > unix.sun_path.len() { + return Err(io::Errno::NAMETOOLONG); + } + for (i, b) in bytes.iter().enumerate() { + unix.sun_path[i] = *b as c::c_char; + } + + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + { + unix.sun_len = (offsetof_sun_path() + bytes.len()).try_into().unwrap(); + } + + Ok(Self { + unix, + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + len: (offsetof_sun_path() + bytes.len()).try_into().unwrap(), + }) + } + + /// Construct a new abstract Unix-domain address from a byte slice. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[inline] + pub fn new_abstract_name(name: &[u8]) -> io::Result { + 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 len = offsetof_sun_path() + 1 + name.len(); + let len = len.try_into().unwrap(); + Ok(Self { + unix, + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + len, + }) + } + + fn init() -> c::sockaddr_un { + c::sockaddr_un { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sun_len: 0, + sun_family: c::AF_UNIX as _, + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sun_path: [0; 104], + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + sun_path: [0; 108], + #[cfg(target_os = "haiku")] + sun_path: [0; 126], + } + } + + /// For a filesystem path address, return the path. + #[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 { + 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(), + ))) + } + } else { + None + } + } + + /// For an abstract address, return the identifier. + #[cfg(any(target_os = "android", target_os = "linux"))] + #[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 { + 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())) } + } else { + None + } + } + + #[inline] + pub(crate) fn addr_len(&self) -> c::socklen_t { + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + { + self.len + } + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + { + c::socklen_t::from(self.unix.sun_len) + } + } + + #[inline] + pub(crate) fn len(&self) -> usize { + self.addr_len() as usize + } +} + +#[cfg(unix)] +impl PartialEq for SocketAddrUnix { + #[inline] + fn eq(&self, other: &Self) -> bool { + let self_len = self.len() - offsetof_sun_path(); + let other_len = other.len() - offsetof_sun_path(); + self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) + } +} + +#[cfg(unix)] +impl Eq for SocketAddrUnix {} + +#[cfg(unix)] +impl PartialOrd for SocketAddrUnix { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + 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]) + } +} + +#[cfg(unix)] +impl Ord for SocketAddrUnix { + #[inline] + fn cmp(&self, other: &Self) -> core::cmp::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]) + } +} + +#[cfg(unix)] +impl core::hash::Hash for SocketAddrUnix { + #[inline] + fn hash(&self, state: &mut H) { + let self_len = self.len() - offsetof_sun_path(); + self.unix.sun_path[..self_len].hash(state) + } +} + +#[cfg(unix)] +impl fmt::Debug for SocketAddrUnix { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(path) = self.path() { + path.fmt(fmt) + } else { + #[cfg(any(target_os = "android", target_os = "linux"))] + if let Some(name) = self.abstract_name() { + return name.fmt(fmt); + } + + "(unnamed)".fmt(fmt) + } + } +} + +/// `struct sockaddr_storage` as a raw struct. +pub type SocketAddrStorage = c::sockaddr_storage; + +/// Return the offset of the `sun_path` field of `sockaddr_un`. +#[cfg(not(windows))] +#[inline] +pub(crate) fn offsetof_sun_path() -> usize { + let z = c::sockaddr_un { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sun_len: 0_u8, + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sun_family: 0_u8, + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + sun_family: 0_u16, + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sun_path: [0; 104], + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + sun_path: [0; 108], + #[cfg(target_os = "haiku")] + sun_path: [0; 126], + }; + (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) +} diff --git a/vendor/rustix/src/backend/libc/net/ext.rs b/vendor/rustix/src/backend/libc/net/ext.rs new file mode 100644 index 000000000..1c8f9f65c --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/ext.rs @@ -0,0 +1,210 @@ +use super::super::c; + +/// The windows `sockaddr_in6` type is a union with accessor functions which +/// are not `const fn`. Define our own layout-compatible version so that we +/// can transmute in and out of it. +#[cfg(windows)] +#[repr(C)] +struct sockaddr_in6 { + sin6_family: u16, + sin6_port: u16, + sin6_flowinfo: u32, + sin6_addr: c::in6_addr, + sin6_scope_id: u32, +} + +#[cfg(not(windows))] +#[inline] +pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { + addr.s_addr +} + +#[cfg(not(feature = "std"))] +#[cfg(windows)] +#[inline] +pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { + // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. + unsafe { core::mem::transmute(addr) } +} + +// TODO: With Rust 1.55, we can use the above `in_addr_s_addr` definition that +// uses a const-fn transmute. +#[cfg(feature = "std")] +#[cfg(windows)] +#[inline] +pub(crate) fn in_addr_s_addr(addr: c::in_addr) -> u32 { + // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. + unsafe { core::mem::transmute(addr) } +} + +#[cfg(not(windows))] +#[inline] +pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { + c::in_addr { s_addr } +} + +#[cfg(not(feature = "std"))] +#[cfg(windows)] +#[inline] +pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { + unsafe { core::mem::transmute(s_addr) } +} + +// TODO: With Rust 1.55, we can use the above `in_addr_new` definition that +// uses a const-fn transmute. +#[cfg(feature = "std")] +#[cfg(windows)] +#[inline] +pub(crate) fn in_addr_new(s_addr: u32) -> c::in_addr { + unsafe { core::mem::transmute(s_addr) } +} + +#[cfg(not(windows))] +#[inline] +pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { + addr.s6_addr +} + +#[cfg(not(feature = "std"))] +#[cfg(windows)] +#[inline] +pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { + unsafe { core::mem::transmute(addr) } +} + +// TODO: With Rust 1.55, we can use the above `in6_addr_s6_addr` definition +// that uses a const-fn transmute. +#[cfg(feature = "std")] +#[cfg(windows)] +#[inline] +pub(crate) fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { + unsafe { core::mem::transmute(addr) } +} + +#[cfg(not(windows))] +#[inline] +pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { + c::in6_addr { s6_addr } +} + +#[cfg(not(feature = "std"))] +#[cfg(windows)] +#[inline] +pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { + unsafe { core::mem::transmute(s6_addr) } +} + +// TODO: With Rust 1.55, we can use the above `in6_addr_new` definition that +// uses a const-fn transmute. +#[cfg(feature = "std")] +#[cfg(windows)] +#[inline] +pub(crate) fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { + unsafe { core::mem::transmute(s6_addr) } +} + +#[cfg(not(windows))] +#[inline] +pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { + addr.sin6_scope_id +} + +#[cfg(not(feature = "std"))] +#[cfg(windows)] +#[inline] +pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { + let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; + addr.sin6_scope_id +} + +// TODO: With Rust 1.55, we can use the above `sockaddr_in6_sin6_scope_id` +// definition that uses a const-fn transmute. +#[cfg(feature = "std")] +#[cfg(windows)] +#[inline] +pub(crate) fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { + let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; + addr.sin6_scope_id +} + +#[cfg(not(windows))] +#[inline] +pub(crate) const fn sockaddr_in6_new( + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sin6_len: u8, + sin6_family: c::sa_family_t, + sin6_port: u16, + sin6_flowinfo: u32, + sin6_addr: c::in6_addr, + sin6_scope_id: u32, +) -> c::sockaddr_in6 { + c::sockaddr_in6 { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sin6_len, + sin6_family, + sin6_port, + sin6_flowinfo, + sin6_addr, + sin6_scope_id, + #[cfg(any(target_os = "illumos", target_os = "solaris"))] + __sin6_src_id: 0, + } +} + +#[cfg(not(feature = "std"))] +#[cfg(windows)] +#[inline] +pub(crate) const fn sockaddr_in6_new( + sin6_family: u16, + sin6_port: u16, + sin6_flowinfo: u32, + sin6_addr: c::in6_addr, + sin6_scope_id: u32, +) -> c::sockaddr_in6 { + let addr = sockaddr_in6 { + sin6_family, + sin6_port, + sin6_flowinfo, + sin6_addr, + sin6_scope_id, + }; + unsafe { core::mem::transmute(addr) } +} + +// TODO: With Rust 1.55, we can use the above `sockaddr_in6_new` definition +// that uses a const-fn transmute. +#[cfg(feature = "std")] +#[cfg(windows)] +#[inline] +pub(crate) fn sockaddr_in6_new( + sin6_family: u16, + sin6_port: u16, + sin6_flowinfo: u32, + sin6_addr: c::in6_addr, + sin6_scope_id: u32, +) -> c::sockaddr_in6 { + let addr = sockaddr_in6 { + sin6_family, + sin6_port, + sin6_flowinfo, + sin6_addr, + sin6_scope_id, + }; + unsafe { core::mem::transmute(addr) } +} diff --git a/vendor/rustix/src/backend/libc/net/mod.rs b/vendor/rustix/src/backend/libc/net/mod.rs new file mode 100644 index 000000000..f7196ae4f --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/mod.rs @@ -0,0 +1,7 @@ +pub(crate) mod addr; +pub(crate) mod ext; +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/libc/net/read_sockaddr.rs b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs new file mode 100644 index 000000000..5a946fbeb --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/read_sockaddr.rs @@ -0,0 +1,255 @@ +use super::super::c; +#[cfg(unix)] +use super::addr::SocketAddrUnix; +use super::ext::{in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_sin6_scope_id}; +#[cfg(not(windows))] +use crate::ffi::CStr; +use crate::io; +use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; +#[cfg(not(windows))] +use alloc::vec::Vec; +use core::mem::size_of; + +// This must match the header of `sockaddr`. +#[repr(C)] +struct sockaddr_header { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sa_len: u8, + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + ss_family: u8, + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + ss_family: u16, +} + +#[inline] +unsafe fn read_ss_family(storage: *const c::sockaddr_storage) -> u16 { + // Assert that we know the layout of `sockaddr`. + let _ = c::sockaddr { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sa_len: 0_u8, + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sa_family: 0_u8, + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + sa_family: 0_u16, + #[cfg(not(target_os = "haiku"))] + sa_data: [0; 14], + #[cfg(target_os = "haiku")] + sa_data: [0; 30], + }; + + (*storage.cast::()).ss_family.into() +} + +/// Set the `ss_family` field of a socket address to `AF_UNSPEC`, so that we +/// can test for `AF_UNSPEC` to test whether it was stored to. +pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr_storage) { + (*storage.cast::()).ss_family = c::AF_UNSPEC as _; +} + +pub(crate) unsafe fn read_sockaddr( + storage: *const c::sockaddr_storage, + len: usize, +) -> io::Result { + #[cfg(unix)] + let offsetof_sun_path = super::addr::offsetof_sun_path(); + + if len < size_of::() { + return Err(io::Errno::INVAL); + } + match read_ss_family(storage).into() { + c::AF_INET => { + if len < size_of::() { + return Err(io::Errno::INVAL); + } + let decode = *storage.cast::(); + Ok(SocketAddrAny::V4(SocketAddrV4::new( + Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), + u16::from_be(decode.sin_port), + ))) + } + c::AF_INET6 => { + if len < size_of::() { + return Err(io::Errno::INVAL); + } + let decode = *storage.cast::(); + #[cfg(not(windows))] + let s6_addr = decode.sin6_addr.s6_addr; + #[cfg(windows)] + let s6_addr = decode.sin6_addr.u.Byte; + #[cfg(not(windows))] + let sin6_scope_id = decode.sin6_scope_id; + #[cfg(windows)] + let sin6_scope_id = decode.Anonymous.sin6_scope_id; + Ok(SocketAddrAny::V6(SocketAddrV6::new( + Ipv6Addr::from(s6_addr), + u16::from_be(decode.sin6_port), + u32::from_be(decode.sin6_flowinfo), + sin6_scope_id, + ))) + } + #[cfg(unix)] + c::AF_UNIX => { + if len < offsetof_sun_path { + return Err(io::Errno::INVAL); + } + if len == offsetof_sun_path { + Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap())) + } else { + let decode = *storage.cast::(); + + // Trim off unused bytes from the end of `path_bytes`. + let path_bytes = if cfg!(target_os = "freebsd") { + // FreeBSD sometimes sets the length to longer than the length + // of the NUL-terminated string. Find the NUL and truncate the + // string accordingly. + &decode.sun_path[..decode.sun_path.iter().position(|b| *b == 0).unwrap()] + } else { + // Otherwise, use the provided length. + let provided_len = len - 1 - offsetof_sun_path; + if decode.sun_path[provided_len] != b'\0' as c::c_char { + return Err(io::Errno::INVAL); + } + debug_assert_eq!( + CStr::from_ptr(decode.sun_path.as_ptr()).to_bytes().len(), + provided_len + ); + &decode.sun_path[..provided_len] + }; + + Ok(SocketAddrAny::Unix( + SocketAddrUnix::new(path_bytes.iter().map(|c| *c as u8).collect::>()) + .unwrap(), + )) + } + } + _ => Err(io::Errno::INVAL), + } +} + +pub(crate) unsafe fn maybe_read_sockaddr_os( + storage: *const c::sockaddr_storage, + len: usize, +) -> Option { + if len == 0 { + return None; + } + + assert!(len >= size_of::()); + let family = read_ss_family(storage).into(); + if family == c::AF_UNSPEC { + None + } else { + Some(inner_read_sockaddr_os(family, storage, len)) + } +} + +pub(crate) unsafe fn read_sockaddr_os( + storage: *const c::sockaddr_storage, + len: usize, +) -> SocketAddrAny { + assert!(len >= size_of::()); + let family = read_ss_family(storage).into(); + inner_read_sockaddr_os(family, storage, len) +} + +unsafe fn inner_read_sockaddr_os( + family: c::c_int, + storage: *const c::sockaddr_storage, + len: usize, +) -> SocketAddrAny { + #[cfg(unix)] + let offsetof_sun_path = super::addr::offsetof_sun_path(); + + assert!(len >= size_of::()); + match family { + c::AF_INET => { + assert!(len >= size_of::()); + let decode = *storage.cast::(); + SocketAddrAny::V4(SocketAddrV4::new( + Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), + u16::from_be(decode.sin_port), + )) + } + c::AF_INET6 => { + assert!(len >= size_of::()); + let decode = *storage.cast::(); + SocketAddrAny::V6(SocketAddrV6::new( + Ipv6Addr::from(in6_addr_s6_addr(decode.sin6_addr)), + u16::from_be(decode.sin6_port), + u32::from_be(decode.sin6_flowinfo), + sockaddr_in6_sin6_scope_id(decode), + )) + } + #[cfg(unix)] + c::AF_UNIX => { + assert!(len >= offsetof_sun_path); + if len == offsetof_sun_path { + SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) + } else { + let decode = *storage.cast::(); + assert_eq!( + decode.sun_path[len - 1 - offsetof_sun_path], + b'\0' as c::c_char + ); + let path_bytes = &decode.sun_path[..len - 1 - offsetof_sun_path]; + + // FreeBSD sometimes sets the length to longer than the length + // of the NUL-terminated string. Find the NUL and truncate the + // string accordingly. + #[cfg(target_os = "freebsd")] + let path_bytes = &path_bytes[..path_bytes.iter().position(|b| *b == 0).unwrap()]; + + SocketAddrAny::Unix( + SocketAddrUnix::new(path_bytes.iter().map(|c| *c as u8).collect::>()) + .unwrap(), + ) + } + } + other => unimplemented!("{:?}", other), + } +} diff --git a/vendor/rustix/src/backend/libc/net/send_recv.rs b/vendor/rustix/src/backend/libc/net/send_recv.rs new file mode 100644 index 000000000..8d1cc8ab7 --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/send_recv.rs @@ -0,0 +1,83 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `MSG_*` + pub struct SendFlags: i32 { + /// `MSG_CONFIRM` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + const CONFIRM = c::MSG_CONFIRM; + /// `MSG_DONTROUTE` + const DONTROUTE = c::MSG_DONTROUTE; + /// `MSG_DONTWAIT` + #[cfg(not(windows))] + const DONTWAIT = c::MSG_DONTWAIT; + /// `MSG_EOR` + #[cfg(not(windows))] + const EOT = c::MSG_EOR; + /// `MSG_MORE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + const MORE = c::MSG_MORE; + #[cfg(not(any(windows, target_os = "ios", target_os = "macos")))] + /// `MSG_NOSIGNAL` + const NOSIGNAL = c::MSG_NOSIGNAL; + /// `MSG_OOB` + const OOB = c::MSG_OOB; + } +} + +bitflags! { + /// `MSG_*` + pub struct RecvFlags: i32 { + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "solaris")))] + /// `MSG_CMSG_CLOEXEC` + const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; + /// `MSG_DONTWAIT` + #[cfg(not(windows))] + const DONTWAIT = c::MSG_DONTWAIT; + /// `MSG_ERRQUEUE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + const ERRQUEUE = c::MSG_ERRQUEUE; + /// `MSG_OOB` + const OOB = c::MSG_OOB; + /// `MSG_PEEK` + const PEEK = c::MSG_PEEK; + /// `MSG_TRUNC` + const TRUNC = c::MSG_TRUNC as c::c_int; + /// `MSG_WAITALL` + const WAITALL = c::MSG_WAITALL; + } +} diff --git a/vendor/rustix/src/backend/libc/net/syscalls.rs b/vendor/rustix/src/backend/libc/net/syscalls.rs new file mode 100644 index 000000000..3d8a849c7 --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/syscalls.rs @@ -0,0 +1,886 @@ +//! libc syscalls supporting `rustix::net`. + +use super::super::c; +use super::super::conv::{borrowed_fd, ret, ret_owned_fd, ret_send_recv, send_recv_len}; +#[cfg(unix)] +use super::addr::SocketAddrUnix; +use super::ext::{in6_addr_new, in_addr_new}; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +use super::read_sockaddr::initialize_family_to_unspec; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +use super::read_sockaddr::{maybe_read_sockaddr_os, read_sockaddr_os}; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +use super::send_recv::{RecvFlags, SendFlags}; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +use super::types::{AcceptFlags, AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; +use crate::utils::as_ptr; +use core::convert::TryInto; +use core::mem::{size_of, MaybeUninit}; +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +use core::ptr::null_mut; + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io::Result { + let nrecv = unsafe { + ret_send_recv(c::recv( + borrowed_fd(fd), + buf.as_mut_ptr().cast(), + send_recv_len(buf.len()), + flags.bits(), + ))? + }; + Ok(nrecv as usize) +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result { + let nwritten = unsafe { + ret_send_recv(c::send( + borrowed_fd(fd), + buf.as_ptr().cast(), + send_recv_len(buf.len()), + flags.bits(), + ))? + }; + Ok(nwritten as usize) +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn recvfrom( + fd: BorrowedFd<'_>, + buf: &mut [u8], + flags: RecvFlags, +) -> io::Result<(usize, Option)> { + unsafe { + let mut storage = MaybeUninit::::uninit(); + let mut len = size_of::() as c::socklen_t; + + // `recvfrom` does not write to the storage if the socket is + // connection-oriented sockets, so we initialize the family field to + // `AF_UNSPEC` so that we can detect this case. + initialize_family_to_unspec(storage.as_mut_ptr()); + + let nread = ret_send_recv(c::recvfrom( + borrowed_fd(fd), + buf.as_mut_ptr().cast(), + send_recv_len(buf.len()), + flags.bits(), + storage.as_mut_ptr().cast(), + &mut len, + ))?; + Ok(( + nread as usize, + maybe_read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap()), + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn sendto_v4( + fd: BorrowedFd<'_>, + buf: &[u8], + flags: SendFlags, + addr: &SocketAddrV4, +) -> io::Result { + let nwritten = unsafe { + ret_send_recv(c::sendto( + borrowed_fd(fd), + buf.as_ptr().cast(), + send_recv_len(buf.len()), + flags.bits(), + as_ptr(&encode_sockaddr_v4(addr)).cast::(), + size_of::() as _, + ))? + }; + Ok(nwritten as usize) +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn sendto_v6( + fd: BorrowedFd<'_>, + buf: &[u8], + flags: SendFlags, + addr: &SocketAddrV6, +) -> io::Result { + let nwritten = unsafe { + ret_send_recv(c::sendto( + borrowed_fd(fd), + buf.as_ptr().cast(), + send_recv_len(buf.len()), + flags.bits(), + as_ptr(&encode_sockaddr_v6(addr)).cast::(), + size_of::() as _, + ))? + }; + Ok(nwritten as usize) +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn sendto_unix( + fd: BorrowedFd<'_>, + buf: &[u8], + flags: SendFlags, + addr: &SocketAddrUnix, +) -> io::Result { + let nwritten = unsafe { + ret_send_recv(c::sendto( + borrowed_fd(fd), + buf.as_ptr().cast(), + send_recv_len(buf.len()), + flags.bits(), + as_ptr(&addr.unix).cast(), + addr.addr_len(), + ))? + }; + Ok(nwritten as usize) +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn socket( + domain: AddressFamily, + type_: SocketType, + protocol: Protocol, +) -> io::Result { + unsafe { + ret_owned_fd(c::socket( + domain.0 as c::c_int, + type_.0 as c::c_int, + protocol.0, + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn socket_with( + domain: AddressFamily, + type_: SocketType, + flags: SocketFlags, + protocol: Protocol, +) -> io::Result { + unsafe { + ret_owned_fd(c::socket( + domain.0 as c::c_int, + type_.0 as c::c_int | flags.bits(), + protocol.0, + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn bind_v4(sockfd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { + unsafe { + ret(c::bind( + borrowed_fd(sockfd), + as_ptr(&encode_sockaddr_v4(addr)).cast(), + size_of::() as c::socklen_t, + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn bind_v6(sockfd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { + unsafe { + ret(c::bind( + borrowed_fd(sockfd), + as_ptr(&encode_sockaddr_v6(addr)).cast(), + size_of::() as c::socklen_t, + )) + } +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn bind_unix(sockfd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { + unsafe { + ret(c::bind( + borrowed_fd(sockfd), + as_ptr(&addr.unix).cast(), + addr.addr_len(), + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn connect_v4(sockfd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { + unsafe { + ret(c::connect( + borrowed_fd(sockfd), + as_ptr(&encode_sockaddr_v4(addr)).cast(), + size_of::() as c::socklen_t, + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn connect_v6(sockfd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { + unsafe { + ret(c::connect( + borrowed_fd(sockfd), + as_ptr(&encode_sockaddr_v6(addr)).cast(), + size_of::() as c::socklen_t, + )) + } +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn connect_unix(sockfd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { + unsafe { + ret(c::connect( + borrowed_fd(sockfd), + as_ptr(&addr.unix).cast(), + addr.addr_len(), + )) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn listen(sockfd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { + unsafe { ret(c::listen(borrowed_fd(sockfd), backlog)) } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn accept(sockfd: BorrowedFd<'_>) -> io::Result { + unsafe { + let owned_fd = ret_owned_fd(c::accept(borrowed_fd(sockfd), null_mut(), null_mut()))?; + Ok(owned_fd) + } +} + +#[cfg(not(any( + windows, + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "wasi", +)))] +pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, flags: AcceptFlags) -> io::Result { + unsafe { + let owned_fd = ret_owned_fd(c::accept4( + borrowed_fd(sockfd), + null_mut(), + null_mut(), + flags.bits(), + ))?; + Ok(owned_fd) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn acceptfrom(sockfd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option)> { + unsafe { + let mut storage = MaybeUninit::::uninit(); + let mut len = size_of::() as c::socklen_t; + let owned_fd = ret_owned_fd(c::accept( + borrowed_fd(sockfd), + storage.as_mut_ptr().cast(), + &mut len, + ))?; + Ok(( + owned_fd, + maybe_read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap()), + )) + } +} + +#[cfg(not(any( + windows, + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "wasi", +)))] +pub(crate) fn acceptfrom_with( + sockfd: BorrowedFd<'_>, + flags: AcceptFlags, +) -> io::Result<(OwnedFd, Option)> { + unsafe { + let mut storage = MaybeUninit::::uninit(); + let mut len = size_of::() as c::socklen_t; + let owned_fd = ret_owned_fd(c::accept4( + borrowed_fd(sockfd), + storage.as_mut_ptr().cast(), + &mut len, + flags.bits(), + ))?; + Ok(( + owned_fd, + maybe_read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap()), + )) + } +} + +/// Darwin lacks `accept4`, but does have `accept`. We define +/// `AcceptFlags` to have no flags, so we can discard it here. +#[cfg(any(windows, target_os = "haiku", target_os = "ios", target_os = "macos"))] +pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, _flags: AcceptFlags) -> io::Result { + accept(sockfd) +} + +/// Darwin lacks `accept4`, but does have `accept`. We define +/// `AcceptFlags` to have no flags, so we can discard it here. +#[cfg(any(windows, target_os = "haiku", target_os = "ios", target_os = "macos"))] +pub(crate) fn acceptfrom_with( + sockfd: BorrowedFd<'_>, + _flags: AcceptFlags, +) -> io::Result<(OwnedFd, Option)> { + acceptfrom(sockfd) +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn shutdown(sockfd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { + unsafe { ret(c::shutdown(borrowed_fd(sockfd), how as c::c_int)) } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn getsockname(sockfd: BorrowedFd<'_>) -> io::Result { + unsafe { + let mut storage = MaybeUninit::::uninit(); + let mut len = size_of::() as c::socklen_t; + ret(c::getsockname( + borrowed_fd(sockfd), + storage.as_mut_ptr().cast(), + &mut len, + ))?; + Ok(read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap())) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) fn getpeername(sockfd: BorrowedFd<'_>) -> io::Result> { + unsafe { + let mut storage = MaybeUninit::::uninit(); + let mut len = size_of::() as c::socklen_t; + ret(c::getpeername( + borrowed_fd(sockfd), + storage.as_mut_ptr().cast(), + &mut len, + ))?; + Ok(maybe_read_sockaddr_os( + storage.as_ptr(), + len.try_into().unwrap(), + )) + } +} + +#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +pub(crate) fn socketpair( + domain: AddressFamily, + type_: SocketType, + flags: SocketFlags, + protocol: Protocol, +) -> io::Result<(OwnedFd, OwnedFd)> { + unsafe { + let mut fds = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(c::socketpair( + c::c_int::from(domain.0), + type_.0 as c::c_int | flags.bits(), + protocol.0, + fds.as_mut_ptr().cast::(), + ))?; + + let [fd0, fd1] = fds.assume_init(); + Ok((fd0, fd1)) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +pub(crate) mod sockopt { + use super::{c, in6_addr_new, in_addr_new, BorrowedFd}; + use crate::io; + use crate::net::sockopt::Timeout; + use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; + use crate::utils::as_mut_ptr; + use core::convert::TryInto; + use core::time::Duration; + #[cfg(windows)] + use windows_sys::Win32::Foundation::BOOL; + + // TODO: With Rust 1.53 we can use `Duration::ZERO` instead. + const DURATION_ZERO: Duration = Duration::from_secs(0); + + #[inline] + fn getsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result { + use super::*; + + let mut optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + unsafe { + let mut value = core::mem::zeroed::(); + ret(c::getsockopt( + borrowed_fd(fd), + level, + optname, + as_mut_ptr(&mut value).cast(), + &mut optlen, + ))?; + // On Windows at least, `getsockopt` has been observed writing 1 + // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though + // Windows' documentation says that should write a 4-byte `BOOL`. + // So, we initialize the memory to zeros above, and just assert + // that `getsockopt` doesn't write too many bytes here. + assert!( + optlen as usize <= size_of::(), + "unexpected getsockopt size" + ); + Ok(value) + } + } + + #[inline] + fn setsockopt( + fd: BorrowedFd<'_>, + level: i32, + optname: i32, + value: T, + ) -> io::Result<()> { + use super::*; + + let optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + unsafe { + ret(c::setsockopt( + borrowed_fd(fd), + level, + optname, + as_ptr(&value).cast(), + optlen, + )) + } + } + + #[inline] + pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) + } + + #[inline] + pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_REUSEADDR, + from_bool(reuseaddr), + ) + } + + #[inline] + pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_BROADCAST, + from_bool(broadcast), + ) + } + + #[inline] + pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) + } + + #[inline] + pub(crate) fn set_socket_linger( + fd: BorrowedFd<'_>, + linger: Option, + ) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + let mut l_linger = linger.as_secs(); + if linger.subsec_nanos() != 0 { + l_linger = l_linger.checked_add(1).ok_or(io::Errno::INVAL)?; + } + l_linger.try_into().map_err(|_e| io::Errno::INVAL)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: linger.is_some() as _, + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) + } + + #[inline] + pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { + 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 + }) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[inline] + pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + #[inline] + pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) + } + + #[inline] + pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, + ) -> io::Result<()> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO, + Timeout::Send => c::SO_SNDTIMEO, + }; + + #[cfg(not(windows))] + let timeout = match timeout { + Some(timeout) => { + if timeout == DURATION_ZERO { + return Err(io::Errno::INVAL); + } + + let tv_sec = timeout.as_secs().try_into(); + #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] + let tv_sec = tv_sec.unwrap_or(c::c_long::MAX); + #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] + let tv_sec = tv_sec.unwrap_or(i64::MAX); + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = c::timeval { + tv_sec, + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => c::timeval { + tv_sec: 0, + tv_usec: 0, + }, + }; + + #[cfg(windows)] + let timeout: u32 = match timeout { + Some(timeout) => { + if timeout == DURATION_ZERO { + return Err(io::Errno::INVAL); + } + + // `as_millis` rounds down, so we use `as_nanos` and + // manually round up. + let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) + .try_into() + .map_err(|_convert_err| io::Errno::INVAL)?; + if timeout == 0 { + timeout = 1; + } + timeout + } + None => 0, + }; + + setsockopt(fd, c::SOL_SOCKET, optname, timeout) + } + + #[inline] + pub(crate) fn get_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + ) -> io::Result> { + let optname = match id { + Timeout::Recv => c::SO_RCVTIMEO, + Timeout::Send => c::SO_SNDTIMEO, + }; + + #[cfg(not(windows))] + { + let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + Ok(None) + } else { + Ok(Some( + Duration::from_secs(timeout.tv_sec as u64) + + Duration::from_micros(timeout.tv_usec as u64), + )) + } + } + + #[cfg(windows)] + { + let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; + if timeout == 0 { + Ok(None) + } else { + Ok(Some(Duration::from_millis(timeout as u64))) + } + } + } + + #[inline] + pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) + } + + #[inline] + pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) + } + + #[inline] + pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) + } + + #[inline] + pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) + } + + #[inline] + pub(crate) fn set_ip_multicast_loop( + fd: BorrowedFd<'_>, + multicast_loop: bool, + ) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) + } + + #[inline] + pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) + } + + #[inline] + pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) + } + + #[inline] + pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) + } + + #[inline] + pub(crate) fn set_ipv6_multicast_loop( + fd: BorrowedFd<'_>, + multicast_loop: bool, + ) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6 as _, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) + } + + #[inline] + pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) + } + + #[inline] + pub(crate) fn set_ipv6_multicast_hops( + fd: BorrowedFd<'_>, + multicast_hops: u32, + ) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IPV6_MULTICAST_LOOP, + multicast_hops, + ) + } + + #[inline] + pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_LOOP) + } + + #[inline] + pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + ) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, + ) -> io::Result<()> { + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "l4re", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + use c::IPV6_ADD_MEMBERSHIP; + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "l4re", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + ))] + use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; + + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_ADD_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + ) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, + ) -> io::Result<()> { + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "l4re", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + use c::IPV6_DROP_MEMBERSHIP; + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "l4re", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + ))] + use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; + + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_DROP_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) + } + + #[inline] + pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) + } + + #[inline] + fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } + } + + #[inline] + fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + in_addr_new(u32::from_ne_bytes(addr.octets())) + } + + #[inline] + fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_interface: to_ipv6mr_interface(interface), + } + } + + #[inline] + fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + in6_addr_new(multiaddr.octets()) + } + + #[cfg(target_os = "android")] + #[inline] + fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int + } + + #[cfg(not(target_os = "android"))] + #[inline] + fn to_ipv6mr_interface(interface: u32) -> c::c_uint { + interface as c::c_uint + } + + // `getsockopt` and `setsockopt` represent boolean values as integers. + #[cfg(not(windows))] + type RawSocketBool = c::c_int; + #[cfg(windows)] + type RawSocketBool = BOOL; + + // Wrap `RawSocketBool` in a newtype to discourage misuse. + #[repr(transparent)] + #[derive(Copy, Clone)] + struct SocketBool(RawSocketBool); + + // Convert from a `bool` to a `SocketBool`. + #[inline] + fn from_bool(value: bool) -> SocketBool { + SocketBool(value as _) + } + + // Convert from a `SocketBool` to a `bool`. + #[inline] + fn to_bool(value: SocketBool) -> bool { + value.0 != 0 + } +} diff --git a/vendor/rustix/src/backend/libc/net/types.rs b/vendor/rustix/src/backend/libc/net/types.rs new file mode 100644 index 000000000..19d97e7c7 --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/types.rs @@ -0,0 +1,687 @@ +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 as u32); + + /// `SOCK_DGRAM` + pub const DGRAM: Self = Self(c::SOCK_DGRAM as u32); + + /// `SOCK_SEQPACKET` + pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET as u32); + + /// `SOCK_RAW` + pub const RAW: Self = Self(c::SOCK_RAW as u32); + + /// `SOCK_RDM` + #[cfg(not(target_os = "haiku"))] + pub const RDM: Self = Self(c::SOCK_RDM as u32); + + /// 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] +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` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + 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` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + 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` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const NETROM: Self = Self(c::AF_NETROM as _); + /// `AF_BRIDGE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); + /// `AF_ATMPVC` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); + /// `AF_X25` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + pub const X25: Self = Self(c::AF_X25 as _); + /// `AF_ROSE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const ROSE: Self = Self(c::AF_ROSE as _); + /// `AF_DECnet` + #[allow(non_upper_case_globals)] + #[cfg(not(target_os = "haiku"))] + pub const DECnet: Self = Self(c::AF_DECnet as _); + /// `AF_NETBEUI` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); + /// `AF_SECURITY` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const SECURITY: Self = Self(c::AF_SECURITY as _); + /// `AF_KEY` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + pub const KEY: Self = Self(c::AF_KEY as _); + /// `AF_PACKET` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + pub const PACKET: Self = Self(c::AF_PACKET as _); + /// `AF_ASH` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const ASH: Self = Self(c::AF_ASH as _); + /// `AF_ECONET` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const ECONET: Self = Self(c::AF_ECONET as _); + /// `AF_ATMSVC` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); + /// `AF_RDS` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const RDS: Self = Self(c::AF_RDS as _); + /// `AF_SNA` + #[cfg(not(target_os = "haiku"))] + pub const SNA: Self = Self(c::AF_SNA as _); + /// `AF_IRDA` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const IRDA: Self = Self(c::AF_IRDA as _); + /// `AF_PPPOX` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const PPPOX: Self = Self(c::AF_PPPOX as _); + /// `AF_WANPIPE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); + /// `AF_LLC` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const LLC: Self = Self(c::AF_LLC as _); + /// `AF_CAN` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const CAN: Self = Self(c::AF_CAN as _); + /// `AF_TIPC` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const TIPC: Self = Self(c::AF_TIPC as _); + /// `AF_BLUETOOTH` + #[cfg(not(any(windows, target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "solaris")))] + pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); + /// `AF_IUCV` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const IUCV: Self = Self(c::AF_IUCV as _); + /// `AF_RXRPC` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const RXRPC: Self = Self(c::AF_RXRPC as _); + /// `AF_ISDN` + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const ISDN: Self = Self(c::AF_ISDN as _); + /// `AF_PHONET` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const PHONET: Self = Self(c::AF_PHONET as _); + /// `AF_IEEE802154` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + 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 = i32; + +/// `IPPROTO_*` +#[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` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const IGMP: Self = Self(c::IPPROTO_IGMP as _); + /// `IPPROTO_IPIP` + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const IPIP: Self = Self(c::IPPROTO_IPIP as _); + /// `IPPROTO_TCP` + pub const TCP: Self = Self(c::IPPROTO_TCP as _); + /// `IPPROTO_EGP` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const EGP: Self = Self(c::IPPROTO_EGP as _); + /// `IPPROTO_PUP` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const PUP: Self = Self(c::IPPROTO_PUP as _); + /// `IPPROTO_UDP` + pub const UDP: Self = Self(c::IPPROTO_UDP as _); + /// `IPPROTO_IDP` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const IDP: Self = Self(c::IPPROTO_IDP as _); + /// `IPPROTO_TP` + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const TP: Self = Self(c::IPPROTO_TP as _); + /// `IPPROTO_DCCP` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const DCCP: Self = Self(c::IPPROTO_DCCP as _); + /// `IPPROTO_IPV6` + pub const IPV6: Self = Self(c::IPPROTO_IPV6 as _); + /// `IPPROTO_RSVP` + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const RSVP: Self = Self(c::IPPROTO_RSVP as _); + /// `IPPROTO_GRE` + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const GRE: Self = Self(c::IPPROTO_GRE as _); + /// `IPPROTO_ESP` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const ESP: Self = Self(c::IPPROTO_ESP as _); + /// `IPPROTO_AH` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const AH: Self = Self(c::IPPROTO_AH as _); + /// `IPPROTO_MTP` + #[cfg(not(any( + windows, + target_os = "haiku", + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const MTP: Self = Self(c::IPPROTO_MTP as _); + /// `IPPROTO_BEETPH` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const BEETPH: Self = Self(c::IPPROTO_BEETPH as _); + /// `IPPROTO_ENCAP` + #[cfg(not(any(windows, target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const ENCAP: Self = Self(c::IPPROTO_ENCAP as _); + /// `IPPROTO_PIM` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const PIM: Self = Self(c::IPPROTO_PIM as _); + /// `IPPROTO_COMP` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const COMP: Self = Self(c::IPPROTO_COMP as _); + /// `IPPROTO_SCTP` + #[cfg(not(any(target_os = "dragonfly", target_os = "haiku", target_os = "illumos", target_os = "openbsd", target_os = "solaris")))] + pub const SCTP: Self = Self(c::IPPROTO_SCTP as _); + /// `IPPROTO_UDPLITE` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const UDPLITE: Self = Self(c::IPPROTO_UDPLITE as _); + /// `IPPROTO_MPLS` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "solaris", + )))] + pub const MPLS: Self = Self(c::IPPROTO_MPLS as _); + /// `IPPROTO_RAW` + pub const RAW: Self = Self(c::IPPROTO_RAW as _); + /// `IPPROTO_MPTCP` + #[cfg(not(any( + windows, + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const MPTCP: Self = Self(c::IPPROTO_MPTCP as _); + /// `IPPROTO_FRAGMENT` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + pub const FRAGMENT: Self = Self(c::IPPROTO_FRAGMENT as _); + /// `IPPROTO_ICMPV6` + pub const ICMPV6: Self = Self(c::IPPROTO_ICMPV6 as _); + /// `IPPROTO_MH` + #[cfg(not(any( + windows, + target_os = "dragonfly", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + pub const MH: Self = Self(c::IPPROTO_MH as _); + /// `IPPROTO_ROUTING` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + 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(i32)] +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 [`accept_with`] and [`acceptfrom_with`]. + /// + /// [`accept_with`]: crate::net::accept_with + /// [`acceptfrom_with`]: crate::net::acceptfrom_with + pub struct AcceptFlags: c::c_int { + /// `SOCK_NONBLOCK` + #[cfg(not(any(windows, target_os = "haiku", target_os = "ios", target_os = "macos")))] + const NONBLOCK = c::SOCK_NONBLOCK; + + /// `SOCK_CLOEXEC` + #[cfg(not(any(windows, target_os = "haiku", target_os = "ios", target_os = "macos")))] + const CLOEXEC = c::SOCK_CLOEXEC; + } +} + +bitflags! { + /// `SOCK_*` constants for use with [`socket`]. + /// + /// [`socket`]: crate::net::socket + pub struct SocketFlags: c::c_int { + /// `SOCK_NONBLOCK` + #[cfg(not(any(windows, target_os = "haiku", target_os = "ios", target_os = "macos")))] + const NONBLOCK = c::SOCK_NONBLOCK; + + /// `SOCK_CLOEXEC` + #[cfg(not(any(windows, target_os = "haiku", target_os = "ios", target_os = "macos")))] + const CLOEXEC = c::SOCK_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(i32)] +pub enum Timeout { + /// `SO_RCVTIMEO`—Timeout for receiving. + Recv = c::SO_RCVTIMEO, + + /// `SO_SNDTIMEO`—Timeout for sending. + Send = c::SO_SNDTIMEO, +} diff --git a/vendor/rustix/src/backend/libc/net/write_sockaddr.rs b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs new file mode 100644 index 000000000..f44284a0b --- /dev/null +++ b/vendor/rustix/src/backend/libc/net/write_sockaddr.rs @@ -0,0 +1,102 @@ +//! The BSD sockets API requires us to read the `ss_family` field before +//! we can interpret the rest of a `sockaddr` produced by the kernel. + +use super::super::c; +use super::addr::SocketAddrStorage; +#[cfg(unix)] +use super::addr::SocketAddrUnix; +use super::ext::{in6_addr_new, in_addr_new, sockaddr_in6_new}; +use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; +use core::mem::size_of; + +pub(crate) unsafe fn write_sockaddr( + addr: &SocketAddrAny, + storage: *mut SocketAddrStorage, +) -> usize { + match addr { + SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage), + SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage), + #[cfg(unix)] + SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage), + } +} + +pub(crate) unsafe fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { + c::sockaddr_in { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + sin_len: size_of::() as _, + sin_family: c::AF_INET as _, + sin_port: u16::to_be(v4.port()), + sin_addr: in_addr_new(u32::from_ne_bytes(v4.ip().octets())), + #[cfg(not(target_os = "haiku"))] + sin_zero: [0; 8_usize], + #[cfg(target_os = "haiku")] + sin_zero: [0; 24_usize], + } +} + +unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize { + let encoded = encode_sockaddr_v4(v4); + core::ptr::write(storage.cast(), encoded); + size_of::() +} + +pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { + #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + ))] + { + sockaddr_in6_new( + size_of::() as _, + c::AF_INET6 as _, + u16::to_be(v6.port()), + u32::to_be(v6.flowinfo()), + in6_addr_new(v6.ip().octets()), + v6.scope_id(), + ) + } + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + { + sockaddr_in6_new( + c::AF_INET6 as _, + u16::to_be(v6.port()), + u32::to_be(v6.flowinfo()), + in6_addr_new(v6.ip().octets()), + v6.scope_id(), + ) + } +} + +unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize { + let encoded = encode_sockaddr_v6(v6); + core::ptr::write(storage.cast(), encoded); + size_of::() +} + +#[cfg(unix)] +unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize { + core::ptr::write(storage.cast(), unix.unix); + unix.len() +} diff --git a/vendor/rustix/src/backend/libc/offset.rs b/vendor/rustix/src/backend/libc/offset.rs new file mode 100644 index 000000000..48729be0c --- /dev/null +++ b/vendor/rustix/src/backend/libc/offset.rs @@ -0,0 +1,406 @@ +//! Automatically enable “large file” support features. + +#[cfg(not(windows))] +use super::c; + +#[cfg(not(any( + windows, + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", +)))] +#[cfg(feature = "fs")] +pub(super) use c::{ + fstat as libc_fstat, fstatat as libc_fstatat, ftruncate as libc_ftruncate, lseek as libc_lseek, + off_t as libc_off_t, +}; + +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", +))] +#[cfg(feature = "fs")] +pub(super) use c::{ + fstat64 as libc_fstat, fstatat64 as libc_fstatat, ftruncate64 as libc_ftruncate, + lseek64 as libc_lseek, off64_t as libc_off_t, +}; + +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", +))] +pub(super) use c::rlimit64 as libc_rlimit; + +#[cfg(not(any( + windows, + target_os = "android", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", + target_os = "wasi", +)))] +#[cfg(feature = "mm")] +pub(super) use c::mmap as libc_mmap; + +#[cfg(not(any( + windows, + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "l4re", + target_os = "linux", + target_os = "redox", + target_os = "wasi", +)))] +pub(super) use c::{rlimit as libc_rlimit, RLIM_INFINITY as LIBC_RLIM_INFINITY}; + +#[cfg(not(any( + windows, + target_os = "android", + target_os = "fuchsia", + target_os = "emscripten", + target_os = "l4re", + target_os = "linux", + target_os = "wasi", +)))] +pub(super) use c::{getrlimit as libc_getrlimit, setrlimit as libc_setrlimit}; + +// TODO: Add `RLIM64_INFINITY` to upstream libc. +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +))] +pub(super) const LIBC_RLIM_INFINITY: u64 = !0_u64; + +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +))] +pub(super) use c::{getrlimit64 as libc_getrlimit, setrlimit64 as libc_setrlimit}; + +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +))] +#[cfg(feature = "mm")] +pub(super) use c::mmap64 as libc_mmap; + +// `prlimit64` wasn't supported in glibc until 2.13. +#[cfg(all(target_os = "linux", target_env = "gnu"))] +weak_or_syscall! { + fn prlimit64( + pid: c::pid_t, + resource: c::__rlimit_resource_t, + new_limit: *const c::rlimit64, + old_limit: *mut c::rlimit64 + ) via SYS_prlimit64 -> c::c_int +} +#[cfg(all(target_os = "linux", target_env = "musl"))] +weak_or_syscall! { + fn prlimit64( + pid: c::pid_t, + resource: c::c_int, + new_limit: *const c::rlimit64, + old_limit: *mut c::rlimit64 + ) via SYS_prlimit64 -> c::c_int +} +#[cfg(target_os = "android")] +weak_or_syscall! { + fn prlimit64( + pid: c::pid_t, + resource: c::c_int, + new_limit: *const c::rlimit64, + old_limit: *mut c::rlimit64 + ) via SYS_prlimit64 -> c::c_int +} +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub(super) unsafe fn libc_prlimit( + pid: c::pid_t, + resource: c::__rlimit_resource_t, + new_limit: *const c::rlimit64, + old_limit: *mut c::rlimit64, +) -> c::c_int { + prlimit64(pid, resource, new_limit, old_limit) +} +#[cfg(all(target_os = "linux", target_env = "musl"))] +pub(super) unsafe fn libc_prlimit( + pid: c::pid_t, + resource: c::c_int, + new_limit: *const c::rlimit64, + old_limit: *mut c::rlimit64, +) -> c::c_int { + prlimit64(pid, resource, new_limit, old_limit) +} +#[cfg(target_os = "android")] +pub(super) unsafe fn libc_prlimit( + pid: c::pid_t, + resource: c::c_int, + new_limit: *const c::rlimit64, + old_limit: *mut c::rlimit64, +) -> c::c_int { + prlimit64(pid, resource, new_limit, old_limit) +} + +#[cfg(not(any( + windows, + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", + target_os = "redox", +)))] +#[cfg(feature = "fs")] +pub(super) use c::openat as libc_openat; +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +))] +#[cfg(feature = "fs")] +pub(super) use c::openat64 as libc_openat; + +#[cfg(target_os = "fuchsia")] +#[cfg(feature = "fs")] +pub(super) use c::fallocate as libc_fallocate; +#[cfg(any(target_os = "android", target_os = "linux"))] +#[cfg(feature = "fs")] +pub(super) use c::fallocate64 as libc_fallocate; +#[cfg(not(any( + windows, + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "linux", + target_os = "l4re", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +#[cfg(feature = "fs")] +pub(super) use c::posix_fadvise as libc_posix_fadvise; +#[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "linux", + target_os = "l4re", +))] +#[cfg(feature = "fs")] +pub(super) use c::posix_fadvise64 as libc_posix_fadvise; + +#[cfg(all(not(any( + windows, + target_os = "android", + target_os = "linux", + target_os = "emscripten", +))))] +pub(super) use c::{pread as libc_pread, pwrite as libc_pwrite}; +#[cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten"))] +pub(super) use c::{pread64 as libc_pread, pwrite64 as libc_pwrite}; +#[cfg(any(target_os = "linux", target_os = "emscripten"))] +pub(super) use c::{preadv64 as libc_preadv, pwritev64 as libc_pwritev}; +#[cfg(target_os = "android")] +mod readwrite_pv64 { + use super::c; + + // 64-bit offsets on 32-bit platforms are passed in endianness-specific + // lo/hi pairs. See src/backend/linux_raw/conv.rs for details. + #[cfg(all(target_endian = "little", target_pointer_width = "32"))] + fn lo(x: u64) -> usize { + (x >> 32) as usize + } + #[cfg(all(target_endian = "little", target_pointer_width = "32"))] + fn hi(x: u64) -> usize { + (x & 0xffff_ffff) as usize + } + #[cfg(all(target_endian = "big", target_pointer_width = "32"))] + fn lo(x: u64) -> usize { + (x & 0xffff_ffff) as usize + } + #[cfg(all(target_endian = "big", target_pointer_width = "32"))] + fn hi(x: u64) -> usize { + (x >> 32) as usize + } + + pub(in super::super) unsafe fn preadv64( + fd: c::c_int, + iov: *const c::iovec, + iovcnt: c::c_int, + offset: c::off64_t, + ) -> c::ssize_t { + // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to + // test for it, and call back to `c::syscall`. We don't use + // `weak_or_syscall` here because we need to pass the 64-bit offset + // specially. + weak! { + fn preadv64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t + } + if let Some(fun) = preadv64.get() { + fun(fd, iov, iovcnt, offset) + } else { + #[cfg(target_pointer_width = "32")] + { + c::syscall( + c::SYS_preadv, + fd, + iov, + iovcnt, + hi(offset as u64), + lo(offset as u64), + ) as c::ssize_t + } + #[cfg(target_pointer_width = "64")] + { + c::syscall(c::SYS_preadv, fd, iov, iovcnt, offset) as c::ssize_t + } + } + } + pub(in super::super) unsafe fn pwritev64( + fd: c::c_int, + iov: *const c::iovec, + iovcnt: c::c_int, + offset: c::off64_t, + ) -> c::ssize_t { + // See the comments in `preadv64`. + weak! { + fn pwritev64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t + } + if let Some(fun) = pwritev64.get() { + fun(fd, iov, iovcnt, offset) + } else { + #[cfg(target_pointer_width = "32")] + { + c::syscall( + c::SYS_pwritev, + fd, + iov, + iovcnt, + hi(offset as u64), + lo(offset as u64), + ) as c::ssize_t + } + #[cfg(target_pointer_width = "64")] + { + c::syscall(c::SYS_pwritev, fd, iov, iovcnt, offset) as c::ssize_t + } + } + } +} +#[cfg(not(any( + windows, + target_os = "android", + target_os = "emscripten", + target_os = "haiku", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "redox", + target_os = "solaris", +)))] +pub(super) use c::{preadv as libc_preadv, pwritev as libc_pwritev}; +#[cfg(target_os = "android")] +pub(super) use readwrite_pv64::{preadv64 as libc_preadv, pwritev64 as libc_pwritev}; +// macOS added preadv and pwritev in version 11.0 +#[cfg(any(target_os = "ios", target_os = "macos"))] +mod readwrite_pv { + use super::c; + + weakcall! { + pub(in super::super) fn preadv( + fd: c::c_int, + iov: *const c::iovec, + iovcnt: c::c_int, + offset: c::off_t + ) -> c::ssize_t + } + weakcall! { + pub(in super::super) fn pwritev( + fd: c::c_int, + iov: *const c::iovec, + iovcnt: c::c_int, offset: c::off_t + ) -> c::ssize_t + } +} +#[cfg(all(target_os = "linux", target_env = "gnu"))] +pub(super) use c::{preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2}; +#[cfg(any(target_os = "ios", target_os = "macos"))] +pub(super) use readwrite_pv::{preadv as libc_preadv, pwritev as libc_pwritev}; + +#[cfg(not(any( + windows, + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "linux", + target_os = "l4re", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +#[cfg(feature = "fs")] +pub(super) use c::posix_fallocate as libc_posix_fallocate; +#[cfg(any(target_os = "l4re"))] +#[cfg(feature = "fs")] +pub(super) use c::posix_fallocate64 as libc_posix_fallocate; +#[cfg(not(any( + windows, + target_os = "android", + target_os = "emscripten", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "l4re", + target_os = "netbsd", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[cfg(feature = "fs")] +pub(super) use {c::fstatfs as libc_fstatfs, c::statfs as libc_statfs}; +#[cfg(not(any( + windows, + target_os = "android", + target_os = "emscripten", + target_os = "haiku", + target_os = "illumos", + target_os = "linux", + target_os = "l4re", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[cfg(feature = "fs")] +pub(super) use {c::fstatvfs as libc_fstatvfs, c::statvfs as libc_statvfs}; + +#[cfg(any( + target_os = "android", + target_os = "linux", + target_os = "emscripten", + target_os = "l4re", +))] +#[cfg(feature = "fs")] +pub(super) use { + c::fstatfs64 as libc_fstatfs, c::fstatvfs64 as libc_fstatvfs, c::statfs64 as libc_statfs, + c::statvfs64 as libc_statvfs, +}; diff --git a/vendor/rustix/src/backend/libc/param/auxv.rs b/vendor/rustix/src/backend/libc/param/auxv.rs new file mode 100644 index 000000000..a770c60d8 --- /dev/null +++ b/vendor/rustix/src/backend/libc/param/auxv.rs @@ -0,0 +1,54 @@ +use super::super::c; +#[cfg(any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", +))] +use crate::ffi::CStr; + +// `getauxval` wasn't supported in glibc until 2.16. +#[cfg(any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", +))] +weak!(fn getauxval(c::c_ulong) -> *mut c::c_void); + +#[inline] +pub(crate) fn page_size() -> usize { + unsafe { c::sysconf(c::_SC_PAGESIZE) as usize } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn clock_ticks_per_second() -> u64 { + unsafe { c::sysconf(c::_SC_CLK_TCK) as u64 } +} + +#[cfg(any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", +))] +#[inline] +pub(crate) fn linux_hwcap() -> (usize, usize) { + if let Some(libc_getauxval) = getauxval.get() { + unsafe { + let hwcap = libc_getauxval(c::AT_HWCAP) as usize; + let hwcap2 = libc_getauxval(c::AT_HWCAP2) as usize; + (hwcap, hwcap2) + } + } else { + (0, 0) + } +} + +#[cfg(any( + all(target_os = "android", target_pointer_width = "64"), + target_os = "linux", +))] +#[inline] +pub(crate) fn linux_execfn() -> &'static CStr { + if let Some(libc_getauxval) = getauxval.get() { + unsafe { CStr::from_ptr(libc_getauxval(c::AT_EXECFN).cast()) } + } else { + cstr!("") + } +} diff --git a/vendor/rustix/src/backend/libc/param/mod.rs b/vendor/rustix/src/backend/libc/param/mod.rs new file mode 100644 index 000000000..2cb2fe78a --- /dev/null +++ b/vendor/rustix/src/backend/libc/param/mod.rs @@ -0,0 +1 @@ +pub(crate) mod auxv; diff --git a/vendor/rustix/src/backend/libc/process/cpu_set.rs b/vendor/rustix/src/backend/libc/process/cpu_set.rs new file mode 100644 index 000000000..14ad8d208 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/cpu_set.rs @@ -0,0 +1,49 @@ +#![allow(non_snake_case)] + +use super::super::c; +use super::types::{RawCpuSet, CPU_SETSIZE}; + +#[inline] +pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { + assert!( + cpu < CPU_SETSIZE, + "cpu out of bounds: the cpu max is {} but the cpu is {}", + CPU_SETSIZE, + cpu + ); + unsafe { c::CPU_SET(cpu, cpuset) } +} + +#[inline] +pub(crate) fn CPU_ZERO(cpuset: &mut RawCpuSet) { + unsafe { c::CPU_ZERO(cpuset) } +} + +#[inline] +pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { + assert!( + cpu < CPU_SETSIZE, + "cpu out of bounds: the cpu max is {} but the cpu is {}", + CPU_SETSIZE, + cpu + ); + unsafe { c::CPU_CLR(cpu, cpuset) } +} + +#[inline] +pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { + assert!( + cpu < CPU_SETSIZE, + "cpu out of bounds: the cpu max is {} but the cpu is {}", + CPU_SETSIZE, + cpu + ); + unsafe { c::CPU_ISSET(cpu, cpuset) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { + use core::convert::TryInto; + unsafe { c::CPU_COUNT(cpuset).try_into().unwrap() } +} diff --git a/vendor/rustix/src/backend/libc/process/mod.rs b/vendor/rustix/src/backend/libc/process/mod.rs new file mode 100644 index 000000000..8675c1af9 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/mod.rs @@ -0,0 +1,12 @@ +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +pub(crate) mod cpu_set; +#[cfg(not(windows))] +pub(crate) mod syscalls; +pub(crate) mod types; +#[cfg(not(target_os = "wasi"))] +pub(crate) mod wait; diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs new file mode 100644 index 000000000..6f4e85916 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/syscalls.rs @@ -0,0 +1,465 @@ +//! libc syscalls supporting `rustix::process`. + +use super::super::c; +#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +use super::super::conv::borrowed_fd; +#[cfg(not(target_os = "wasi"))] +use super::super::conv::ret_pid_t; +use super::super::conv::{c_str, ret, ret_c_int, ret_discarded_char_ptr}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::super::conv::{syscall_ret, syscall_ret_u32}; +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +use super::types::RawCpuSet; +#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +use crate::fd::BorrowedFd; +use crate::ffi::CStr; +use crate::io; +use core::mem::MaybeUninit; +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +use { + super::super::conv::ret_infallible, + super::super::offset::{libc_getrlimit, libc_rlimit, libc_setrlimit, LIBC_RLIM_INFINITY}, + crate::process::{Resource, Rlimit}, + core::convert::TryInto, +}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use { + super::super::offset::libc_prlimit, + crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}, +}; +#[cfg(not(target_os = "wasi"))] +use { + super::types::RawUname, + crate::process::{Gid, Pid, RawNonZeroPid, RawPid, Signal, Uid, WaitOptions, WaitStatus}, +}; + +#[cfg(not(target_os = "wasi"))] +pub(crate) fn chdir(path: &CStr) -> io::Result<()> { + unsafe { ret(c::chdir(c_str(path))) } +} + +#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +pub(crate) fn fchdir(dirfd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::fchdir(borrowed_fd(dirfd))) } +} + +#[cfg(not(target_os = "wasi"))] +pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result<()> { + unsafe { ret_discarded_char_ptr(c::getcwd(buf.as_mut_ptr().cast(), buf.len())) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn membarrier_query() -> MembarrierQuery { + // GLIBC does not have a wrapper for `membarrier`; [the documentation] + // says to use `syscall`. + // + // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES + const MEMBARRIER_CMD_QUERY: u32 = 0; + unsafe { + match syscall_ret_u32(c::syscall(c::SYS_membarrier, MEMBARRIER_CMD_QUERY, 0)) { + Ok(query) => MembarrierQuery::from_bits_unchecked(query), + Err(_) => MembarrierQuery::empty(), + } + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { + unsafe { syscall_ret(c::syscall(c::SYS_membarrier, cmd as u32, 0)) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { + const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; + unsafe { + syscall_ret(c::syscall( + c::SYS_membarrier, + cmd as u32, + MEMBARRIER_CMD_FLAG_CPU, + cpu.as_raw(), + )) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getuid() -> Uid { + unsafe { + let uid = c::getuid(); + Uid::from_raw(uid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn geteuid() -> Uid { + unsafe { + let uid = c::geteuid(); + Uid::from_raw(uid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getgid() -> Gid { + unsafe { + let gid = c::getgid(); + Gid::from_raw(gid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getegid() -> Gid { + unsafe { + let gid = c::getegid(); + Gid::from_raw(gid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getpid() -> Pid { + unsafe { + let pid = c::getpid(); + debug_assert_ne!(pid, 0); + Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getppid() -> Option { + unsafe { + let pid: i32 = c::getppid(); + Pid::from_raw(pid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn getpgid(pid: Option) -> io::Result { + unsafe { + let pgid = ret_pid_t(c::getpgid(Pid::as_raw(pid) as _))?; + debug_assert_ne!(pgid, 0); + Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid))) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getpgrp() -> Pid { + unsafe { + let pgid = c::getpgrp(); + debug_assert_ne!(pgid, 0); + Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid)) + } +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +#[inline] +pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { + unsafe { + ret(c::sched_getaffinity( + Pid::as_raw(pid) as _, + core::mem::size_of::(), + cpuset, + )) + } +} + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +#[inline] +pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { + unsafe { + ret(c::sched_setaffinity( + Pid::as_raw(pid) as _, + core::mem::size_of::(), + cpuset, + )) + } +} + +#[inline] +pub(crate) fn sched_yield() { + unsafe { + let _ = c::sched_yield(); + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn uname() -> RawUname { + let mut uname = MaybeUninit::::uninit(); + unsafe { + ret(c::uname(uname.as_mut_ptr())).unwrap(); + uname.assume_init() + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +#[inline] +pub(crate) fn nice(inc: i32) -> io::Result { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::nice(inc) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn getpriority_user(uid: Uid) -> io::Result { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::getpriority(c::PRIO_USER, uid.as_raw() as _) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn getpriority_pgrp(pgid: Option) -> io::Result { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::getpriority(c::PRIO_PGRP, Pid::as_raw(pgid) as _) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn getpriority_process(pid: Option) -> io::Result { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::getpriority(c::PRIO_PROCESS, Pid::as_raw(pid) as _) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { + unsafe { ret(c::setpriority(c::PRIO_USER, uid.as_raw() as _, priority)) } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { + unsafe { + ret(c::setpriority( + c::PRIO_PGRP, + Pid::as_raw(pgid) as _, + priority, + )) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { + unsafe { + ret(c::setpriority( + c::PRIO_PROCESS, + Pid::as_raw(pid) as _, + priority, + )) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn getrlimit(limit: Resource) -> Rlimit { + let mut result = MaybeUninit::::uninit(); + unsafe { + ret_infallible(libc_getrlimit(limit as _, result.as_mut_ptr())); + rlimit_from_libc(result.assume_init()) + } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { + let lim = rlimit_to_libc(new)?; + unsafe { ret(libc_setrlimit(limit as _, &lim)) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn prlimit(pid: Option, limit: Resource, new: Rlimit) -> io::Result { + let lim = rlimit_to_libc(new)?; + let mut result = MaybeUninit::::uninit(); + unsafe { + ret(libc_prlimit( + Pid::as_raw(pid), + limit as _, + &lim, + result.as_mut_ptr(), + ))?; + Ok(rlimit_from_libc(result.assume_init())) + } +} + +/// Convert a Rust [`Rlimit`] to a C `libc_rlimit`. +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +fn rlimit_from_libc(lim: libc_rlimit) -> Rlimit { + let current = if lim.rlim_cur == LIBC_RLIM_INFINITY { + None + } else { + Some(lim.rlim_cur.try_into().unwrap()) + }; + let maximum = if lim.rlim_max == LIBC_RLIM_INFINITY { + None + } else { + Some(lim.rlim_max.try_into().unwrap()) + }; + Rlimit { current, maximum } +} + +/// Convert a C `libc_rlimit` to a Rust `Rlimit`. +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +fn rlimit_to_libc(lim: Rlimit) -> io::Result { + let Rlimit { current, maximum } = lim; + let rlim_cur = match current { + Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, + None => LIBC_RLIM_INFINITY as _, + }; + let rlim_max = match maximum { + Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, + None => LIBC_RLIM_INFINITY as _, + }; + Ok(libc_rlimit { rlim_cur, rlim_max }) +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn wait(waitopts: WaitOptions) -> io::Result> { + _waitpid(!0, waitopts) +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn waitpid( + pid: Option, + waitopts: WaitOptions, +) -> io::Result> { + _waitpid(Pid::as_raw(pid), waitopts) +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn _waitpid( + pid: RawPid, + waitopts: WaitOptions, +) -> io::Result> { + unsafe { + let mut status: c::c_int = 0; + let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?; + Ok(RawNonZeroPid::new(pid).map(|non_zero| { + ( + Pid::from_raw_nonzero(non_zero), + WaitStatus::new(status as _), + ) + })) + } +} + +#[inline] +pub(crate) fn exit_group(code: c::c_int) -> ! { + // `_exit` and `_Exit` are the same; it's just a matter of which ones + // the libc bindings expose. + #[cfg(any(target_os = "wasi", target_os = "solid"))] + unsafe { + c::_Exit(code) + } + #[cfg(unix)] + unsafe { + c::_exit(code) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn setsid() -> io::Result { + unsafe { + let pid = ret_c_int(c::setsid())?; + debug_assert_ne!(pid, 0); + Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { + unsafe { ret(c::kill(pid.as_raw_nonzero().get(), sig as i32)) } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { + unsafe { + ret(c::kill( + pid.as_raw_nonzero().get().wrapping_neg(), + sig as i32, + )) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { + unsafe { ret(c::kill(0, sig as i32)) } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[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 { + ret_c_int(c::prctl(option, arg2, arg3, arg4, arg5)) +} + +#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] +#[inline] +pub(crate) unsafe fn procctl( + idtype: c::idtype_t, + id: c::id_t, + option: c::c_int, + data: *mut c::c_void, +) -> io::Result<()> { + ret(c::procctl(idtype, id, option, data)) +} diff --git a/vendor/rustix/src/backend/libc/process/types.rs b/vendor/rustix/src/backend/libc/process/types.rs new file mode 100644 index 000000000..f8e3b8bf4 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/types.rs @@ -0,0 +1,414 @@ +use super::super::c; + +/// A command for use with [`membarrier`] and [`membarrier_cpu`]. +/// +/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. +/// +/// [`membarrier`]: crate::process::membarrier +/// [`membarrier_cpu`]: crate::process::membarrier_cpu +/// [`membarrier_query`]: crate::process::membarrier_query +// TODO: These are not yet exposed through libc, so we define the +// constants ourselves. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[repr(u32)] +pub enum MembarrierCommand { + /// `MEMBARRIER_CMD_GLOBAL` + #[doc(alias = "Shared")] + #[doc(alias = "MEMBARRIER_CMD_SHARED")] + Global = 1, + /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` + GlobalExpedited = 2, + /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` + RegisterGlobalExpedited = 4, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` + PrivateExpedited = 8, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` + RegisterPrivateExpedited = 16, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` + PrivateExpeditedSyncCore = 32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` + RegisterPrivateExpeditedSyncCore = 64, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + PrivateExpeditedRseq = 128, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + RegisterPrivateExpeditedRseq = 256, +} + +/// A resource value for use with [`getrlimit`], [`setrlimit`], and +/// [`prlimit`]. +/// +/// [`getrlimit`]: crate::process::getrlimit +/// [`setrlimit`]: crate::process::setrlimit +/// [`prlimit`]: crate::process::prlimit +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum Resource { + /// `RLIMIT_CPU` + Cpu = c::RLIMIT_CPU as c::c_int, + /// `RLIMIT_FSIZE` + Fsize = c::RLIMIT_FSIZE as c::c_int, + /// `RLIMIT_DATA` + Data = c::RLIMIT_DATA as c::c_int, + /// `RLIMIT_STACK` + Stack = c::RLIMIT_STACK as c::c_int, + /// `RLIMIT_CORE` + #[cfg(not(target_os = "haiku"))] + Core = c::RLIMIT_CORE as c::c_int, + /// `RLIMIT_RSS` + #[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "solaris", + )))] + Rss = c::RLIMIT_RSS as c::c_int, + /// `RLIMIT_NPROC` + #[cfg(not(any(target_os = "haiku", target_os = "illumos", target_os = "solaris")))] + Nproc = c::RLIMIT_NPROC as c::c_int, + /// `RLIMIT_NOFILE` + Nofile = c::RLIMIT_NOFILE as c::c_int, + /// `RLIMIT_MEMLOCK` + #[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "illumos", + target_os = "solaris" + )))] + Memlock = c::RLIMIT_MEMLOCK as c::c_int, + /// `RLIMIT_AS` + #[cfg(not(target_os = "openbsd"))] + As = c::RLIMIT_AS as c::c_int, + /// `RLIMIT_LOCKS` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + Locks = c::RLIMIT_LOCKS as c::c_int, + /// `RLIMIT_SIGPENDING` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + Sigpending = c::RLIMIT_SIGPENDING as c::c_int, + /// `RLIMIT_MSGQUEUE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + Msgqueue = c::RLIMIT_MSGQUEUE as c::c_int, + /// `RLIMIT_NICE` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + Nice = c::RLIMIT_NICE as c::c_int, + /// `RLIMIT_RTPRIO` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + Rtprio = c::RLIMIT_RTPRIO as c::c_int, + /// `RLIMIT_RTTIME` + #[cfg(not(any( + target_os = "aix", + target_os = "android", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + )))] + Rttime = c::RLIMIT_RTTIME as c::c_int, +} + +#[cfg(any(target_os = "ios", target_os = "macos"))] +impl Resource { + /// `RLIMIT_RSS` + #[allow(non_upper_case_globals)] + pub const Rss: Self = Self::As; +} + +/// 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 +#[cfg(not(target_os = "wasi"))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum Signal { + /// `SIGHUP` + Hup = c::SIGHUP, + /// `SIGINT` + Int = c::SIGINT, + /// `SIGQUIT` + Quit = c::SIGQUIT, + /// `SIGILL` + Ill = c::SIGILL, + /// `SIGTRAP` + Trap = c::SIGTRAP, + /// `SIGABRT`, aka `SIGIOT` + #[doc(alias = "Iot")] + #[doc(alias = "Abrt")] + Abort = c::SIGABRT, + /// `SIGBUS` + Bus = c::SIGBUS, + /// `SIGFPE` + Fpe = c::SIGFPE, + /// `SIGKILL` + Kill = c::SIGKILL, + /// `SIGUSR1` + Usr1 = c::SIGUSR1, + /// `SIGSEGV` + Segv = c::SIGSEGV, + /// `SIGUSR2` + Usr2 = c::SIGUSR2, + /// `SIGPIPE` + Pipe = c::SIGPIPE, + /// `SIGALRM` + #[doc(alias = "Alrm")] + Alarm = c::SIGALRM, + /// `SIGTERM` + Term = c::SIGTERM, + /// `SIGSTKFLT` + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + all( + any(target_os = "android", target_os = "linux"), + any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc", + target_arch = "sparc64" + ), + ) + )))] + Stkflt = c::SIGSTKFLT, + /// `SIGCHLD` + #[doc(alias = "Chld")] + Child = c::SIGCHLD, + /// `SIGCONT` + Cont = c::SIGCONT, + /// `SIGSTOP` + Stop = c::SIGSTOP, + /// `SIGTSTP` + Tstp = c::SIGTSTP, + /// `SIGTTIN` + Ttin = c::SIGTTIN, + /// `SIGTTOU` + Ttou = c::SIGTTOU, + /// `SIGURG` + Urg = c::SIGURG, + /// `SIGXCPU` + Xcpu = c::SIGXCPU, + /// `SIGXFSZ` + Xfsz = c::SIGXFSZ, + /// `SIGVTALRM` + #[doc(alias = "Vtalrm")] + Vtalarm = c::SIGVTALRM, + /// `SIGPROF` + Prof = c::SIGPROF, + /// `SIGWINCH` + Winch = c::SIGWINCH, + /// `SIGIO`, aka `SIGPOLL` + #[doc(alias = "Poll")] + #[cfg(not(target_os = "haiku"))] + Io = c::SIGIO, + /// `SIGPWR` + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + #[doc(alias = "Pwr")] + Power = c::SIGPWR, + /// `SIGSYS`, aka `SIGUNUSED` + #[doc(alias = "Unused")] + Sys = c::SIGSYS, +} + +#[cfg(not(target_os = "wasi"))] +impl Signal { + /// Convert a raw signal number into a `Signal`, if possible. + pub fn from_raw(sig: i32) -> Option { + match sig as _ { + c::SIGHUP => Some(Self::Hup), + c::SIGINT => Some(Self::Int), + c::SIGQUIT => Some(Self::Quit), + c::SIGILL => Some(Self::Ill), + c::SIGTRAP => Some(Self::Trap), + c::SIGABRT => Some(Self::Abort), + c::SIGBUS => Some(Self::Bus), + c::SIGFPE => Some(Self::Fpe), + c::SIGKILL => Some(Self::Kill), + c::SIGUSR1 => Some(Self::Usr1), + c::SIGSEGV => Some(Self::Segv), + c::SIGUSR2 => Some(Self::Usr2), + c::SIGPIPE => Some(Self::Pipe), + c::SIGALRM => Some(Self::Alarm), + c::SIGTERM => Some(Self::Term), + #[cfg(not(any( + target_os = "aix", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + all( + any(target_os = "android", target_os = "linux"), + any( + target_arch = "mips", + target_arch = "mips64", + target_arch = "sparc", + target_arch = "sparc64" + ), + ) + )))] + c::SIGSTKFLT => Some(Self::Stkflt), + c::SIGCHLD => Some(Self::Child), + c::SIGCONT => Some(Self::Cont), + c::SIGSTOP => Some(Self::Stop), + c::SIGTSTP => Some(Self::Tstp), + c::SIGTTIN => Some(Self::Ttin), + c::SIGTTOU => Some(Self::Ttou), + c::SIGURG => Some(Self::Urg), + c::SIGXCPU => Some(Self::Xcpu), + c::SIGXFSZ => Some(Self::Xfsz), + c::SIGVTALRM => Some(Self::Vtalarm), + c::SIGPROF => Some(Self::Prof), + c::SIGWINCH => Some(Self::Winch), + #[cfg(not(target_os = "haiku"))] + c::SIGIO => Some(Self::Io), + #[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + )))] + c::SIGPWR => Some(Self::Power), + c::SIGSYS => Some(Self::Sys), + _ => None, + } + } +} + +pub const EXIT_SUCCESS: c::c_int = c::EXIT_SUCCESS; +pub const EXIT_FAILURE: c::c_int = c::EXIT_FAILURE; +#[cfg(not(target_os = "wasi"))] +pub const EXIT_SIGNALED_SIGABRT: c::c_int = 128 + c::SIGABRT; + +/// A process identifier as a raw integer. +#[cfg(not(target_os = "wasi"))] +pub type RawPid = c::pid_t; +/// A non-zero process identifier as a raw non-zero integer. +#[cfg(not(target_os = "wasi"))] +pub type RawNonZeroPid = core::num::NonZeroI32; +/// A group identifier as a raw integer. +#[cfg(not(target_os = "wasi"))] +pub type RawGid = c::gid_t; +/// A user identifier as a raw integer. +#[cfg(not(target_os = "wasi"))] +pub type RawUid = c::uid_t; +/// A CPU identifier as a raw integer. +#[cfg(any(target_os = "android", target_os = "linux"))] +pub type RawCpuid = u32; +#[cfg(target_os = "freebsd")] +pub type RawId = c::id_t; + +#[cfg(not(target_os = "wasi"))] +pub(crate) type RawUname = c::utsname; + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +pub(crate) type RawCpuSet = c::cpu_set_t; + +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +#[inline] +pub(crate) fn raw_cpu_set_new() -> RawCpuSet { + let mut set = unsafe { core::mem::zeroed() }; + super::cpu_set::CPU_ZERO(&mut set); + set +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; +#[cfg(target_os = "dragonfly")] +pub(crate) const CPU_SETSIZE: usize = 256; diff --git a/vendor/rustix/src/backend/libc/process/wait.rs b/vendor/rustix/src/backend/libc/process/wait.rs new file mode 100644 index 000000000..6de79955d --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/wait.rs @@ -0,0 +1,6 @@ +use super::super::c; + +pub(crate) use c::{ + WCONTINUED, WEXITSTATUS, WIFCONTINUED, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, + WTERMSIG, WUNTRACED, +}; diff --git a/vendor/rustix/src/backend/libc/rand/mod.rs b/vendor/rustix/src/backend/libc/rand/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/libc/rand/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/rand/syscalls.rs b/vendor/rustix/src/backend/libc/rand/syscalls.rs new file mode 100644 index 000000000..1c4286235 --- /dev/null +++ b/vendor/rustix/src/backend/libc/rand/syscalls.rs @@ -0,0 +1,16 @@ +//! libc syscalls supporting `rustix::rand`. + +#[cfg(target_os = "linux")] +use {super::super::c, super::super::conv::ret_ssize_t, crate::io, crate::rand::GetRandomFlags}; + +#[cfg(target_os = "linux")] +pub(crate) fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result { + // `getrandom` wasn't supported in glibc until 2.25. + weak_or_syscall! { + fn getrandom(buf: *mut c::c_void, buflen: c::size_t, flags: c::c_uint) via SYS_getrandom -> c::ssize_t + } + + let nread = + unsafe { ret_ssize_t(getrandom(buf.as_mut_ptr().cast(), buf.len(), flags.bits()))? }; + Ok(nread as usize) +} diff --git a/vendor/rustix/src/backend/libc/rand/types.rs b/vendor/rustix/src/backend/libc/rand/types.rs new file mode 100644 index 000000000..2ba3f1119 --- /dev/null +++ b/vendor/rustix/src/backend/libc/rand/types.rs @@ -0,0 +1,19 @@ +#[cfg(target_os = "linux")] +use super::super::c; +#[cfg(target_os = "linux")] +use bitflags::bitflags; + +#[cfg(target_os = "linux")] +bitflags! { + /// `GRND_*` flags for use with [`getrandom`]. + /// + /// [`getrandom`]: crate::rand::getrandom + pub struct GetRandomFlags: u32 { + /// `GRND_RANDOM` + const RANDOM = c::GRND_RANDOM; + /// `GRND_NONBLOCK` + const NONBLOCK = c::GRND_NONBLOCK; + /// `GRND_INSECURE` + const INSECURE = c::GRND_INSECURE; + } +} diff --git a/vendor/rustix/src/backend/libc/termios/mod.rs b/vendor/rustix/src/backend/libc/termios/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/libc/termios/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/termios/syscalls.rs b/vendor/rustix/src/backend/libc/termios/syscalls.rs new file mode 100644 index 000000000..e0ab7a016 --- /dev/null +++ b/vendor/rustix/src/backend/libc/termios/syscalls.rs @@ -0,0 +1,158 @@ +//! libc syscalls supporting `rustix::termios`. +//! +//! # Safety +//! +//! See the `rustix::backend::syscalls` module documentation for details. + +use super::super::c; +use super::super::conv::{borrowed_fd, ret, ret_pid_t}; +use crate::fd::BorrowedFd; +#[cfg(feature = "procfs")] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +use crate::ffi::CStr; +use crate::io; +use crate::process::{Pid, RawNonZeroPid}; +use crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize}; +use core::mem::MaybeUninit; +use libc_errno::errno; + +pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result { + let mut result = MaybeUninit::::uninit(); + unsafe { + ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr()))?; + Ok(result.assume_init()) + } +} + +pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; + debug_assert_ne!(pid, 0); + Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + } +} + +pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { + unsafe { ret(c::tcsetpgrp(borrowed_fd(fd), pid.as_raw_nonzero().get())) } +} + +pub(crate) fn tcsetattr( + fd: BorrowedFd, + optional_actions: OptionalActions, + termios: &Termios, +) -> io::Result<()> { + unsafe { + ret(c::tcsetattr( + borrowed_fd(fd), + optional_actions as _, + termios, + )) + } +} + +pub(crate) fn tcsendbreak(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(c::tcsendbreak(borrowed_fd(fd), 0)) } +} + +pub(crate) fn tcdrain(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(c::tcdrain(borrowed_fd(fd))) } +} + +pub(crate) fn tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()> { + unsafe { ret(c::tcflush(borrowed_fd(fd), queue_selector as _)) } +} + +pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { + unsafe { ret(c::tcflow(borrowed_fd(fd), action as _)) } +} + +pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result { + unsafe { + let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?; + debug_assert_ne!(pid, 0); + Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) + } +} + +pub(crate) fn tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()> { + unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCSWINSZ, &winsize)) } +} + +pub(crate) fn tcgetwinsize(fd: BorrowedFd) -> io::Result { + unsafe { + let mut buf = MaybeUninit::::uninit(); + ret(c::ioctl( + borrowed_fd(fd), + c::TIOCGWINSZ.into(), + buf.as_mut_ptr(), + ))?; + Ok(buf.assume_init()) + } +} + +#[inline] +#[must_use] +pub(crate) fn cfgetospeed(termios: &Termios) -> Speed { + unsafe { c::cfgetospeed(termios) } +} + +#[inline] +#[must_use] +pub(crate) fn cfgetispeed(termios: &Termios) -> Speed { + unsafe { c::cfgetispeed(termios) } +} + +#[inline] +pub(crate) fn cfmakeraw(termios: &mut Termios) { + unsafe { c::cfmakeraw(termios) } +} + +#[inline] +pub(crate) fn cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { + unsafe { ret(c::cfsetospeed(termios, speed)) } +} + +#[inline] +pub(crate) fn cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { + unsafe { ret(c::cfsetispeed(termios, speed)) } +} + +#[inline] +pub(crate) fn cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { + unsafe { ret(c::cfsetspeed(termios, speed)) } +} + +pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { + let res = unsafe { c::isatty(borrowed_fd(fd)) }; + if res == 0 { + match errno().0 { + #[cfg(not(any(target_os = "android", target_os = "linux")))] + c::ENOTTY => false, + + // Old Linux versions reportedly return `EINVAL`. + // + #[cfg(any(target_os = "android", target_os = "linux"))] + c::ENOTTY | c::EINVAL => false, + + // Darwin mysteriously returns `EOPNOTSUPP` sometimes. + #[cfg(any(target_os = "ios", target_os = "macos"))] + c::EOPNOTSUPP => false, + + err => panic!("unexpected error from isatty: {:?}", err), + } + } else { + true + } +} + +#[cfg(feature = "procfs")] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { + unsafe { + // `ttyname_r` returns its error status rather than using `errno`. + match c::ttyname_r(borrowed_fd(dirfd), buf.as_mut_ptr().cast(), buf.len()) { + 0 => Ok(CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len()), + err => Err(io::Errno::from_raw_os_error(err)), + } + } +} diff --git a/vendor/rustix/src/backend/libc/termios/types.rs b/vendor/rustix/src/backend/libc/termios/types.rs new file mode 100644 index 000000000..6dda70064 --- /dev/null +++ b/vendor/rustix/src/backend/libc/termios/types.rs @@ -0,0 +1,1046 @@ +use super::super::c; + +/// `TCSA*` values for use with [`tcsetattr`]. +/// +/// [`tcsetattr`]: crate::termios::tcsetattr +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[repr(i32)] +pub enum OptionalActions { + /// `TCSANOW`—Make the change immediately. + Now = c::TCSANOW, + + /// `TCSADRAIN`—Make the change after all output has been transmitted. + Drain = c::TCSADRAIN, + + /// `TCSAFLUSH`—Discard any pending input and then make the change + /// after all output has been transmitted. + Flush = c::TCSAFLUSH, +} + +/// `TC*` values for use with [`tcflush`]. +/// +/// [`tcflush`]: crate::termios::tcflush +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[repr(i32)] +pub enum QueueSelector { + /// `TCIFLUSH`—Flush data received but not read. + IFlush = c::TCIFLUSH, + + /// `TCOFLUSH`—Flush data written but not transmitted. + OFlush = c::TCOFLUSH, + + /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. + IOFlush = c::TCIOFLUSH, +} + +/// `TC*` values for use with [`tcflow`]. +/// +/// [`tcflow`]: crate::termios::tcflow +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[repr(i32)] +pub enum Action { + /// `TCOOFF`—Suspend output. + OOff = c::TCOOFF, + + /// `TCOON`—Restart suspended output. + OOn = c::TCOON, + + /// `TCIOFF`—Transmits a STOP byte. + IOff = c::TCIOFF, + + /// `TCION`—Transmits a START byte. + IOn = c::TCION, +} + +/// `struct termios` for use with [`tcgetattr`]. +/// +/// [`tcgetattr`]: crate::termios::tcgetattr +pub type Termios = c::termios; + +/// `struct winsize` for use with [`tcgetwinsize`]. +/// +/// [`tcgetwinsize`]: crate::termios::tcgetwinsize +pub type Winsize = c::winsize; + +/// `tcflag_t`—A type for the flags fields of [`Termios`]. +pub type Tcflag = c::tcflag_t; + +/// `speed_t`—A return type for [`cfsetspeed`] and similar. +/// +/// [`cfsetspeed`]: crate::termios::cfsetspeed +pub type Speed = c::speed_t; + +/// `VINTR` +pub const VINTR: usize = c::VINTR as usize; + +/// `VQUIT` +pub const VQUIT: usize = c::VQUIT as usize; + +/// `VERASE` +pub const VERASE: usize = c::VERASE as usize; + +/// `VKILL` +pub const VKILL: usize = c::VKILL as usize; + +/// `VEOF` +pub const VEOF: usize = c::VEOF as usize; + +/// `VTIME` +pub const VTIME: usize = c::VTIME as usize; + +/// `VMIN` +pub const VMIN: usize = c::VMIN as usize; + +/// `VSWTC` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const VSWTC: usize = c::VSWTC as usize; + +/// `VSTART` +pub const VSTART: usize = c::VSTART as usize; + +/// `VSTOP` +pub const VSTOP: usize = c::VSTOP as usize; + +/// `VSUSP` +pub const VSUSP: usize = c::VSUSP as usize; + +/// `VEOL` +pub const VEOL: usize = c::VEOL as usize; + +/// `VREPRINT` +#[cfg(not(target_os = "haiku"))] +pub const VREPRINT: usize = c::VREPRINT as usize; + +/// `VDISCARD` +#[cfg(not(target_os = "haiku"))] +pub const VDISCARD: usize = c::VDISCARD as usize; + +/// `VWERASE` +#[cfg(not(target_os = "haiku"))] +pub const VWERASE: usize = c::VWERASE as usize; + +/// `VLNEXT` +#[cfg(not(target_os = "haiku"))] +pub const VLNEXT: usize = c::VLNEXT as usize; + +/// `VEOL2` +pub const VEOL2: usize = c::VEOL2 as usize; + +/// `IGNBRK` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const IGNBRK: c::c_uint = c::IGNBRK; + +/// `BRKINT` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const BRKINT: c::c_uint = c::BRKINT; + +/// `IGNPAR` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const IGNPAR: c::c_uint = c::IGNPAR; + +/// `PARMRK` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const PARMRK: c::c_uint = c::PARMRK; + +/// `INPCK` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const INPCK: c::c_uint = c::INPCK; + +/// `ISTRIP` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ISTRIP: c::c_uint = c::ISTRIP; + +/// `INLCR` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const INLCR: c::c_uint = c::INLCR; + +/// `IGNCR` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const IGNCR: c::c_uint = c::IGNCR; + +/// `ICRNL` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ICRNL: c::c_uint = c::ICRNL; + +/// `IUCLC` +#[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))] +pub const IUCLC: c::c_uint = c::IUCLC; + +/// `IXON` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const IXON: c::c_uint = c::IXON; + +/// `IXANY` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const IXANY: c::c_uint = c::IXANY; + +/// `IXOFF` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const IXOFF: c::c_uint = c::IXOFF; + +/// `IMAXBEL` +#[cfg(not(any( + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox" +)))] +pub const IMAXBEL: c::c_uint = c::IMAXBEL; + +/// `IUTF8` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const IUTF8: c::c_uint = c::IUTF8; + +/// `OPOST` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const OPOST: c::c_uint = c::OPOST; + +/// `OLCUC` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "redox", +)))] +pub const OLCUC: c::c_uint = c::OLCUC; + +/// `ONLCR` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ONLCR: c::c_uint = c::ONLCR; + +/// `OCRNL` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const OCRNL: c::c_uint = c::OCRNL; + +/// `ONOCR` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ONOCR: c::c_uint = c::ONOCR; + +/// `ONLRET` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ONLRET: c::c_uint = c::ONLRET; + +/// `OFILL` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +)))] +pub const OFILL: c::c_uint = c::OFILL; + +/// `OFDEL` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", +)))] +pub const OFDEL: c::c_uint = c::OFDEL; + +/// `NLDLY` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const NLDLY: c::c_uint = c::NLDLY; + +/// `NL0` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const NL0: c::c_uint = c::NL0; + +/// `NL1` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const NL1: c::c_uint = c::NL1; + +/// `CRDLY` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CRDLY: c::c_uint = c::CRDLY; + +/// `CR0` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CR0: c::c_uint = c::CR0; + +/// `CR1` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CR1: c::c_uint = c::CR1; + +/// `CR2` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CR2: c::c_uint = c::CR2; + +/// `CR3` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CR3: c::c_uint = c::CR3; + +/// `TABDLY` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", +)))] +pub const TABDLY: c::c_uint = c::TABDLY; + +/// `TAB0` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const TAB0: c::c_uint = c::TAB0; + +/// `TAB1` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const TAB1: c::c_uint = c::TAB1; + +/// `TAB2` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const TAB2: c::c_uint = c::TAB2; + +/// `TAB3` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const TAB3: c::c_uint = c::TAB3; + +/// `BSDLY` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const BSDLY: c::c_uint = c::BSDLY; + +/// `BS0` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const BS0: c::c_uint = c::BS0; + +/// `BS1` +#[cfg(not(any( + target_env = "musl", + target_os = "emscripten", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const BS1: c::c_uint = c::BS1; + +/// `FFDLY` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const FFDLY: c::c_uint = c::FFDLY; + +/// `FF0` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const FF0: c::c_uint = c::FF0; + +/// `FF1` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const FF1: c::c_uint = c::FF1; + +/// `VTDLY` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const VTDLY: c::c_uint = c::VTDLY; + +/// `VT0` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const VT0: c::c_uint = c::VT0; + +/// `VT1` +#[cfg(not(any( + target_env = "musl", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "fuchsia", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const VT1: c::c_uint = c::VT1; + +/// `B0` +pub const B0: Speed = c::B0; + +/// `B50` +pub const B50: Speed = c::B50; + +/// `B75` +pub const B75: Speed = c::B75; + +/// `B110` +pub const B110: Speed = c::B110; + +/// `B134` +pub const B134: Speed = c::B134; + +/// `B150` +pub const B150: Speed = c::B150; + +/// `B200` +pub const B200: Speed = c::B200; + +/// `B300` +pub const B300: Speed = c::B300; + +/// `B600` +pub const B600: Speed = c::B600; + +/// `B1200` +pub const B1200: Speed = c::B1200; + +/// `B1800` +pub const B1800: Speed = c::B1800; + +/// `B2400` +pub const B2400: Speed = c::B2400; + +/// `B4800` +pub const B4800: Speed = c::B4800; + +/// `B9600` +pub const B9600: Speed = c::B9600; + +/// `B19200` +pub const B19200: Speed = c::B19200; + +/// `B38400` +pub const B38400: Speed = c::B38400; + +/// `B57600` +pub const B57600: Speed = c::B57600; + +/// `B115200` +pub const B115200: Speed = c::B115200; + +/// `B230400` +pub const B230400: Speed = c::B230400; + +/// `B460800` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" +)))] +pub const B460800: Speed = c::B460800; + +/// `B500000` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B500000: Speed = c::B500000; + +/// `B576000` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B576000: Speed = c::B576000; + +/// `B921600` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" +)))] +pub const B921600: Speed = c::B921600; + +/// `B1000000` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B1000000: Speed = c::B1000000; + +/// `B1152000` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B1152000: Speed = c::B1152000; + +/// `B1500000` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B1500000: Speed = c::B1500000; + +/// `B2000000` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B2000000: Speed = c::B2000000; + +/// `B2500000` +#[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B2500000: Speed = c::B2500000; + +/// `B3000000` +#[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B3000000: Speed = c::B3000000; + +/// `B3500000` +#[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B3500000: Speed = c::B3500000; + +/// `B4000000` +#[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", +)))] +pub const B4000000: Speed = c::B4000000; + +/// `CSIZE` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CSIZE: c::c_uint = c::CSIZE; + +/// `CS5` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CS5: c::c_uint = c::CS5; + +/// `CS6` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CS6: c::c_uint = c::CS6; + +/// `CS7` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CS7: c::c_uint = c::CS7; + +/// `CS8` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CS8: c::c_uint = c::CS8; + +/// `CSTOPB` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CSTOPB: c::c_uint = c::CSTOPB; + +/// `CREAD` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CREAD: c::c_uint = c::CREAD; + +/// `PARENB` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const PARENB: c::c_uint = c::PARENB; + +/// `PARODD` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const PARODD: c::c_uint = c::PARODD; + +/// `HUPCL` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const HUPCL: c::c_uint = c::HUPCL; + +/// `CLOCAL` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const CLOCAL: c::c_uint = c::CLOCAL; + +/// `ISIG` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ISIG: c::c_uint = c::ISIG; + +/// `ICANON`—A flag for the `c_lflag` field of [`Termios`] indicating +/// canonical mode. +pub const ICANON: Tcflag = c::ICANON; + +/// `ECHO` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ECHO: c::c_uint = c::ECHO; + +/// `ECHOE` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ECHOE: c::c_uint = c::ECHOE; + +/// `ECHOK` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ECHOK: c::c_uint = c::ECHOK; + +/// `ECHONL` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const ECHONL: c::c_uint = c::ECHONL; + +/// `NOFLSH` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const NOFLSH: c::c_uint = c::NOFLSH; + +/// `TOSTOP` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const TOSTOP: c::c_uint = c::TOSTOP; + +/// `IEXTEN` +#[cfg(not(any(target_os = "ios", target_os = "macos")))] +pub const IEXTEN: c::c_uint = c::IEXTEN; + +/// `EXTA` +#[cfg(not(any( + target_os = "emscripten", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "solaris", +)))] +pub const EXTA: c::c_uint = c::EXTA; + +/// `EXTB` +#[cfg(not(any( + target_os = "emscripten", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "redox", + target_os = "solaris", +)))] +pub const EXTB: c::c_uint = c::EXTB; + +/// `CBAUD` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", +)))] +pub const CBAUD: c::c_uint = c::CBAUD; + +/// `CBAUDEX` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CBAUDEX: c::c_uint = c::CBAUDEX; + +/// `CIBAUD` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_arch = "powerpc", + target_arch = "powerpc64", +)))] +pub const CIBAUD: c::tcflag_t = c::CIBAUD; + +/// `CIBAUD` +// TODO: Upstream this. +#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] +pub const CIBAUD: c::tcflag_t = 0o77600000; + +/// `CMSPAR` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const CMSPAR: c::c_uint = c::CMSPAR; + +/// `CRTSCTS` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const CRTSCTS: c::c_uint = c::CRTSCTS; + +/// `XCASE` +#[cfg(any(target_arch = "s390x", target_os = "haiku"))] +pub const XCASE: c::c_uint = c::XCASE; + +/// `ECHOCTL` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const ECHOCTL: c::c_uint = c::ECHOCTL; + +/// `ECHOPRT` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const ECHOPRT: c::c_uint = c::ECHOPRT; + +/// `ECHOKE` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const ECHOKE: c::c_uint = c::ECHOKE; + +/// `FLUSHO` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const FLUSHO: c::c_uint = c::FLUSHO; + +/// `PENDIN` +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub const PENDIN: c::c_uint = c::PENDIN; + +/// `EXTPROC` +#[cfg(not(any( + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox" +)))] +pub const EXTPROC: c::c_uint = c::EXTPROC; + +/// `XTABS` +#[cfg(not(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "haiku", + target_os = "illumos", + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", +)))] +pub const XTABS: c::c_uint = c::XTABS; diff --git a/vendor/rustix/src/backend/libc/thread/mod.rs b/vendor/rustix/src/backend/libc/thread/mod.rs new file mode 100644 index 000000000..40e0d1135 --- /dev/null +++ b/vendor/rustix/src/backend/libc/thread/mod.rs @@ -0,0 +1,2 @@ +#[cfg(not(windows))] +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/thread/syscalls.rs b/vendor/rustix/src/backend/libc/thread/syscalls.rs new file mode 100644 index 000000000..0709fbb19 --- /dev/null +++ b/vendor/rustix/src/backend/libc/thread/syscalls.rs @@ -0,0 +1,295 @@ +//! libc syscalls supporting `rustix::thread`. + +use super::super::c; +use super::super::conv::ret; +#[cfg(any(target_os = "android", target_os = "linux"))] +use super::super::conv::{borrowed_fd, ret_c_int}; +use super::super::time::types::LibcTimespec; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::fd::BorrowedFd; +use crate::io; +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::process::{Pid, RawNonZeroPid}; +#[cfg(not(target_os = "redox"))] +use crate::thread::{NanosleepRelativeResult, Timespec}; +use core::mem::MaybeUninit; +#[cfg(not(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd", + target_os = "redox", + target_os = "wasi", +)))] +use {crate::thread::ClockId, core::ptr::null_mut}; + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +weak!(fn __clock_nanosleep_time64(c::clockid_t, c::c_int, *const LibcTimespec, *mut LibcTimespec) -> c::c_int); +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +weak!(fn __nanosleep64(*const LibcTimespec, *mut LibcTimespec) -> c::c_int); + +#[cfg(not(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd", + target_os = "redox", + target_os = "wasi", +)))] +#[inline] +pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { + let mut remain = MaybeUninit::::uninit(); + let flags = 0; + + // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe by + // default. + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { + match libc_clock_nanosleep( + id as c::clockid_t, + flags, + &request.clone().into(), + remain.as_mut_ptr(), + ) { + 0 => NanosleepRelativeResult::Ok, + err if err == io::Errno::INTR.0 => { + NanosleepRelativeResult::Interrupted(remain.assume_init().into()) + } + err => NanosleepRelativeResult::Err(io::Errno(err)), + } + } else { + clock_nanosleep_relative_old(id, request) + } + } + + // Main version: libc is y2038 safe and has `clock_nanosleep`. + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + unsafe { + match c::clock_nanosleep(id as c::clockid_t, flags, request, remain.as_mut_ptr()) { + 0 => NanosleepRelativeResult::Ok, + err if err == io::Errno::INTR.0 => { + NanosleepRelativeResult::Interrupted(remain.assume_init()) + } + err => NanosleepRelativeResult::Err(io::Errno(err)), + } + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +unsafe fn clock_nanosleep_relative_old(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { + use core::convert::TryInto; + let tv_sec = match request.tv_sec.try_into() { + Ok(tv_sec) => tv_sec, + Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), + }; + let tv_nsec = match request.tv_nsec.try_into() { + Ok(tv_nsec) => tv_nsec, + Err(_) => return NanosleepRelativeResult::Err(io::Errno::INVAL), + }; + let old_request = c::timespec { tv_sec, tv_nsec }; + let mut old_remain = MaybeUninit::::uninit(); + let flags = 0; + + match c::clock_nanosleep( + id as c::clockid_t, + flags, + &old_request, + old_remain.as_mut_ptr(), + ) { + 0 => NanosleepRelativeResult::Ok, + err if err == io::Errno::INTR.0 => { + let old_remain = old_remain.assume_init(); + let remain = Timespec { + tv_sec: old_remain.tv_sec.into(), + tv_nsec: old_remain.tv_nsec.into(), + }; + NanosleepRelativeResult::Interrupted(remain) + } + err => NanosleepRelativeResult::Err(io::Errno(err)), + } +} + +#[cfg(not(any( + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd", + target_os = "redox", + target_os = "wasi", +)))] +#[inline] +pub(crate) fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { + let flags = c::TIMER_ABSTIME; + + // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe by + // default. + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + { + if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { + match unsafe { + libc_clock_nanosleep( + id as c::clockid_t, + flags, + &request.clone().into(), + null_mut(), + ) + } { + 0 => Ok(()), + err => Err(io::Errno(err)), + } + } else { + clock_nanosleep_absolute_old(id, request) + } + } + + // Main version: libc is y2038 safe and has `clock_nanosleep`. + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + match unsafe { c::clock_nanosleep(id as c::clockid_t, flags, request, null_mut()) } { + 0 => Ok(()), + err => Err(io::Errno(err)), + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +fn clock_nanosleep_absolute_old(id: ClockId, request: &Timespec) -> io::Result<()> { + use core::convert::TryInto; + + let flags = c::TIMER_ABSTIME; + + let old_request = c::timespec { + tv_sec: request.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: request.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }; + match unsafe { c::clock_nanosleep(id as c::clockid_t, flags, &old_request, null_mut()) } { + 0 => Ok(()), + err => Err(io::Errno(err)), + } +} + +#[cfg(not(target_os = "redox"))] +#[inline] +pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { + let mut remain = MaybeUninit::::uninit(); + + // 32-bit gnu version: libc has `nanosleep` but it is not y2038 safe by + // default. + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_nanosleep) = __nanosleep64.get() { + match ret(libc_nanosleep(&request.clone().into(), remain.as_mut_ptr())) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => { + NanosleepRelativeResult::Interrupted(remain.assume_init().into()) + } + Err(err) => NanosleepRelativeResult::Err(err), + } + } else { + nanosleep_old(request) + } + } + + // Main version: libc is y2038 safe and has `nanosleep`. + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + unsafe { + match ret(c::nanosleep(request, remain.as_mut_ptr())) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(remain.assume_init()), + Err(err) => NanosleepRelativeResult::Err(err), + } + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +unsafe fn nanosleep_old(request: &Timespec) -> NanosleepRelativeResult { + use core::convert::TryInto; + let tv_sec = match request.tv_sec.try_into() { + Ok(tv_sec) => tv_sec, + Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), + }; + let tv_nsec = match request.tv_nsec.try_into() { + Ok(tv_nsec) => tv_nsec, + Err(_) => return NanosleepRelativeResult::Err(io::Errno::INVAL), + }; + let old_request = c::timespec { tv_sec, tv_nsec }; + let mut old_remain = MaybeUninit::::uninit(); + + match ret(c::nanosleep(&old_request, old_remain.as_mut_ptr())) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => { + let old_remain = old_remain.assume_init(); + let remain = Timespec { + tv_sec: old_remain.tv_sec.into(), + tv_nsec: old_remain.tv_nsec.into(), + }; + NanosleepRelativeResult::Interrupted(remain) + } + Err(err) => NanosleepRelativeResult::Err(err), + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +#[must_use] +pub(crate) fn gettid() -> Pid { + // `gettid` wasn't supported in glibc until 2.30, and musl until 1.2.2, + // so use `syscall`. + // + weak_or_syscall! { + fn gettid() via SYS_gettid -> c::pid_t + } + + unsafe { + let tid = gettid(); + debug_assert_ne!(tid, 0); + Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid)) + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result { + unsafe { ret_c_int(c::setns(borrowed_fd(fd), nstype)) } +} diff --git a/vendor/rustix/src/backend/libc/time/mod.rs b/vendor/rustix/src/backend/libc/time/mod.rs new file mode 100644 index 000000000..bff7fd564 --- /dev/null +++ b/vendor/rustix/src/backend/libc/time/mod.rs @@ -0,0 +1,3 @@ +#[cfg(not(windows))] +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/libc/time/syscalls.rs b/vendor/rustix/src/backend/libc/time/syscalls.rs new file mode 100644 index 000000000..c9e075e53 --- /dev/null +++ b/vendor/rustix/src/backend/libc/time/syscalls.rs @@ -0,0 +1,414 @@ +//! libc syscalls supporting `rustix::time`. + +use super::super::c; +use super::super::conv::ret; +#[cfg(feature = "time")] +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +use super::super::time::types::LibcItimerspec; +use super::super::time::types::LibcTimespec; +use super::types::Timespec; +#[cfg(not(target_os = "wasi"))] +use super::types::{ClockId, DynamicClockId}; +use crate::io; +use core::mem::MaybeUninit; +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(feature = "time")] +use { + super::super::conv::{borrowed_fd, ret_owned_fd}, + crate::fd::{BorrowedFd, OwnedFd}, + crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, +}; + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +weak!(fn __clock_gettime64(c::clockid_t, *mut LibcTimespec) -> c::c_int); +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +weak!(fn __clock_getres64(c::clockid_t, *mut LibcTimespec) -> c::c_int); +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[cfg(feature = "time")] +weak!(fn __timerfd_gettime64(c::c_int, *mut LibcItimerspec) -> c::c_int); +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[cfg(feature = "time")] +weak!(fn __timerfd_settime64(c::c_int, c::c_int, *const LibcItimerspec, *mut LibcItimerspec) -> c::c_int); + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +#[inline] +#[must_use] +pub(crate) fn clock_getres(id: ClockId) -> Timespec { + let mut timespec = MaybeUninit::::uninit(); + + // 32-bit gnu version: libc has `clock_getres` but it is not y2038 safe by + // default. + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_clock_getres) = __clock_getres64.get() { + ret(libc_clock_getres(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); + timespec.assume_init().into() + } else { + clock_getres_old(id) + } + } + + // Main version: libc is y2038 safe and has `clock_getres`. + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + unsafe { + let _ = c::clock_getres(id as c::clockid_t, timespec.as_mut_ptr()); + timespec.assume_init() + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[must_use] +unsafe fn clock_getres_old(id: ClockId) -> Timespec { + let mut old_timespec = MaybeUninit::::uninit(); + ret(c::clock_getres( + id as c::clockid_t, + old_timespec.as_mut_ptr(), + )) + .unwrap(); + let old_timespec = old_timespec.assume_init(); + Timespec { + tv_sec: old_timespec.tv_sec.into(), + tv_nsec: old_timespec.tv_nsec.into(), + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn clock_gettime(id: ClockId) -> Timespec { + let mut timespec = MaybeUninit::::uninit(); + + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_clock_gettime) = __clock_gettime64.get() { + ret(libc_clock_gettime( + id as c::clockid_t, + timespec.as_mut_ptr(), + )) + .unwrap(); + timespec.assume_init().into() + } else { + clock_gettime_old(id) + } + } + + // Use `unwrap()` here because `clock_getres` can fail if the clock itself + // overflows a number of seconds, but if that happens, the monotonic clocks + // can't maintain their invariants, or the realtime clocks aren't properly + // configured. + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + unsafe { + ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); + timespec.assume_init() + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[must_use] +unsafe fn clock_gettime_old(id: ClockId) -> Timespec { + let mut old_timespec = MaybeUninit::::uninit(); + ret(c::clock_gettime( + id as c::clockid_t, + old_timespec.as_mut_ptr(), + )) + .unwrap(); + let old_timespec = old_timespec.assume_init(); + Timespec { + tv_sec: old_timespec.tv_sec.into(), + tv_nsec: old_timespec.tv_nsec.into(), + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result { + let mut timespec = MaybeUninit::::uninit(); + unsafe { + let id: c::clockid_t = match id { + DynamicClockId::Known(id) => id as c::clockid_t, + + #[cfg(any(target_os = "android", target_os = "linux"))] + DynamicClockId::Dynamic(fd) => { + use crate::fd::AsRawFd; + const CLOCKFD: i32 = 3; + (!fd.as_raw_fd() << 3) | CLOCKFD + } + + #[cfg(not(any(target_os = "android", target_os = "linux")))] + DynamicClockId::Dynamic(_fd) => { + // Dynamic clocks are not supported on this platform. + return Err(io::Errno::INVAL); + } + + #[cfg(any(target_os = "android", target_os = "linux"))] + DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM, + + #[cfg(any(target_os = "android", target_os = "linux"))] + DynamicClockId::Tai => c::CLOCK_TAI, + + #[cfg(any(target_os = "android", target_os = "linux"))] + DynamicClockId::Boottime => c::CLOCK_BOOTTIME, + + #[cfg(any(target_os = "android", target_os = "linux"))] + DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM, + }; + + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + { + if let Some(libc_clock_gettime) = __clock_gettime64.get() { + ret(libc_clock_gettime( + id as c::clockid_t, + timespec.as_mut_ptr(), + ))?; + + Ok(timespec.assume_init().into()) + } else { + clock_gettime_dynamic_old(id) + } + } + + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + { + ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr()))?; + + Ok(timespec.assume_init()) + } + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[inline] +unsafe fn clock_gettime_dynamic_old(id: c::clockid_t) -> io::Result { + let mut old_timespec = MaybeUninit::::uninit(); + + ret(c::clock_gettime( + id as c::clockid_t, + old_timespec.as_mut_ptr(), + ))?; + + let old_timespec = old_timespec.assume_init(); + Ok(Timespec { + tv_sec: old_timespec.tv_sec.into(), + tv_nsec: old_timespec.tv_nsec.into(), + }) +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(feature = "time")] +pub(crate) fn timerfd_create(id: TimerfdClockId, flags: TimerfdFlags) -> io::Result { + unsafe { ret_owned_fd(c::timerfd_create(id as c::clockid_t, flags.bits())) } +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(feature = "time")] +pub(crate) fn timerfd_settime( + fd: BorrowedFd<'_>, + flags: TimerfdTimerFlags, + new_value: &Itimerspec, +) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_timerfd_settime) = __timerfd_settime64.get() { + ret(libc_timerfd_settime( + borrowed_fd(fd), + flags.bits(), + &new_value.clone().into(), + result.as_mut_ptr(), + ))?; + Ok(result.assume_init().into()) + } else { + timerfd_settime_old(fd, flags, new_value) + } + } + + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + unsafe { + ret(c::timerfd_settime( + borrowed_fd(fd), + flags.bits(), + new_value, + result.as_mut_ptr(), + ))?; + Ok(result.assume_init()) + } +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[cfg(feature = "time")] +unsafe fn timerfd_settime_old( + fd: BorrowedFd<'_>, + flags: TimerfdTimerFlags, + new_value: &Itimerspec, +) -> io::Result { + use core::convert::TryInto; + + let mut old_result = MaybeUninit::::uninit(); + + // Convert `new_value` to the old `itimerspec` format. + let old_new_value = c::itimerspec { + it_interval: c::timespec { + tv_sec: new_value + .it_interval + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: new_value + .it_interval + .tv_nsec + .try_into() + .map_err(|_| io::Errno::INVAL)?, + }, + it_value: c::timespec { + tv_sec: new_value + .it_value + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: new_value + .it_value + .tv_nsec + .try_into() + .map_err(|_| io::Errno::INVAL)?, + }, + }; + + ret(c::timerfd_settime( + borrowed_fd(fd), + flags.bits(), + &old_new_value, + old_result.as_mut_ptr(), + ))?; + + let old_result = old_result.assume_init(); + Ok(Itimerspec { + it_interval: Timespec { + tv_sec: old_result + .it_interval + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: old_result.it_interval.tv_nsec as _, + }, + it_value: Timespec { + tv_sec: old_result + .it_interval + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: old_result.it_interval.tv_nsec as _, + }, + }) +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(feature = "time")] +pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + ))] + unsafe { + if let Some(libc_timerfd_gettime) = __timerfd_gettime64.get() { + ret(libc_timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr()))?; + Ok(result.assume_init().into()) + } else { + timerfd_gettime_old(fd) + } + } + + #[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", + )))] + unsafe { + ret(c::timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr()))?; + Ok(result.assume_init()) + } +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[cfg(feature = "time")] +unsafe fn timerfd_gettime_old(fd: BorrowedFd<'_>) -> io::Result { + use core::convert::TryInto; + + let mut old_result = MaybeUninit::::uninit(); + + ret(c::timerfd_gettime(borrowed_fd(fd), old_result.as_mut_ptr()))?; + + let old_result = old_result.assume_init(); + Ok(Itimerspec { + it_interval: Timespec { + tv_sec: old_result + .it_interval + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: old_result.it_interval.tv_nsec as _, + }, + it_value: Timespec { + tv_sec: old_result + .it_interval + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: old_result.it_interval.tv_nsec as _, + }, + }) +} diff --git a/vendor/rustix/src/backend/libc/time/types.rs b/vendor/rustix/src/backend/libc/time/types.rs new file mode 100644 index 000000000..080f64431 --- /dev/null +++ b/vendor/rustix/src/backend/libc/time/types.rs @@ -0,0 +1,364 @@ +use super::super::c; +#[cfg(not(target_os = "wasi"))] +use crate::fd::BorrowedFd; +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +use bitflags::bitflags; + +/// `struct timespec` +#[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +)))] +pub type Timespec = c::timespec; + +/// `struct timespec` +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[derive(Debug, Clone)] +#[repr(C)] +pub struct Timespec { + /// Seconds. + pub tv_sec: Secs, + + /// Nanoseconds. Must be less than 1_000_000_000. + pub tv_nsec: Nsecs, +} + +/// A type for the `tv_sec` field of [`Timespec`]. +#[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +)))] +#[allow(deprecated)] +pub type Secs = c::time_t; + +/// A type for the `tv_sec` field of [`Timespec`]. +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +pub type Secs = i64; + +/// A type for the `tv_nsec` field of [`Timespec`]. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] +pub type Nsecs = i64; + +/// A type for the `tv_nsec` field of [`Timespec`]. +#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] +pub type Nsecs = c::c_long; + +/// On most platforms, `LibcTimespec` is just `Timespec`. +#[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +)))] +pub(crate) type LibcTimespec = Timespec; + +/// On 32-bit glibc platforms, `timespec` has anonymous padding fields, which +/// Rust doesn't support yet (see `unnamed_fields`), so we define our own +/// struct with explicit padding, with bidirectional `From` impls. +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[repr(C)] +#[derive(Debug, Clone)] +pub(crate) struct LibcTimespec { + pub(crate) tv_sec: Secs, + + #[cfg(target_endian = "big")] + padding: core::mem::MaybeUninit, + + pub(crate) tv_nsec: Nsecs, + + #[cfg(target_endian = "little")] + padding: core::mem::MaybeUninit, +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +impl From for Timespec { + #[inline] + fn from(t: LibcTimespec) -> Self { + Self { + tv_sec: t.tv_sec, + tv_nsec: t.tv_nsec, + } + } +} + +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +impl From for LibcTimespec { + #[inline] + fn from(t: Timespec) -> Self { + Self { + tv_sec: t.tv_sec, + tv_nsec: t.tv_nsec, + padding: core::mem::MaybeUninit::uninit(), + } + } +} + +/// `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 +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[cfg_attr(not(target_os = "dragonfly"), repr(i32))] +#[cfg_attr(target_os = "dragonfly", repr(u64))] +#[non_exhaustive] +pub enum ClockId { + /// `CLOCK_REALTIME` + Realtime = c::CLOCK_REALTIME, + + /// `CLOCK_MONOTONIC` + Monotonic = c::CLOCK_MONOTONIC, + + /// `CLOCK_PROCESS_CPUTIME_ID` + #[cfg(not(any( + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, + + /// `CLOCK_THREAD_CPUTIME_ID` + #[cfg(not(any( + target_os = "illumos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", + target_os = "solaris", + )))] + ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, + + /// `CLOCK_REALTIME_COARSE` + #[cfg(any(target_os = "android", target_os = "linux"))] + RealtimeCoarse = c::CLOCK_REALTIME_COARSE, + + /// `CLOCK_MONOTONIC_COARSE` + #[cfg(any(target_os = "android", target_os = "linux"))] + MonotonicCoarse = c::CLOCK_MONOTONIC_COARSE, + + /// `CLOCK_MONOTONIC_RAW` + #[cfg(any(target_os = "android", target_os = "linux"))] + MonotonicRaw = c::CLOCK_MONOTONIC_RAW, +} + +/// `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. +#[cfg(any(target_os = "ios", target_os = "macos"))] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[repr(u32)] +#[non_exhaustive] +pub enum ClockId { + /// `CLOCK_REALTIME` + Realtime = c::CLOCK_REALTIME, + + /// `CLOCK_MONOTONIC` + Monotonic = c::CLOCK_MONOTONIC, + + /// `CLOCK_PROCESS_CPUTIME_ID` + ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, + + /// `CLOCK_THREAD_CPUTIME_ID` + ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, +} + +/// `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 +#[cfg(not(target_os = "wasi"))] +#[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 + #[cfg(any(target_os = "android", target_os = "linux"))] + RealtimeAlarm, + + /// `CLOCK_TAI`, available on Linux >= 3.10 + #[cfg(any(target_os = "android", target_os = "linux"))] + Tai, + + /// `CLOCK_BOOTTIME`, available on Linux >= 2.6.39 + #[cfg(any(target_os = "android", target_os = "linux"))] + Boottime, + + /// `CLOCK_BOOTTIME_ALARM`, available on Linux >= 2.6.39 + #[cfg(any(target_os = "android", target_os = "linux"))] + BoottimeAlarm, +} + +/// `struct itimerspec` +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +)))] +pub type Itimerspec = c::itimerspec; + +/// `struct itimerspec` +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[allow(missing_docs)] +#[repr(C)] +#[derive(Debug, Clone)] +pub struct Itimerspec { + pub it_interval: Timespec, + pub it_value: Timespec, +} + +/// On most platforms, `LibcItimerspec` is just `Itimerspec`. +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(not(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +)))] +pub(crate) type LibcItimerspec = Itimerspec; + +/// On 32-bit glibc platforms, `LibcTimespec` differs from `Timespec`, so we +/// define our own struct, with bidirectional `From` impls. +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +#[repr(C)] +#[derive(Debug, Clone)] +pub(crate) struct LibcItimerspec { + pub it_interval: LibcTimespec, + pub it_value: LibcTimespec, +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +impl From for Itimerspec { + #[inline] + fn from(t: LibcItimerspec) -> Self { + Self { + it_interval: t.it_interval.into(), + it_value: t.it_value.into(), + } + } +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[cfg(all( + any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), + target_env = "gnu", +))] +impl From for LibcItimerspec { + #[inline] + fn from(t: Itimerspec) -> Self { + Self { + it_interval: t.it_interval.into(), + it_value: t.it_value.into(), + } + } +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +bitflags! { + /// `TFD_*` flags for use with [`timerfd_create`]. + pub struct TimerfdFlags: c::c_int { + /// `TFD_NONBLOCK` + const NONBLOCK = c::TFD_NONBLOCK; + + /// `TFD_CLOEXEC` + const CLOEXEC = c::TFD_CLOEXEC; + } +} + +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +bitflags! { + /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. + pub struct TimerfdTimerFlags: c::c_int { + /// `TFD_TIMER_ABSTIME` + const ABSTIME = c::TFD_TIMER_ABSTIME; + + /// `TFD_TIMER_CANCEL_ON_SET` + #[cfg(any(target_os = "android", target_os = "linux"))] + const CANCEL_ON_SET = 2; // TODO: upstream TFD_TIMER_CANCEL_ON_SET + } +} + +/// `CLOCK_*` constants for use with [`timerfd_create`]. +/// +/// [`timerfd_create`]: crate::time::timerfd_create +#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[repr(i32)] +#[non_exhaustive] +pub enum TimerfdClockId { + /// `CLOCK_REALTIME`—A clock that tells the "real" time. + /// + /// This is a clock that tells the amount of time elapsed since the + /// Unix epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so + /// it is not monotonic. Successive reads may see decreasing times, so it + /// isn't reliable for measuring durations. + Realtime = c::CLOCK_REALTIME, + + /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. + /// + /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so + /// individual times aren't meaningful. However, since it isn't settable, + /// it is reliable for measuring durations. + /// + /// This clock does not advance while the system is suspended; see + /// `Boottime` for a clock that does. + Monotonic = c::CLOCK_MONOTONIC, + + /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. + /// + /// This clock is similar to `Monotonic`, but does advance while the system + /// is suspended. + Boottime = c::CLOCK_BOOTTIME, + + /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. + /// + /// This clock is like `Realtime`, but can wake up a suspended system. + /// + /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + RealtimeAlarm = c::CLOCK_REALTIME_ALARM, + + /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. + /// + /// This clock is like `Boottime`, but can wake up a suspended system. + /// + /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + BoottimeAlarm = c::CLOCK_BOOTTIME_ALARM, +} diff --git a/vendor/rustix/src/backend/libc/weak.rs b/vendor/rustix/src/backend/libc/weak.rs new file mode 100644 index 000000000..d578038cd --- /dev/null +++ b/vendor/rustix/src/backend/libc/weak.rs @@ -0,0 +1,226 @@ +// Implementation derived from `weak` in Rust's +// library/std/src/sys/unix/weak.rs at revision +// fd0cb0cdc21dd9c06025277d772108f8d42cb25f. + +//! Support for "weak linkage" to symbols on Unix +//! +//! Some I/O operations we do in libstd require newer versions of OSes but we +//! need to maintain binary compatibility with older releases for now. In order +//! to use the new functionality when available we use this module for +//! detection. +//! +//! One option to use here is weak linkage, but that is unfortunately only +//! really workable on Linux. Hence, use dlsym to get the symbol value at +//! runtime. This is also done for compatibility with older versions of glibc, +//! and to avoid creating dependencies on `GLIBC_PRIVATE` symbols. It assumes +//! that we've been dynamically linked to the library the symbol comes from, +//! but that is currently always the case for things like libpthread/libc. +//! +//! A long time ago this used weak linkage for the `__pthread_get_minstack` +//! symbol, but that caused Debian to detect an unnecessarily strict versioned +//! dependency on libc6 (#23628). + +// There are a variety of `#[cfg]`s controlling which targets are involved in +// each instance of `weak!` and `syscall!`. Rather than trying to unify all of +// that, we'll just allow that some unix targets don't use this module at all. +#![allow(dead_code, unused_macros)] +#![allow(clippy::doc_markdown)] + +use crate::ffi::CStr; +use core::ffi::c_void; +use core::ptr::null_mut; +use core::sync::atomic::{self, AtomicPtr, Ordering}; +use core::{marker, mem}; + +const NULL: *mut c_void = null_mut(); +const INVALID: *mut c_void = 1 as *mut c_void; + +macro_rules! weak { + ($vis:vis fn $name:ident($($t:ty),*) -> $ret:ty) => ( + #[allow(non_upper_case_globals)] + $vis static $name: $crate::backend::weak::Weak $ret> = + $crate::backend::weak::Weak::new(concat!(stringify!($name), '\0')); + ) +} + +pub(crate) struct Weak { + name: &'static str, + addr: AtomicPtr, + _marker: marker::PhantomData, +} + +impl Weak { + pub(crate) const fn new(name: &'static str) -> Self { + Self { + name, + addr: AtomicPtr::new(INVALID), + _marker: marker::PhantomData, + } + } + + pub(crate) fn get(&self) -> Option { + assert_eq!(mem::size_of::(), mem::size_of::()); + unsafe { + // Relaxed is fine here because we fence before reading through the + // pointer (see the comment below). + match self.addr.load(Ordering::Relaxed) { + INVALID => self.initialize(), + NULL => None, + addr => { + let func = mem::transmute_copy::<*mut c_void, F>(&addr); + // The caller is presumably going to read through this value + // (by calling the function we've dlsymed). This means we'd + // need to have loaded it with at least C11's consume + // ordering in order to be guaranteed that the data we read + // from the pointer isn't from before the pointer was + // stored. Rust has no equivalent to memory_order_consume, + // so we use an acquire fence (sorry, ARM). + // + // Now, in practice this likely isn't needed even on CPUs + // where relaxed and consume mean different things. The + // symbols we're loading are probably present (or not) at + // init, and even if they aren't the runtime dynamic loader + // is extremely likely have sufficient barriers internally + // (possibly implicitly, for example the ones provided by + // invoking `mprotect`). + // + // That said, none of that's *guaranteed*, and so we fence. + atomic::fence(Ordering::Acquire); + Some(func) + } + } + } + } + + // Cold because it should only happen during first-time initialization. + #[cold] + unsafe fn initialize(&self) -> Option { + let val = fetch(self.name); + // This synchronizes with the acquire fence in `get`. + self.addr.store(val, Ordering::Release); + + match val { + NULL => None, + addr => Some(mem::transmute_copy::<*mut c_void, F>(&addr)), + } + } +} + +unsafe fn fetch(name: &str) -> *mut c_void { + let name = match CStr::from_bytes_with_nul(name.as_bytes()) { + Ok(c_str) => c_str, + Err(..) => return null_mut(), + }; + libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr().cast()) +} + +#[cfg(not(any(target_os = "android", target_os = "linux")))] +macro_rules! syscall { + (fn $name:ident($($arg_name:ident: $t:ty),*) via $_sys_name:ident -> $ret:ty) => ( + unsafe fn $name($($arg_name: $t),*) -> $ret { + weak! { fn $name($($t),*) -> $ret } + + if let Some(fun) = $name.get() { + fun($($arg_name),*) + } else { + libc_errno::set_errno(libc_errno::Errno(libc::ENOSYS)); + -1 + } + } + ) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +macro_rules! syscall { + (fn $name:ident($($arg_name:ident: $t:ty),*) via $sys_name:ident -> $ret:ty) => ( + unsafe fn $name($($arg_name:$t),*) -> $ret { + // This looks like a hack, but concat_idents only accepts idents + // (not paths). + use libc::*; + + trait AsSyscallArg { + type SyscallArgType; + fn into_syscall_arg(self) -> Self::SyscallArgType; + } + + // Pass pointer types as pointers, to preserve provenance. + impl AsSyscallArg for *mut T { + type SyscallArgType = *mut T; + fn into_syscall_arg(self) -> Self::SyscallArgType { self } + } + impl AsSyscallArg for *const T { + type SyscallArgType = *const T; + fn into_syscall_arg(self) -> Self::SyscallArgType { self } + } + + // Pass `BorrowedFd` values as the integer value. + impl AsSyscallArg for $crate::fd::BorrowedFd<'_> { + type SyscallArgType = c::c_long; + fn into_syscall_arg(self) -> Self::SyscallArgType { + $crate::fd::AsRawFd::as_raw_fd(&self) as _ + } + } + + // Coerce integer values into `c_long`. + impl AsSyscallArg for i32 { + type SyscallArgType = c::c_long; + fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } + } + impl AsSyscallArg for u32 { + type SyscallArgType = c::c_long; + fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } + } + impl AsSyscallArg for usize { + type SyscallArgType = c::c_long; + fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } + } + + // `concat_idents is unstable, so we take an extra `sys_name` + // parameter and have our users do the concat for us for now. + /* + syscall( + concat_idents!(SYS_, $name), + $($arg_name.into_syscall_arg()),* + ) as $ret + */ + + syscall($sys_name, $($arg_name.into_syscall_arg()),*) as $ret + } + ) +} + +macro_rules! weakcall { + ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( + $vis unsafe fn $name($($arg_name: $t),*) -> $ret { + weak! { fn $name($($t),*) -> $ret } + + // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` + // interposition, but if it's not found just fail. + if let Some(fun) = $name.get() { + fun($($arg_name),*) + } else { + libc_errno::set_errno(libc_errno::Errno(libc::ENOSYS)); + -1 + } + } + ) +} + +/// A combination of `weakcall` and `syscall`. Use the libc function if it's +/// available, and fall back to `libc::syscall` otherwise. +macro_rules! weak_or_syscall { + ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) via $sys_name:ident -> $ret:ty) => ( + $vis unsafe fn $name($($arg_name: $t),*) -> $ret { + weak! { fn $name($($t),*) -> $ret } + + // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` + // interposition, but if it's not found just fail. + if let Some(fun) = $name.get() { + fun($($arg_name),*) + } else { + syscall! { fn $name($($arg_name: $t),*) via $sys_name -> $ret } + $name($($arg_name),*) + } + } + ) +} diff --git a/vendor/rustix/src/backend/libc/winsock_c.rs b/vendor/rustix/src/backend/libc/winsock_c.rs new file mode 100644 index 000000000..7d78aef65 --- /dev/null +++ b/vendor/rustix/src/backend/libc/winsock_c.rs @@ -0,0 +1,82 @@ +//! Adapt the Winsock2 API to resemble a POSIX-style libc API. + +#![allow(unused_imports)] +#![allow(non_camel_case_types)] + +use windows_sys::Win32::Networking::WinSock; + +pub(crate) use libc::{ + c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong, + c_ushort, c_void, ssize_t, +}; +pub(crate) type socklen_t = i32; + +// windows-sys declares these constants as unsigned. For better compatibility +// with Unix-family APIs, redeclare them as signed. Filed upstream: +// +pub(crate) const AF_INET: i32 = WinSock::AF_INET as _; +pub(crate) const AF_INET6: i32 = WinSock::AF_INET6 as _; +pub(crate) const AF_UNSPEC: i32 = WinSock::AF_UNSPEC as _; +pub(crate) const SO_TYPE: i32 = WinSock::SO_TYPE as _; +pub(crate) const SO_REUSEADDR: i32 = WinSock::SO_REUSEADDR as _; +pub(crate) const SO_BROADCAST: i32 = WinSock::SO_BROADCAST as _; +pub(crate) const SO_LINGER: i32 = WinSock::SO_LINGER as _; +pub(crate) const SOL_SOCKET: i32 = WinSock::SOL_SOCKET as _; +pub(crate) const SO_RCVTIMEO: i32 = WinSock::SO_RCVTIMEO as _; +pub(crate) const SO_SNDTIMEO: i32 = WinSock::SO_SNDTIMEO as _; +pub(crate) const IP_TTL: i32 = WinSock::IP_TTL as _; +pub(crate) const TCP_NODELAY: i32 = WinSock::TCP_NODELAY as _; +pub(crate) const IP_ADD_MEMBERSHIP: i32 = WinSock::IP_ADD_MEMBERSHIP as _; +pub(crate) const IP_DROP_MEMBERSHIP: i32 = WinSock::IP_DROP_MEMBERSHIP as _; +pub(crate) const IP_MULTICAST_TTL: i32 = WinSock::IP_MULTICAST_TTL as _; +pub(crate) const IP_MULTICAST_LOOP: i32 = WinSock::IP_MULTICAST_LOOP as _; +pub(crate) const IPV6_ADD_MEMBERSHIP: i32 = WinSock::IPV6_ADD_MEMBERSHIP as _; +pub(crate) const IPV6_DROP_MEMBERSHIP: i32 = WinSock::IPV6_DROP_MEMBERSHIP as _; +pub(crate) const IPV6_MULTICAST_LOOP: i32 = WinSock::IPV6_MULTICAST_LOOP as _; +pub(crate) const IPV6_V6ONLY: i32 = WinSock::IPV6_V6ONLY as _; +pub(crate) const POLLERR: i16 = WinSock::POLLERR as _; +pub(crate) const POLLIN: i16 = WinSock::POLLIN as _; +pub(crate) const POLLNVAL: i16 = WinSock::POLLNVAL as _; +pub(crate) const POLLHUP: i16 = WinSock::POLLHUP as _; +pub(crate) const POLLPRI: i16 = WinSock::POLLPRI as _; +pub(crate) const POLLOUT: i16 = WinSock::POLLOUT as _; +pub(crate) const POLLRDNORM: i16 = WinSock::POLLRDNORM as _; +pub(crate) const POLLWRNORM: i16 = WinSock::POLLWRNORM as _; +pub(crate) const POLLRDBAND: i16 = WinSock::POLLRDBAND as _; +pub(crate) const POLLWRBAND: i16 = WinSock::POLLWRBAND as _; + +// As above, cast the types for better compatibility, and also rename these to +// their Unix names. +pub(crate) const SHUT_RDWR: i32 = WinSock::SD_BOTH as _; +pub(crate) const SHUT_RD: i32 = WinSock::SD_RECEIVE as _; +pub(crate) const SHUT_WR: i32 = WinSock::SD_SEND as _; + +// Include the contents of `WinSock`, renaming as needed to match POSIX. +// +// Use `WSA_E_CANCELLED` for `ECANCELED` instead of `WSAECANCELLED`, because +// `WSAECANCELLED` will be removed in the future. +// +pub(crate) use WinSock::{ + closesocket as close, ioctlsocket as ioctl, WSAPoll as poll, ADDRESS_FAMILY as sa_family_t, + ADDRINFOA as addrinfo, IN6_ADDR as in6_addr, IN_ADDR as in_addr, IPV6_MREQ as ipv6_mreq, + IP_MREQ as ip_mreq, LINGER as linger, SOCKADDR as sockaddr, SOCKADDR_IN as sockaddr_in, + SOCKADDR_IN6 as sockaddr_in6, SOCKADDR_STORAGE as sockaddr_storage, WSAEACCES as EACCES, + WSAEADDRINUSE as EADDRINUSE, WSAEADDRNOTAVAIL as EADDRNOTAVAIL, + WSAEAFNOSUPPORT as EAFNOSUPPORT, WSAEALREADY as EALREADY, WSAEBADF as EBADF, + WSAECONNABORTED as ECONNABORTED, WSAECONNREFUSED as ECONNREFUSED, WSAECONNRESET as ECONNRESET, + WSAEDESTADDRREQ as EDESTADDRREQ, WSAEDISCON as EDISCON, WSAEDQUOT as EDQUOT, + WSAEFAULT as EFAULT, WSAEHOSTDOWN as EHOSTDOWN, WSAEHOSTUNREACH as EHOSTUNREACH, + WSAEINPROGRESS as EINPROGRESS, WSAEINTR as EINTR, WSAEINVAL as EINVAL, + WSAEINVALIDPROCTABLE as EINVALIDPROCTABLE, WSAEINVALIDPROVIDER as EINVALIDPROVIDER, + WSAEISCONN as EISCONN, WSAELOOP as ELOOP, WSAEMFILE as EMFILE, WSAEMSGSIZE as EMSGSIZE, + WSAENAMETOOLONG as ENAMETOOLONG, WSAENETDOWN as ENETDOWN, WSAENETRESET as ENETRESET, + WSAENETUNREACH as ENETUNREACH, WSAENOBUFS as ENOBUFS, WSAENOMORE as ENOMORE, + WSAENOPROTOOPT as ENOPROTOOPT, WSAENOTCONN as ENOTCONN, WSAENOTEMPTY as ENOTEMPTY, + WSAENOTSOCK as ENOTSOCK, WSAEOPNOTSUPP as EOPNOTSUPP, WSAEPFNOSUPPORT as EPFNOSUPPORT, + WSAEPROCLIM as EPROCLIM, WSAEPROTONOSUPPORT as EPROTONOSUPPORT, WSAEPROTOTYPE as EPROTOTYPE, + WSAEPROVIDERFAILEDINIT as EPROVIDERFAILEDINIT, WSAEREFUSED as EREFUSED, WSAEREMOTE as EREMOTE, + WSAESHUTDOWN as ESHUTDOWN, WSAESOCKTNOSUPPORT as ESOCKTNOSUPPORT, WSAESTALE as ESTALE, + WSAETIMEDOUT as ETIMEDOUT, WSAETOOMANYREFS as ETOOMANYREFS, WSAEUSERS as EUSERS, + WSAEWOULDBLOCK as EWOULDBLOCK, WSAEWOULDBLOCK as EAGAIN, WSAPOLLFD as pollfd, + WSA_E_CANCELLED as ECANCELED, *, +}; diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/aarch64.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/aarch64.rs new file mode 100644 index 000000000..0f4465d51 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/aarch64.rs @@ -0,0 +1,268 @@ +//! aarch64 Linux system calls. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[cfg(target_pointer_width = "32")] +compile_error!("arm64-ilp32 is not supported yet"); + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + lateout("x0") r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "svc 0", + in("x8") nr.to_asm(), + in("x0") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + in("x3") a3.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + in("x3") a3.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + in("x3") a3.to_asm(), + in("x4") a4.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + in("x3") a3.to_asm(), + in("x4") a4.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + in("x3") a3.to_asm(), + in("x4") a4.to_asm(), + in("x5") a5.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("x8") nr.to_asm(), + inlateout("x0") a0.to_asm() => r0, + in("x1") a1.to_asm(), + in("x2") a2.to_asm(), + in("x3") a3.to_asm(), + in("x4") a4.to_asm(), + in("x5") a5.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/arm.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/arm.rs new file mode 100644 index 000000000..9695c6028 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/arm.rs @@ -0,0 +1,265 @@ +//! arm Linux system calls. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + lateout("r0") r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "svc 0", + in("r7") nr.to_asm(), + in("r0") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + in("r5") a5.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "svc 0", + in("r7") nr.to_asm(), + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + in("r5") a5.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/mips.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/mips.rs new file mode 100644 index 000000000..b39a16847 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/mips.rs @@ -0,0 +1,543 @@ +//! mipsel Linux system calls. +//! +//! On mipsel, Linux indicates success or failure using `$a3` rather +//! than by returning a negative error code as most other architectures do. +//! +//! Mips-family platforms have a special calling convention for `__NR_pipe`, +//! however we use `__NR_pipe2` instead to avoid having to implement it. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, A6, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "syscall", + in("$2" /*$v0*/) nr.to_asm(), + in("$4" /*$a0*/) a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let x0; + let err: usize; + asm!( + ".set noat", + "subu $sp, 32", + "sw {}, 16($sp)", + "syscall", + "addu $sp, 32", + ".set at", + in(reg) a4.to_asm(), + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let x0; + let err: usize; + asm!( + ".set noat", + "subu $sp, 32", + "sw {}, 16($sp)", + "syscall", + "addu $sp, 32", + ".set at", + in(reg) a4.to_asm(), + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let x0; + let err: usize; + asm!( + ".set noat", + "subu $sp, 32", + "sw {}, 16($sp)", + "sw {}, 20($sp)", + "syscall", + "addu $sp, 32", + ".set at", + in(reg) a4.to_asm(), + in(reg) a5.to_asm(), + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let x0; + let err: usize; + asm!( + ".set noat", + "subu $sp, 32", + "sw {}, 16($sp)", + "sw {}, 20($sp)", + "syscall", + "addu $sp, 32", + ".set at", + in(reg) a4.to_asm(), + in(reg) a5.to_asm(), + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall7_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + a6: ArgReg<'_, A6>, +) -> RetReg { + let x0; + let err: usize; + asm!( + ".set noat", + "subu $sp, 32", + "sw {}, 16($sp)", + "sw {}, 20($sp)", + "sw {}, 24($sp)", + "syscall", + "addu $sp, 32", + ".set at", + in(reg) a4.to_asm(), + in(reg) a5.to_asm(), + in(reg) a6.to_asm(), + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$t0*/) _, + lateout("$9" /*$t1*/) _, + lateout("$10" /*$t2*/) _, + lateout("$11" /*$t3*/) _, + lateout("$12" /*$t4*/) _, + lateout("$13" /*$t5*/) _, + lateout("$14" /*$t6*/) _, + lateout("$15" /*$t7*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/mips64.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/mips64.rs new file mode 100644 index 000000000..d3c7d341f --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/mips64.rs @@ -0,0 +1,466 @@ +//! mips64el Linux system calls. +//! +//! On mips64el, Linux indicates success or failure using `$a3` (`$7`) rather +//! than by returning a negative error code as most other architectures do. +//! +//! Mips-family platforms have a special calling convention for `__NR_pipe`, +//! however we use `__NR_pipe2` instead to avoid having to implement it. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "syscall", + in("$2" /*$v0*/) nr.to_asm(), + in("$4" /*$a0*/) a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + lateout("$7" /*$a3*/) err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + lateout("$8" /*$a4*/) _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + inlateout("$8" /*$a4*/) a4.to_asm() => _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + inlateout("$8" /*$a4*/) a4.to_asm() => _, + lateout("$9" /*$a5*/) _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + inlateout("$8" /*$a4*/) a4.to_asm() => _, + inlateout("$9" /*$a5*/) a5.to_asm() => _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let x0; + let err: usize; + asm!( + "syscall", + inlateout("$2" /*$v0*/) nr.to_asm() => x0, + in("$4" /*$a0*/) a0.to_asm(), + in("$5" /*$a1*/) a1.to_asm(), + in("$6" /*$a2*/) a2.to_asm(), + inlateout("$7" /*$a3*/) a3.to_asm() => err, + inlateout("$8" /*$a4*/) a4.to_asm() => _, + inlateout("$9" /*$a5*/) a5.to_asm() => _, + lateout("$10" /*$a6*/) _, + lateout("$11" /*$a7*/) _, + lateout("$12" /*$t0*/) _, + lateout("$13" /*$t1*/) _, + lateout("$14" /*$t2*/) _, + lateout("$15" /*$t3*/) _, + lateout("$24" /*$t8*/) _, + lateout("$25" /*$t9*/) _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(if err != 0 { + (x0 as usize).wrapping_neg() as *mut _ + } else { + x0 + }) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs new file mode 100644 index 000000000..524c449d9 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/mod.rs @@ -0,0 +1,18 @@ +//! Inline asm for making system calls. +//! +//! Compilers should really have intrinsics for making system calls. They're +//! much like regular calls, with custom calling conventions, and calling +//! conventions are otherwise the compiler's job. But for now, use inline asm. + +#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")] +#[cfg_attr(all(target_arch = "arm", not(thumb_mode)), path = "arm.rs")] +#[cfg_attr(all(target_arch = "arm", thumb_mode), path = "thumb.rs")] +#[cfg_attr(target_arch = "mips", path = "mips.rs")] +#[cfg_attr(target_arch = "mips64", path = "mips64.rs")] +#[cfg_attr(target_arch = "powerpc64", path = "powerpc64.rs")] +#[cfg_attr(target_arch = "riscv64", path = "riscv64.rs")] +#[cfg_attr(target_arch = "x86", path = "x86.rs")] +#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")] +mod target_arch; + +pub(in crate::backend) use self::target_arch::*; diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/powerpc64.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/powerpc64.rs new file mode 100644 index 000000000..8cca7dca7 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/powerpc64.rs @@ -0,0 +1,413 @@ +//! powerpc64le Linux system calls. +//! +//! On powerpc64le, Linux indicates success or failure using `cr0.SO` rather +//! than by returning a negative error code as most other architectures do. In +//! theory we could immediately translate this into a `Result`, and it'd save a +//! few branches. And in theory we could have specialized sequences for use +//! with syscalls that are known to never fail. However, those would require +//! more extensive changes in rustix's platform-independent code. For now, we +//! check the flag and negate the error value to make PowerPC64 look like other +//! architectures. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + lateout("r3") r0, + lateout("r4") _, + lateout("r5") _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + lateout("r4") _, + lateout("r5") _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + lateout("r4") _, + lateout("r5") _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "sc", + in("r0") nr.to_asm(), + in("r3") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + lateout("r5") _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + lateout("r5") _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + lateout("r6") _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + inlateout("r6") a3.to_asm() => _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + inlateout("r6") a3.to_asm() => _, + lateout("r7") _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + inlateout("r6") a3.to_asm() => _, + inlateout("r7") a4.to_asm() => _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + inlateout("r6") a3.to_asm() => _, + inlateout("r7") a4.to_asm() => _, + lateout("r8") _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + inlateout("r6") a3.to_asm() => _, + inlateout("r7") a4.to_asm() => _, + inlateout("r8") a5.to_asm() => _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "sc", + "bns 0f", + "neg 3, 3", + "0:", + inlateout("r0") nr.to_asm() => _, + inlateout("r3") a0.to_asm() => r0, + inlateout("r4") a1.to_asm() => _, + inlateout("r5") a2.to_asm() => _, + inlateout("r6") a3.to_asm() => _, + inlateout("r7") a4.to_asm() => _, + inlateout("r8") a5.to_asm() => _, + lateout("r9") _, + lateout("r10") _, + lateout("r11") _, + lateout("r12") _, + lateout("cr0") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/riscv64.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/riscv64.rs new file mode 100644 index 000000000..b1e306266 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/riscv64.rs @@ -0,0 +1,265 @@ +//! riscv64 Linux system calls. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + lateout("a0") r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "ecall", + in("a7") nr.to_asm(), + in("a0") a0.to_asm(), + options(noreturn) + ); +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + in("a3") a3.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + in("a3") a3.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + in("a3") a3.to_asm(), + in("a4") a4.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + in("a3") a3.to_asm(), + in("a4") a4.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + in("a3") a3.to_asm(), + in("a4") a4.to_asm(), + in("a5") a5.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "ecall", + in("a7") nr.to_asm(), + inlateout("a0") a0.to_asm() => r0, + in("a1") a1.to_asm(), + in("a2") a2.to_asm(), + in("a3") a3.to_asm(), + in("a4") a4.to_asm(), + in("a5") a5.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/thumb.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/thumb.rs new file mode 100644 index 000000000..398a73dfe --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/thumb.rs @@ -0,0 +1,322 @@ +//! arm Linux system calls, using thumb-mode. +//! +//! In thumb-mode, r7 is the frame pointer and is not permitted to be used in +//! an inline asm operand, so we have to use a different register and copy it +//! into r7 inside the inline asm. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + lateout("r0") r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "mov r7, {nr}", + "svc 0", + nr = in(reg) nr.to_asm(), + in("r0") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + in("r5") a5.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "mov {tmp}, r7", + "mov r7, {nr}", + "svc 0", + "mov r7, {tmp}", + nr = in(reg) nr.to_asm(), + tmp = out(reg) _, + inlateout("r0") a0.to_asm() => r0, + in("r1") a1.to_asm(), + in("r2") a2.to_asm(), + in("r3") a3.to_asm(), + in("r4") a4.to_asm(), + in("r5") a5.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs new file mode 100644 index 000000000..8e115148d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/x86.rs @@ -0,0 +1,494 @@ +//! 32-bit x86 Linux system calls. +//! +//! There are two forms; `indirect_*` which take a callee, which allow calling +//! through the vDSO when possible, and plain forms, which use the `int 0x80` +//! instruction. +//! +//! Most `rustix` syscalls use the vsyscall mechanism rather than going using +//! `int 0x80` sequences. + +#![allow(dead_code)] + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use crate::backend::vdso_wrappers::SyscallType; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall0( + callee: SyscallType, + nr: SyscallNumber<'_>, +) -> RetReg { + let r0; + asm!( + "call {callee}", + callee = in(reg) callee, + inlateout("eax") nr.to_asm() => r0, + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall1( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "call {callee}", + callee = in(reg) callee, + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall1_noreturn( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> ! { + asm!( + "call {callee}", + callee = in(reg) callee, + in("eax") nr.to_asm(), + in("ebx") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall2( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "call {callee}", + callee = in(reg) callee, + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall3( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "call {callee}", + callee = in(reg) callee, + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall4( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + 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. + // + // 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 + // satisfy `in(reg)`. + asm!( + "xchg esi, {a3}", + "call edi", + "xchg esi, {a3}", + a3 = in(reg) a3.to_asm(), + in("edi") callee, + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall5( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + // Oof. a3 should go in esi, and `asm!` won't let us use that register as + // an operand. And we can't request stack slots. And there are no other + // registers free. Use eax as a temporary pointer to a slice, since it + // gets clobbered as the return value anyway. + asm!( + "push esi", + "push DWORD PTR [eax + 0]", + "mov esi, DWORD PTR [eax + 4]", + "mov eax, DWORD PTR [eax + 8]", + "call DWORD PTR [esp]", + "pop esi", + "pop esi", + inout("eax") &[callee as _, a3.to_asm(), nr.to_asm()] => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + in("edi") a4.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[allow(clippy::too_many_arguments)] +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall6( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + // Oof again. a3 should go in esi, and a5 should go in ebp, and `asm!` + // won't let us use either of those registers as operands. And we can't + // request stack slots. And there are no other registers free. Use eax as a + // temporary pointer to a slice, since it gets clobbered as the return + // value anyway. + // + // This is another reason that syscalls should be compiler intrinsics + // rather than inline asm. + asm!( + "push ebp", + "push esi", + "push DWORD PTR [eax + 0]", + "mov esi, DWORD PTR [eax + 4]", + "mov ebp, DWORD PTR [eax + 8]", + "mov eax, DWORD PTR [eax + 12]", + "call DWORD PTR [esp]", + "pop esi", + "pop esi", + "pop ebp", + inout("eax") &[callee as _, a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + in("edi") a4.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "int $$0x80", + in("eax") nr.to_asm(), + in("ebx") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "int $$0x80", + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + 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. + asm!( + "xchg esi, {a3}", + "int $$0x80", + "xchg esi, {a3}", + a3 = in(reg) a3.to_asm(), + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "xchg esi, {a3}", + "int $$0x80", + "xchg esi, {a3}", + a3 = in(reg) a3.to_asm(), + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + // As in `syscall4`, use xchg to handle a3. a4 should go in edi, and we can + // use that register as an operand. Unlike in `indirect_syscall5`, we don't + // have a `callee` operand taking up a register, so we have enough + // registers and don't need to use a slice. + asm!( + "xchg esi, {a3}", + "int $$0x80", + "xchg esi, {a3}", + a3 = in(reg) a3.to_asm(), + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + in("edi") a4.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + // See the comments in `syscall5`. + asm!( + "xchg esi, {a3}", + "int $$0x80", + "xchg esi, {a3}", + a3 = in(reg) a3.to_asm(), + inlateout("eax") nr.to_asm() => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + in("edi") a4.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + // See the comments in `indirect_syscall6`. + asm!( + "push ebp", + "push esi", + "mov esi, DWORD PTR [eax + 0]", + "mov ebp, DWORD PTR [eax + 4]", + "mov eax, DWORD PTR [eax + 8]", + "int $$0x80", + "pop esi", + "pop ebp", + inout("eax") &[a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + in("edi") a4.to_asm(), + options(preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + // See the comments in `indirect_syscall6`. + asm!( + "push ebp", + "push esi", + "mov esi, DWORD PTR [eax + 0]", + "mov ebp, DWORD PTR [eax + 4]", + "mov eax, DWORD PTR [eax + 8]", + "int $$0x80", + "pop esi", + "pop ebp", + inout("eax") &[a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, + in("ebx") a0.to_asm(), + in("ecx") a1.to_asm(), + in("edx") a2.to_asm(), + in("edi") a4.to_asm(), + options(preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/inline/x86_64.rs b/vendor/rustix/src/backend/linux_raw/arch/inline/x86_64.rs new file mode 100644 index 000000000..084f5fee4 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/inline/x86_64.rs @@ -0,0 +1,293 @@ +//! x86-64 Linux system calls. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[cfg(target_pointer_width = "32")] +compile_error!("x32 is not yet supported"); + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "syscall", + in("rax") nr.to_asm(), + in("rdi") a0.to_asm(), + options(noreturn) + ) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + in("r10") a3.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + in("r10") a3.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + in("r10") a3.to_asm(), + in("r8") a4.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + in("r10") a3.to_asm(), + in("r8") a4.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + in("r10") a3.to_asm(), + in("r8") a4.to_asm(), + in("r9") a5.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "syscall", + inlateout("rax") nr.to_asm() => r0, + in("rdi") a0.to_asm(), + in("rsi") a1.to_asm(), + in("rdx") a2.to_asm(), + in("r10") a3.to_asm(), + in("r8") a4.to_asm(), + in("r9") a5.to_asm(), + lateout("rcx") _, + lateout("r11") _, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/mod.rs new file mode 100644 index 000000000..e13f675fd --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/mod.rs @@ -0,0 +1,222 @@ +//! 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). +//! +//! This module also has a `choose` submodule which chooses a scheme and is +//! what most of the `rustix` syscalls use. +//! +//! # Safety +//! +//! This contains the inline `asm` statements performing the syscall +//! instructions and FFI declarations declaring the out-of-line ("outline") +//! syscall instructions. + +#![allow(unsafe_code)] +#![cfg_attr(not(feature = "all-apis"), allow(unused_imports))] +// We'll use as many arguments as syscalls need. +#![allow(clippy::too_many_arguments)] + +// When inline asm is available, use it. Otherwise, use out-of-line asm. These +// functions always use the machine's syscall instruction, even when it isn't +// the fastest option available. +#[cfg_attr(asm, path = "inline/mod.rs")] +#[cfg_attr(not(asm), path = "outline/mod.rs")] +pub(in crate::backend) mod asm; + +// On most architectures, the architecture syscall instruction is fast, so use +// it directly. +#[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 self::asm as choose; + +// On 32-bit x86, use vDSO wrappers for all syscalls. We could use the +// architecture syscall instruction (`int 0x80`), but the vDSO kernel_vsyscall +// mechanism is much faster. +#[cfg(target_arch = "x86")] +pub(in crate::backend) use super::vdso_wrappers::x86_via_vdso as choose; + +// This would be the code for always using `int 0x80` on 32-bit x86. +//#[cfg(target_arch = "x86")] +//pub(in crate::backend) use self::asm as choose; + +// Macros for invoking system calls. +// +// These factor out: +// - Calling `nr` on the syscall number to convert it into `SyscallNumber`. +// - Calling `.into()` on each of the arguments to convert them into `ArgReg`. +// - Qualifying the `syscall*` and `__NR_*` identifiers. +// - Counting the number of arguments. +macro_rules! syscall { + ($nr:ident) => { + $crate::backend::arch::choose::syscall0($crate::backend::reg::nr( + linux_raw_sys::general::$nr, + )) + }; + + ($nr:ident, $a0:expr) => { + $crate::backend::arch::choose::syscall1( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr) => { + $crate::backend::arch::choose::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::choose::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::choose::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::choose::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::choose::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::choose::syscall7( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + $a3.into(), + $a4.into(), + $a5.into(), + $a6.into(), + ) + }; +} + +macro_rules! syscall_readonly { + ($nr:ident) => { + $crate::backend::arch::choose::syscall0_readonly($crate::backend::reg::nr( + linux_raw_sys::general::$nr, + )) + }; + + ($nr:ident, $a0:expr) => { + $crate::backend::arch::choose::syscall1_readonly( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr) => { + $crate::backend::arch::choose::syscall2_readonly( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + ) + }; + + ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { + $crate::backend::arch::choose::syscall3_readonly( + $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::choose::syscall4_readonly( + $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::choose::syscall5_readonly( + $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::choose::syscall6_readonly( + $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::choose::syscall7_readonly( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + $a1.into(), + $a2.into(), + $a3.into(), + $a4.into(), + $a5.into(), + $a6.into(), + ) + }; +} + +#[cfg(feature = "runtime")] +macro_rules! syscall_noreturn { + ($nr:ident, $a0:expr) => { + $crate::backend::arch::choose::syscall1_noreturn( + $crate::backend::reg::nr(linux_raw_sys::general::$nr), + $a0.into(), + ) + }; +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s new file mode 100644 index 000000000..1fad2fa6d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/aarch64.s @@ -0,0 +1,119 @@ +// 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 new file mode 100644 index 000000000..7001686f1 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/arm.s @@ -0,0 +1,135 @@ +// 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 new file mode 100644 index 000000000..ab1bbfa2d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/mips.s @@ -0,0 +1,213 @@ +# Assembly code for making mips64 syscalls. +# +# mips64 syscall argument register ordering is the same as the mips64 +# userspace argument register ordering except that the syscall number +# (nr) is passed in v0. +# +# 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" + .section .mdebug.abi32 + .previous + .abicalls + + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall0_nr_last +rustix_syscall0_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $4 + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall0_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall1_nr_last +rustix_syscall1_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $5 + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall1_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall1_noreturn_nr_last +rustix_syscall1_noreturn_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $5 + syscall + teq $zero, $zero + .end rustix_syscall1_noreturn_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall2_nr_last +rustix_syscall2_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $6 + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall2_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall3_nr_last +rustix_syscall3_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $7 + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall3_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall4_nr_last +rustix_syscall4_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + lw $2, 16($sp) + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall4_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall5_nr_last +rustix_syscall5_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + lw $2, 20($sp) + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall5_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall6_nr_last +rustix_syscall6_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + lw $2, 24($sp) + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .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 + .hidden rustix_syscall7_nr_last + .type rustix_syscall7_nr_last, @function + .set nomips16 + .set nomicromips + .ent rustix_syscall7_nr_last +rustix_syscall7_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + lw $2, 28($sp) + syscall + negu $8, $2 + jr $31 + movn $2, $8, $7 + .end rustix_syscall7_nr_last + .size rustix_syscall7_nr_last, .-rustix_syscall7_nr_last + + .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s new file mode 100644 index 000000000..3c5e76e36 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/mips64.s @@ -0,0 +1,189 @@ +# Assembly code for making mips64 syscalls. +# +# mips64 syscall argument register ordering is the same as the mips64 +# userspace argument register ordering except that the syscall number +# (nr) is passed in v0. +# +# 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" + .section .mdebug.abi64 + .previous + .abicalls + + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall0_nr_last +rustix_syscall0_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $4 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall0_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall1_nr_last +rustix_syscall1_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $5 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall1_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall1_noreturn_nr_last +rustix_syscall1_noreturn_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $5 + syscall + teq $0, $0 + .end rustix_syscall1_noreturn_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall2_nr_last +rustix_syscall2_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $6 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall2_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall3_nr_last +rustix_syscall3_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $7 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall3_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall4_nr_last +rustix_syscall4_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $8 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall4_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall5_nr_last +rustix_syscall5_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $9 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall5_nr_last + .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 + .set nomips16 + .set nomicromips + .ent rustix_syscall6_nr_last +rustix_syscall6_nr_last: + .frame $sp,0,$31 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .set nomacro + move $2, $10 + syscall + dnegu $12, $2 + jr $31 + movn $2, $12, $7 + .end rustix_syscall6_nr_last + .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/mod.rs b/vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs new file mode 100644 index 000000000..a6a5f270d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/mod.rs @@ -0,0 +1,33 @@ +//! Declare functions defined in out-of-line ("outline") asm files. +//! +//! Kernel calling conventions differ from userspace calling conventions, +//! so we also define inline function wrappers which reorder the arguments +//! so that they match with the kernel convention as closely as possible, +//! to minimize the amount of out-of-line code we need. + +#[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")] +pub(in crate::backend) use x86::*; diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/nr_last.rs b/vendor/rustix/src/backend/linux_raw/arch/outline/nr_last.rs new file mode 100644 index 000000000..4af64d6c4 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/nr_last.rs @@ -0,0 +1,166 @@ +//! Syscall wrappers for platforms which pass the syscall number specially. +//! +//! Rustix aims to minimize the amount of assembly code it needs. To that end, +//! this code reorders syscall arguments as close as feasible to the actual +//! syscall convention before calling the assembly functions. +//! +//! Many architectures use a convention where the syscall number is passed in a +//! special register, with the regular syscall arguments passed in either the +//! same or similar registers as the platform C convention. This code +//! approximates that order by passing the regular syscall arguments first, and +//! the syscall number last. That way, the outline assembly code typically just +//! needs to move the syscall number to its special register, and leave the +//! other arguments mostly as they are. + +#[cfg(target_arch = "mips")] +use crate::backend::reg::A6; +use crate::backend::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; + +// First we declare the actual assembly routines with `*_nr_last` names and +// reordered arguments. If the signatures or calling conventions are ever +// changed, the symbol names should also be updated accordingly, to avoid +// collisions with other versions of this crate. +// +// We don't define `_readonly` versions of these because we have no way to tell +// Rust that calls to our outline assembly are readonly. +extern "C" { + fn rustix_syscall0_nr_last(nr: SyscallNumber<'_>) -> RetReg; + fn rustix_syscall1_nr_last(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> RetReg; + fn rustix_syscall1_noreturn_nr_last(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> !; + fn rustix_syscall2_nr_last( + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall3_nr_last( + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall4_nr_last( + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall5_nr_last( + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall6_nr_last( + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + nr: SyscallNumber<'_>, + ) -> RetReg; + #[cfg(target_arch = "mips")] + fn rustix_syscall7_nr_last( + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + a6: ArgReg<'_, A6>, + nr: SyscallNumber<'_>, + ) -> RetReg; +} + +// Then we define inline wrapper functions that do the reordering. + +#[inline] +pub(in crate::backend) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { + rustix_syscall0_nr_last(nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + rustix_syscall1_nr_last(a0, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + rustix_syscall1_noreturn_nr_last(a0, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + rustix_syscall2_nr_last(a0, a1, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + rustix_syscall3_nr_last(a0, a1, a2, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + rustix_syscall4_nr_last(a0, a1, a2, a3, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + rustix_syscall5_nr_last(a0, a1, a2, a3, a4, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + rustix_syscall6_nr_last(a0, a1, a2, a3, a4, a5, nr) +} +#[cfg(target_arch = "mips")] +#[inline] +pub(in crate::backend) unsafe fn syscall7( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + a6: ArgReg<'_, A6>, +) -> RetReg { + rustix_syscall7_nr_last(a0, a1, a2, a3, a4, a5, a6, nr) +} + +// Then we define the `_readonly` versions of the wrappers. We don't have +// separate `_readonly` implementations, so these can just be aliases to +// their non-`_readonly` counterparts. +#[cfg(target_arch = "mips")] +pub(in crate::backend) use syscall7 as syscall7_readonly; +pub(in crate::backend) use { + syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly, + syscall3 as syscall3_readonly, syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, + syscall6 as syscall6_readonly, +}; diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/powerpc64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/powerpc64.s new file mode 100644 index 000000000..29d4c0a95 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/powerpc64.s @@ -0,0 +1,132 @@ +# Assembly code for making powerpc64le syscalls. +# +# powerpc64le syscall argument register ordering is the same as the +# powerpc64le userspace argument register ordering except that the syscall +# number (nr) is passed in r0. +# +# outline.rs takes care of reordering the nr argument to the end for us, +# so we only need to move nr into r0. + + .file "powerpc64le.s" + .machine power8 + .abiversion 2 + + .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 + mr 0, 3 + sc + bnslr + neg 3, 3 + blr + .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 + mr 0, 4 + sc + bnslr + neg 3, 3 + blr + .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 + mr 0, 4 + sc + trap + .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 + mr 0, 5 + sc + bnslr + neg 3, 3 + blr + .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 + mr 0, 6 + sc + bnslr + neg 3, 3 + blr + .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 + mr 0, 7 + sc + bnslr + neg 3, 3 + blr + .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 + mr 0, 8 + sc + bnslr + neg 3, 3 + blr + .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 + mr 0, 9 + sc + bnslr + neg 3, 3 + blr + .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/riscv64.s b/vendor/rustix/src/backend/linux_raw/arch/outline/riscv64.s new file mode 100644 index 000000000..28d692f7c --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/riscv64.s @@ -0,0 +1,116 @@ +# 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.rs b/vendor/rustix/src/backend/linux_raw/arch/outline/x86.rs new file mode 100644 index 000000000..e74b8d2aa --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/x86.rs @@ -0,0 +1,285 @@ +//! Syscall wrappers for 32-bit x86. +//! +//! This module is similar to the `nr_last` module, except specialized for +//! 32-bit x86. +//! +//! The syscall convention passes all arguments in registers. The closest we +//! can easily get to that from Rust is to use the fastcall convention which +//! passes the first two arguments in `ecx` and `edx`, which are the second +//! and third Linux syscall arguments. To line them up, this function passes +//! the second and third syscall argument as the first and second argument to +//! the outline assembly, followed by the first syscall argument, and then the +//! rest of the syscall arguments. The assembly code still has to do some work, +//! but at least we can get up to two arguments into the right place for it. + +#![allow(dead_code, unused_imports)] + +use crate::backend::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; +use crate::backend::vdso_wrappers::SyscallType; + +// First we declare the actual assembly routines with `*_nr_last_fastcall` +// names and reordered arguments. If the signatures or calling conventions are +// ever changed, the symbol names should also be updated accordingly, to avoid +// collisions with other versions of this crate. +// +// We don't define `_readonly` versions of these because we have no way to tell +// Rust that calls to our outline assembly are readonly. +extern "fastcall" { + fn rustix_syscall0_nr_last_fastcall(nr: SyscallNumber<'_>) -> RetReg; + fn rustix_syscall1_nr_last_fastcall(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> RetReg; + fn rustix_syscall1_noreturn_nr_last_fastcall(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> !; + fn rustix_syscall2_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall3_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall4_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall5_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + nr: SyscallNumber<'_>, + ) -> RetReg; + fn rustix_syscall6_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + nr: SyscallNumber<'_>, + ) -> RetReg; +} + +// Then we define inline wrapper functions that do the reordering. + +#[inline] +pub(in crate::backend) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { + rustix_syscall0_nr_last_fastcall(nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + rustix_syscall1_nr_last_fastcall(a0, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + rustix_syscall1_noreturn_nr_last_fastcall(a0, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + rustix_syscall2_nr_last_fastcall(a1, a0, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + rustix_syscall3_nr_last_fastcall(a1, a2, a0, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + rustix_syscall4_nr_last_fastcall(a1, a2, a0, a3, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + rustix_syscall5_nr_last_fastcall(a1, a2, a0, a3, a4, nr) +} +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + rustix_syscall6_nr_last_fastcall(a1, a2, a0, a3, a4, a5, nr) +} + +// Then we define the `_readonly` versions of the wrappers. We don't have +// separate `_readonly` implementations, so these can just be aliases to +// their non-`_readonly` counterparts. +pub(in crate::backend) use { + syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly, + syscall3 as syscall3_readonly, syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, + syscall6 as syscall6_readonly, +}; + +// x86 prefers to route all syscalls through the vDSO, though this isn't +// always possible, so it also has a special form for doing the dispatch. +// +// First we declare the actual assembly routines with `*_nr_last_fastcall` +// names and reordered arguments. If the signatures or calling conventions are +// ever changed, the symbol names should also be updated accordingly, to avoid +// collisions with other versions of this crate. +extern "fastcall" { + fn rustix_indirect_syscall0_nr_last_fastcall( + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall1_nr_last_fastcall( + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall1_noreturn_nr_last_fastcall( + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> !; + fn rustix_indirect_syscall2_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall3_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall4_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall5_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; + fn rustix_indirect_syscall6_nr_last_fastcall( + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a0: ArgReg<'_, A0>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, + nr: SyscallNumber<'_>, + callee: SyscallType, + ) -> RetReg; +} + +// Then we define inline wrapper functions that do the reordering. + +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall0( + callee: SyscallType, + nr: SyscallNumber<'_>, +) -> RetReg { + rustix_indirect_syscall0_nr_last_fastcall(nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall1( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + rustix_indirect_syscall1_nr_last_fastcall(a0, nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall1_noreturn( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> ! { + rustix_indirect_syscall1_noreturn_nr_last_fastcall(a0, nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall2( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + rustix_indirect_syscall2_nr_last_fastcall(a1, a0, nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall3( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + rustix_indirect_syscall3_nr_last_fastcall(a1, a2, a0, nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall4( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + rustix_indirect_syscall4_nr_last_fastcall(a1, a2, a0, a3, nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall5( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + rustix_indirect_syscall5_nr_last_fastcall(a1, a2, a0, a3, a4, nr, callee) +} +#[inline] +pub(in crate::backend) unsafe fn indirect_syscall6( + callee: SyscallType, + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + rustix_indirect_syscall6_nr_last_fastcall(a1, a2, a0, a3, a4, a5, nr, callee) +} diff --git a/vendor/rustix/src/backend/linux_raw/arch/outline/x86.s b/vendor/rustix/src/backend/linux_raw/arch/outline/x86.s new file mode 100644 index 000000000..bda234e1a --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/x86.s @@ -0,0 +1,381 @@ +// Assembly code for making x86 syscalls. +// +// On x86 we use the "fastcall" convention which passes the first two +// arguments in ecx and edx. Outline.rs reorders the arguments to put +// a1 and a2 in those registers so they we don't have to move them to +// set up the kernel convention. +// +// "fastcall" expects callee to pop argument stack space, so we use +// `ret imm` instructions to clean up the stack. We don't need callee +// cleanup per se, it just comes along with using "fastcall". + + .file "x86.s" + .intel_syntax noprefix + + .section .text.rustix_indirect_syscall0_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall0_nr_last_fastcall + .hidden rustix_indirect_syscall0_nr_last_fastcall + .type rustix_indirect_syscall0_nr_last_fastcall, @function +rustix_indirect_syscall0_nr_last_fastcall: + .cfi_startproc + mov eax,ecx + call edx + ret + .cfi_endproc + .size rustix_indirect_syscall0_nr_last_fastcall, .-rustix_indirect_syscall0_nr_last_fastcall + + .section .text.rustix_indirect_syscall1_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall1_nr_last_fastcall + .hidden rustix_indirect_syscall1_nr_last_fastcall + .type rustix_indirect_syscall1_nr_last_fastcall, @function +rustix_indirect_syscall1_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + .cfi_offset ebx, -8 + mov ebx,ecx + mov eax,edx + call DWORD PTR [esp+0x8] + pop ebx + .cfi_def_cfa_offset 4 + ret 0x4 + .cfi_endproc + .size rustix_indirect_syscall1_nr_last_fastcall, .-rustix_indirect_syscall1_nr_last_fastcall + + .section .text.rustix_indirect_syscall1_noreturn_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall1_noreturn_nr_last_fastcall + .hidden rustix_indirect_syscall1_noreturn_nr_last_fastcall + .type rustix_indirect_syscall1_noreturn_nr_last_fastcall, @function +rustix_indirect_syscall1_noreturn_nr_last_fastcall: + .cfi_startproc + mov ebx,ecx + mov eax,edx + call DWORD PTR [esp+0x4] + ud2 + .cfi_endproc + .size rustix_indirect_syscall1_noreturn_nr_last_fastcall, .-rustix_indirect_syscall1_noreturn_nr_last_fastcall + + .section .text.rustix_indirect_syscall2_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall2_nr_last_fastcall + .hidden rustix_indirect_syscall2_nr_last_fastcall + .type rustix_indirect_syscall2_nr_last_fastcall, @function +rustix_indirect_syscall2_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + .cfi_offset ebx, -8 + mov ebx,edx + mov eax,DWORD PTR [esp+0x8] + call DWORD PTR [esp+0xc] + pop ebx + .cfi_def_cfa_offset 4 + ret 0x8 + .cfi_endproc + .size rustix_indirect_syscall2_nr_last_fastcall, .-rustix_indirect_syscall2_nr_last_fastcall + + .section .text.rustix_indirect_syscall3_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall3_nr_last_fastcall + .hidden rustix_indirect_syscall3_nr_last_fastcall + .type rustix_indirect_syscall3_nr_last_fastcall, @function +rustix_indirect_syscall3_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0x8] + mov eax,DWORD PTR [esp+0xc] + call DWORD PTR [esp+0x10] + pop ebx + .cfi_def_cfa_offset 4 + ret 0xc + .cfi_endproc + .size rustix_indirect_syscall3_nr_last_fastcall, .-rustix_indirect_syscall3_nr_last_fastcall + + .section .text.rustix_indirect_syscall4_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall4_nr_last_fastcall + .hidden rustix_indirect_syscall4_nr_last_fastcall + .type rustix_indirect_syscall4_nr_last_fastcall, @function +rustix_indirect_syscall4_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + push esi + .cfi_def_cfa_offset 12 + .cfi_offset esi, -12 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0xc] + mov esi,DWORD PTR [esp+0x10] + mov eax,DWORD PTR [esp+0x14] + call DWORD PTR [esp+0x18] + pop esi + .cfi_def_cfa_offset 8 + pop ebx + .cfi_def_cfa_offset 4 + ret 0x10 + .cfi_endproc + .size rustix_indirect_syscall4_nr_last_fastcall, .-rustix_indirect_syscall4_nr_last_fastcall + + .section .text.rustix_indirect_syscall5_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall5_nr_last_fastcall + .hidden rustix_indirect_syscall5_nr_last_fastcall + .type rustix_indirect_syscall5_nr_last_fastcall, @function +rustix_indirect_syscall5_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + push esi + .cfi_def_cfa_offset 12 + push edi + .cfi_def_cfa_offset 16 + .cfi_offset edi, -16 + .cfi_offset esi, -12 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0x10] + mov esi,DWORD PTR [esp+0x14] + mov edi,DWORD PTR [esp+0x18] + mov eax,DWORD PTR [esp+0x1c] + call DWORD PTR [esp+0x20] + pop edi + .cfi_def_cfa_offset 12 + pop esi + .cfi_def_cfa_offset 8 + pop ebx + .cfi_def_cfa_offset 4 + ret 0x14 + .cfi_endproc + .size rustix_indirect_syscall5_nr_last_fastcall, .-rustix_indirect_syscall5_nr_last_fastcall + + .section .text.rustix_indirect_syscall6_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_indirect_syscall6_nr_last_fastcall + .hidden rustix_indirect_syscall6_nr_last_fastcall + .type rustix_indirect_syscall6_nr_last_fastcall, @function +rustix_indirect_syscall6_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + push esi + .cfi_def_cfa_offset 12 + push edi + .cfi_def_cfa_offset 16 + push ebp + .cfi_def_cfa_offset 20 + .cfi_offset ebp, -20 + .cfi_offset edi, -16 + .cfi_offset esi, -12 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0x14] + mov esi,DWORD PTR [esp+0x18] + mov edi,DWORD PTR [esp+0x1c] + mov ebp,DWORD PTR [esp+0x20] + mov eax,DWORD PTR [esp+0x24] + call DWORD PTR [esp+0x28] + pop ebp + .cfi_def_cfa_offset 16 + pop edi + .cfi_def_cfa_offset 12 + pop esi + .cfi_def_cfa_offset 8 + pop ebx + .cfi_def_cfa_offset 4 + ret 0x18 + .cfi_endproc + .size rustix_indirect_syscall6_nr_last_fastcall, .-rustix_indirect_syscall6_nr_last_fastcall + + .section .text.rustix_syscall0_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall0_nr_last_fastcall + .hidden rustix_syscall0_nr_last_fastcall + .type rustix_syscall0_nr_last_fastcall, @function +rustix_syscall0_nr_last_fastcall: + .cfi_startproc + mov eax,ecx + int 0x80 + ret + .cfi_endproc + .size rustix_syscall0_nr_last_fastcall, .-rustix_syscall0_nr_last_fastcall + + .section .text.rustix_syscall1_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall1_nr_last_fastcall + .hidden rustix_syscall1_nr_last_fastcall + .type rustix_syscall1_nr_last_fastcall, @function +rustix_syscall1_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + .cfi_offset ebx, -8 + mov eax,edx + mov ebx,ecx + int 0x80 + pop ebx + .cfi_def_cfa_offset 4 + ret + .cfi_endproc + .size rustix_syscall1_nr_last_fastcall, .-rustix_syscall1_nr_last_fastcall + + .section .text.rustix_syscall1_noreturn_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall1_noreturn_nr_last_fastcall + .hidden rustix_syscall1_noreturn_nr_last_fastcall + .type rustix_syscall1_noreturn_nr_last_fastcall, @function +rustix_syscall1_noreturn_nr_last_fastcall: + .cfi_startproc + mov eax,edx + mov ebx,ecx + int 0x80 + ud2 + .cfi_endproc + .size rustix_syscall1_noreturn_nr_last_fastcall, .-rustix_syscall1_noreturn_nr_last_fastcall + + .section .text.rustix_syscall2_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall2_nr_last_fastcall + .hidden rustix_syscall2_nr_last_fastcall + .type rustix_syscall2_nr_last_fastcall, @function +rustix_syscall2_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + .cfi_offset ebx, -8 + mov ebx,edx + mov eax,DWORD PTR [esp+0x8] + int 0x80 + pop ebx + .cfi_def_cfa_offset 4 + ret 0x4 + .cfi_endproc + .size rustix_syscall2_nr_last_fastcall, .-rustix_syscall2_nr_last_fastcall + + .section .text.rustix_syscall3_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall3_nr_last_fastcall + .hidden rustix_syscall3_nr_last_fastcall + .type rustix_syscall3_nr_last_fastcall, @function +rustix_syscall3_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0x8] + mov eax,DWORD PTR [esp+0xc] + int 0x80 + pop ebx + .cfi_def_cfa_offset 4 + ret 0x8 + .cfi_endproc + .size rustix_syscall3_nr_last_fastcall, .-rustix_syscall3_nr_last_fastcall + + .section .text.rustix_syscall4_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall4_nr_last_fastcall + .hidden rustix_syscall4_nr_last_fastcall + .type rustix_syscall4_nr_last_fastcall, @function +rustix_syscall4_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + push esi + .cfi_def_cfa_offset 12 + .cfi_offset esi, -12 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0xc] + mov esi,DWORD PTR [esp+0x10] + mov eax,DWORD PTR [esp+0x14] + int 0x80 + pop esi + .cfi_def_cfa_offset 8 + pop ebx + .cfi_def_cfa_offset 4 + ret 0xc + .cfi_endproc + .size rustix_syscall4_nr_last_fastcall, .-rustix_syscall4_nr_last_fastcall + + .section .text.rustix_syscall5_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall5_nr_last_fastcall + .hidden rustix_syscall5_nr_last_fastcall + .type rustix_syscall5_nr_last_fastcall, @function +rustix_syscall5_nr_last_fastcall: + .cfi_startproc + push ebx + .cfi_def_cfa_offset 8 + push edi + .cfi_def_cfa_offset 12 + push esi + .cfi_def_cfa_offset 16 + .cfi_offset esi, -16 + .cfi_offset edi, -12 + .cfi_offset ebx, -8 + mov ebx,DWORD PTR [esp+0x10] + mov esi,DWORD PTR [esp+0x14] + mov edi,DWORD PTR [esp+0x18] + mov eax,DWORD PTR [esp+0x1c] + int 0x80 + pop esi + .cfi_def_cfa_offset 12 + pop edi + .cfi_def_cfa_offset 8 + pop ebx + .cfi_def_cfa_offset 4 + ret 0x10 + .cfi_endproc + .size rustix_syscall5_nr_last_fastcall, .-rustix_syscall5_nr_last_fastcall + + .section .text.rustix_syscall6_nr_last_fastcall,"ax",@progbits + .p2align 4 + .weak rustix_syscall6_nr_last_fastcall + .hidden rustix_syscall6_nr_last_fastcall + .type rustix_syscall6_nr_last_fastcall, @function +rustix_syscall6_nr_last_fastcall: + .cfi_startproc + push ebp + .cfi_def_cfa_offset 8 + push ebx + .cfi_def_cfa_offset 12 + push edi + .cfi_def_cfa_offset 16 + push esi + .cfi_def_cfa_offset 20 + .cfi_offset esi, -20 + .cfi_offset edi, -16 + .cfi_offset ebx, -12 + .cfi_offset ebp, -8 + mov ebx,DWORD PTR [esp+0x14] + mov esi,DWORD PTR [esp+0x18] + mov edi,DWORD PTR [esp+0x1c] + mov ebp,DWORD PTR [esp+0x20] + mov eax,DWORD PTR [esp+0x24] + int 0x80 + pop esi + .cfi_def_cfa_offset 16 + pop edi + .cfi_def_cfa_offset 12 + pop ebx + .cfi_def_cfa_offset 8 + pop ebp + .cfi_def_cfa_offset 4 + ret 0x14 + .cfi_endproc + .size rustix_syscall6_nr_last_fastcall, .-rustix_syscall6_nr_last_fastcall + + .section .text.rustix_int_0x80,"ax",@progbits + .p2align 4 + .weak rustix_int_0x80 + .hidden rustix_int_0x80 + .type rustix_int_0x80, @function +rustix_int_0x80: + .cfi_startproc + int 0x80 + ret + .cfi_endproc + .size rustix_int_0x80, .-rustix_int_0x80 + + .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 new file mode 100644 index 000000000..2beda323b --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/arch/outline/x86_64.s @@ -0,0 +1,122 @@ +// 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 new file mode 100644 index 000000000..a6f0b8ff6 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/c.rs @@ -0,0 +1,29 @@ +//! Adapt the Linux API to resemble a POSIX-style libc API. +//! +//! The linux_raw backend doesn't use actual libc; this just defines certain +//! types that are convenient to have defined. + +#![allow(unused_imports)] + +pub(crate) use linux_raw_sys::ctypes::*; +pub(crate) use linux_raw_sys::errno::EINVAL; +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, 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_LOOP, 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, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, + SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_LINGER, + SO_PASSCRED, SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD, + SO_TYPE, TCP_NODELAY, +}; diff --git a/vendor/rustix/src/backend/linux_raw/conv.rs b/vendor/rustix/src/backend/linux_raw/conv.rs new file mode 100644 index 000000000..7e09cdf80 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/conv.rs @@ -0,0 +1,790 @@ +//! Convert values to [`ArgReg`] and from [`RetReg`]. +//! +//! System call arguments and return values are all communicated with inline +//! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping +//! or being accidentally misused as they travel through the code, we wrap +//! them in [`ArgReg`] and [`RetReg`] structs. This file provides `From` +//! implementations and explicit conversion functions for converting values +//! into and out of these wrapper structs. +//! +//! # Safety +//! +//! Some of this code is `unsafe` in order to work with raw file descriptors, +//! and some is `unsafe` to interpret the values in a `RetReg`. +#![allow(unsafe_code)] + +use super::c; +use super::fd::{AsRawFd, BorrowedFd, FromRawFd, RawFd}; +#[cfg(not(debug_assertions))] +use super::io::errno::decode_usize_infallible; +#[cfg(feature = "runtime")] +use super::io::errno::try_decode_error; +#[cfg(target_pointer_width = "64")] +use super::io::errno::try_decode_u64; +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; +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}; +use crate::utils::{as_mut_ptr, as_ptr}; +use core::mem::MaybeUninit; +use core::ptr::null_mut; +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +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; + +/// Convert `SYS_*` constants for socketcall. +#[cfg(target_arch = "x86")] +#[inline] +pub(super) fn x86_sys<'a, Num: ArgNumber>(sys: u32) -> ArgReg<'a, Num> { + pass_usize(sys as usize) +} + +/// Pass the "low" half of the endian-specific memory encoding of a `u64`, for +/// 32-bit architectures. +#[cfg(target_pointer_width = "32")] +#[inline] +pub(super) fn lo<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> { + #[cfg(target_endian = "little")] + let x = x >> 32; + #[cfg(target_endian = "big")] + let x = x & 0xffff_ffff; + + pass_usize(x as usize) +} + +/// Pass the "high" half of the endian-specific memory encoding of a `u64`, for +/// 32-bit architectures. +#[cfg(target_pointer_width = "32")] +#[inline] +pub(super) fn hi<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> { + #[cfg(target_endian = "little")] + let x = x & 0xffff_ffff; + #[cfg(target_endian = "big")] + let x = x >> 32; + + pass_usize(x as usize) +} + +/// Pass a zero, or null, argument. +#[inline] +pub(super) fn zero<'a, Num: ArgNumber>() -> ArgReg<'a, Num> { + raw_arg(null_mut()) +} + +/// Pass the `mem::size_of` of a type. +#[inline] +pub(super) fn size_of<'a, T: Sized, Num: ArgNumber>() -> ArgReg<'a, Num> { + pass_usize(core::mem::size_of::()) +} + +/// Pass an arbitrary `usize` value. +/// +/// For passing pointers, use `void_star` or other functions which take a raw +/// pointer instead of casting to `usize`, so that provenance is preserved. +#[inline] +pub(super) fn pass_usize<'a, Num: ArgNumber>(t: usize) -> ArgReg<'a, Num> { + raw_arg(t as *mut _) +} + +impl<'a, Num: ArgNumber, T> From<*mut T> for ArgReg<'a, Num> { + #[inline] + fn from(c: *mut T) -> ArgReg<'a, Num> { + raw_arg(c.cast()) + } +} + +impl<'a, Num: ArgNumber, T> From<*const T> for ArgReg<'a, Num> { + #[inline] + fn from(c: *const T) -> ArgReg<'a, Num> { + let mut_ptr = c as *mut T; + raw_arg(mut_ptr.cast()) + } +} + +impl<'a, Num: ArgNumber> From<&'a CStr> for ArgReg<'a, Num> { + #[inline] + fn from(c: &'a CStr) -> Self { + let mut_ptr = c.as_ptr() as *mut u8; + raw_arg(mut_ptr.cast()) + } +} + +impl<'a, Num: ArgNumber> From> for ArgReg<'a, Num> { + #[inline] + fn from(t: Option<&'a CStr>) -> Self { + raw_arg(match t { + Some(s) => { + let mut_ptr = s.as_ptr() as *mut u8; + mut_ptr.cast() + } + None => null_mut(), + }) + } +} + +/// Pass a borrowed file-descriptor argument. +impl<'a, Num: ArgNumber> From> 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. + unsafe { raw_fd(fd.as_raw_fd()) } + } +} + +/// Pass a raw file-descriptor argument. Most users should use [`ArgReg::from`] +/// instead, to preserve I/O safety as long as possible. +/// +/// # Safety +/// +/// `fd` must be a valid open file descriptor. +#[inline] +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); + + // Don't pass the `io_uring_register_files_skip` sentry value this way. + #[cfg(feature = "io_uring")] + debug_assert_ne!( + fd, + crate::io_uring::io_uring_register_files_skip().as_raw_fd() + ); + + // Linux doesn't look at the high bits beyond the `c_int`, so use + // zero-extension rather than sign-extension because it's a smaller + // instruction. + let fd: c::c_int = fd; + pass_usize(fd as c::c_uint as usize) +} + +/// Deliberately pass `-1` to a file-descriptor argument, for system calls +/// like `mmap` where this indicates the argument is omitted. +#[inline] +pub(super) fn no_fd<'a, Num: ArgNumber>() -> ArgReg<'a, Num> { + pass_usize(!0_usize) +} + +#[inline] +pub(super) fn slice_just_addr(v: &[T]) -> ArgReg { + let mut_ptr = v.as_ptr() as *mut T; + raw_arg(mut_ptr.cast()) +} + +#[inline] +pub(super) fn slice( + v: &[T], +) -> (ArgReg, ArgReg) { + (slice_just_addr(v), pass_usize(v.len())) +} + +#[inline] +pub(super) fn slice_mut( + v: &mut [T], +) -> (ArgReg, ArgReg) { + (raw_arg(v.as_mut_ptr().cast()), pass_usize(v.len())) +} + +#[inline] +pub(super) fn by_ref(t: &T) -> ArgReg { + let mut_ptr = as_ptr(t) as *mut T; + raw_arg(mut_ptr.cast()) +} + +#[inline] +pub(super) fn by_mut(t: &mut T) -> ArgReg { + raw_arg(as_mut_ptr(t).cast()) +} + +/// Convert an optional mutable reference into a `usize` for passing to a +/// syscall. +#[inline] +pub(super) fn opt_mut(t: Option<&mut T>) -> ArgReg { + // This optimizes into the equivalent of `transmute(t)`, and has the + // advantage of not requiring `unsafe`. + match t { + Some(t) => by_mut(t), + None => raw_arg(null_mut()), + } +} + +/// Convert an optional immutable reference into a `usize` for passing to a +/// syscall. +#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] +#[inline] +pub(super) fn opt_ref(t: Option<&T>) -> ArgReg { + // This optimizes into the equivalent of `transmute(t)`, and has the + // advantage of not requiring `unsafe`. + match t { + Some(t) => by_ref(t), + None => raw_arg(null_mut()), + } +} + +/// Convert a `c_int` into an `ArgReg`. +/// +/// Be sure to use `raw_fd` to pass `RawFd` values. +#[inline] +pub(super) fn c_int<'a, Num: ArgNumber>(i: c::c_int) -> ArgReg<'a, Num> { + pass_usize(i as usize) +} + +/// Convert a `c_uint` into an `ArgReg`. +#[inline] +pub(super) fn c_uint<'a, Num: ArgNumber>(i: c::c_uint) -> ArgReg<'a, Num> { + pass_usize(i as usize) +} + +#[cfg(target_pointer_width = "64")] +#[inline] +pub(super) fn loff_t<'a, Num: ArgNumber>(i: __kernel_loff_t) -> ArgReg<'a, Num> { + pass_usize(i as usize) +} + +#[cfg(target_pointer_width = "64")] +#[inline] +pub(super) fn loff_t_from_u64<'a, Num: ArgNumber>(i: u64) -> ArgReg<'a, Num> { + // `loff_t` is signed, but syscalls which expect `loff_t` return `EINVAL` + // if it's outside the signed `i64` range, so we can silently cast. + pass_usize(i as usize) +} + +#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(i: ClockId) -> Self { + pass_usize(i as __kernel_clockid_t as usize) + } +} + +#[cfg(feature = "time")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(i: TimerfdClockId) -> Self { + pass_usize(i as __kernel_clockid_t as usize) + } +} + +#[cfg(feature = "net")] +#[inline] +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 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) + } +} + +#[cfg(feature = "fs")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::AtFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "fs")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::MemfdFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "fs")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::RenameFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "fs")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::StatxFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io::FdFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io::PipeFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io::DupFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io::ReadWriteFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io::EventfdFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io::epoll::CreateFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::ProtFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MsyncFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MremapFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MlockFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MapFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::MprotectFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "mm")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::backend::mm::types::UserfaultfdFlags) -> Self { + c_uint(flags.bits()) + } +} + +impl<'a, Num: ArgNumber> From + for ArgReg<'a, Num> +{ + #[inline] + fn from(cmd: crate::backend::process::types::MembarrierCommand) -> Self { + c_uint(cmd as u32) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(cpuid: crate::process::Cpuid) -> Self { + c_uint(cpuid.as_raw()) + } +} + +#[cfg(target_pointer_width = "64")] +#[inline] +pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> ArgReg<'a, Num> { + pass_usize(dev as usize) +} + +#[cfg(target_pointer_width = "32")] +#[inline] +pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> io::Result> { + 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 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 for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::fs::FallocateFlags) -> Self { + c_uint(flags.bits()) + } +} + +/// Convert a `Resource` into a syscall argument. +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(resource: Resource) -> Self { + c_uint(resource as c::c_uint) + } +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(pid: Pid) -> Self { + pass_usize(pid.as_raw_nonzero().get() as usize) + } +} + +#[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) +} + +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(sig: Signal) -> Self { + pass_usize(sig as usize) + } +} + +#[cfg(feature = "fs")] +impl<'a, Num: ArgNumber> From 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 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 for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::io_uring::IoringEnterFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "time")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::time::TimerfdFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "time")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::time::TimerfdTimerFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "rand")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::rand::GetRandomFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::net::RecvFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::net::SendFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(flags: crate::net::AcceptFlags) -> Self { + c_uint(flags.bits()) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(family: crate::net::AddressFamily) -> Self { + c_uint(family.0.into()) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From<(crate::net::SocketType, crate::net::SocketFlags)> + for ArgReg<'a, Num> +{ + #[inline] + fn from(pair: (crate::net::SocketType, crate::net::SocketFlags)) -> Self { + c_uint(pair.0 .0 | pair.1.bits()) + } +} + +#[cfg(feature = "thread")] +impl<'a, Num: ArgNumber> From<(crate::thread::FutexOperation, crate::thread::FutexFlags)> + for ArgReg<'a, Num> +{ + #[inline] + fn from(pair: (crate::thread::FutexOperation, crate::thread::FutexFlags)) -> Self { + c_uint(pair.0 as u32 | pair.1.bits()) + } +} + +#[cfg(feature = "fs")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(access: crate::fs::Access) -> Self { + c_uint(access.bits()) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(type_: crate::net::SocketType) -> Self { + c_uint(type_.0) + } +} + +#[cfg(feature = "net")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { + #[inline] + fn from(protocol: crate::net::Protocol) -> Self { + c_uint(protocol.0) + } +} + +impl<'a, Num: ArgNumber, T> From<&'a mut MaybeUninit> for ArgReg<'a, Num> { + #[inline] + fn from(t: &'a mut MaybeUninit) -> Self { + raw_arg(t.as_mut_ptr().cast()) + } +} + +/// Convert a `usize` returned from a syscall that effectively returns `()` on +/// success. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a syscall which +/// just returns 0 on success. +#[inline] +pub(super) unsafe fn ret(raw: RetReg) -> io::Result<()> { + try_decode_void(raw) +} + +/// Convert a `usize` returned from a syscall that doesn't return on success. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a syscall which +/// doesn't return on success. +#[cfg(feature = "runtime")] +#[inline] +pub(super) unsafe fn ret_error(raw: RetReg) -> io::Errno { + try_decode_error(raw) +} + +/// Convert a `usize` returned from a syscall that effectively always returns +/// `()`. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a syscall which +/// always returns `()`. +#[inline] +pub(super) unsafe fn ret_infallible(raw: RetReg) { + #[cfg(debug_assertions)] + { + try_decode_void(raw).unwrap() + } + #[cfg(not(debug_assertions))] + drop(raw); +} + +/// Convert a `usize` returned from a syscall that effectively returns a +/// `c_int` on success. +#[inline] +pub(super) fn ret_c_int(raw: RetReg) -> io::Result { + try_decode_c_int(raw) +} + +/// Convert a `usize` returned from a syscall that effectively returns a +/// `c_uint` on success. +#[inline] +pub(super) fn ret_c_uint(raw: RetReg) -> io::Result { + try_decode_c_uint(raw) +} + +/// Convert a `usize` returned from a syscall that effectively returns a `u64` +/// on success. +#[cfg(target_pointer_width = "64")] +#[inline] +pub(super) fn ret_u64(raw: RetReg) -> io::Result { + try_decode_u64(raw) +} + +/// Convert a `usize` returned from a syscall that effectively returns a +/// `usize` on success. +#[inline] +pub(super) fn ret_usize(raw: RetReg) -> io::Result { + try_decode_usize(raw) +} + +/// Convert a `usize` returned from a syscall that effectively always +/// returns a `usize`. +/// +/// # Safety +/// +/// This function must only be used with return values from infallible +/// syscalls. +#[inline] +pub(super) unsafe fn ret_usize_infallible(raw: RetReg) -> usize { + #[cfg(debug_assertions)] + { + try_decode_usize(raw).unwrap() + } + #[cfg(not(debug_assertions))] + { + decode_usize_infallible(raw) + } +} + +/// Convert a `usize` returned from a syscall that effectively returns an +/// `OwnedFd` on success. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a syscall which +/// returns an owned file descriptor. +#[inline] +pub(super) unsafe fn ret_owned_fd(raw: RetReg) -> io::Result { + let raw_fd = try_decode_raw_fd(raw)?; + Ok(crate::backend::fd::OwnedFd::from_raw_fd(raw_fd)) +} + +/// Convert the return value of `dup2` and `dup3`. +/// +/// When these functions succeed, they return the same value as their second +/// argument, so we don't construct a new `OwnedFd`. +/// +/// # Safety +/// +/// The caller must ensure that this is the return value of a syscall which +/// returns a file descriptor. +#[inline] +pub(super) unsafe fn ret_discarded_fd(raw: RetReg) -> io::Result<()> { + let _raw_fd = try_decode_raw_fd(raw)?; + Ok(()) +} + +/// Convert a `usize` returned from a syscall that effectively returns a +/// `*mut c_void` on success. +#[inline] +pub(super) fn ret_void_star(raw: RetReg) -> io::Result<*mut c::c_void> { + try_decode_void_star(raw) +} diff --git a/vendor/rustix/src/backend/linux_raw/elf.rs b/vendor/rustix/src/backend/linux_raw/elf.rs new file mode 100644 index 000000000..87fb5fa0f --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/elf.rs @@ -0,0 +1,176 @@ +//! The ELF ABI. + +#![allow(non_snake_case)] +#![cfg_attr( + all(not(target_vendor = "mustang"), feature = "use-libc-auxv"), + allow(dead_code) +)] + +pub(super) const SELFMAG: usize = 4; +pub(super) const ELFMAG: [u8; SELFMAG] = [0x7f, b'E', b'L', b'F']; +pub(super) const EI_CLASS: usize = 4; +pub(super) const EI_DATA: usize = 5; +pub(super) const EI_VERSION: usize = 6; +pub(super) const EI_OSABI: usize = 7; +pub(super) const EI_ABIVERSION: usize = 8; +pub(super) const EV_CURRENT: u8 = 1; +#[cfg(target_pointer_width = "32")] +pub(super) const ELFCLASS: u8 = 1; // ELFCLASS32 +#[cfg(target_pointer_width = "64")] +pub(super) const ELFCLASS: u8 = 2; // ELFCLASS64 +#[cfg(target_endian = "little")] +pub(super) const ELFDATA: u8 = 1; // ELFDATA2LSB +#[cfg(target_endian = "big")] +pub(super) const ELFDATA: u8 = 2; // ELFDATA2MSB +pub(super) const ELFOSABI_SYSV: u8 = 0; +pub(super) const ELFOSABI_LINUX: u8 = 3; +// At present all of our supported platforms use 0. +pub(super) const ELFABIVERSION: u8 = 0; +pub(super) const ET_DYN: u16 = 3; +pub(super) const EI_NIDENT: usize = 16; +pub(super) const SHN_UNDEF: u16 = 0; +pub(super) const SHN_ABS: u16 = 0xfff1; +pub(super) const PN_XNUM: u16 = 0xffff; +pub(super) const PT_LOAD: u32 = 1; +pub(super) const PT_DYNAMIC: u32 = 2; +pub(super) const PT_INTERP: u32 = 3; +pub(super) const PT_PHDR: u32 = 6; +pub(super) const PT_TLS: u32 = 7; +pub(super) const PT_GNU_STACK: u32 = 0x6474_e551; +pub(super) const PT_GNU_RELRO: u32 = 0x6474_e552; +pub(super) const PF_X: u32 = 1; +pub(super) const PF_W: u32 = 2; +pub(super) const PF_R: u32 = 4; +pub(super) const DT_NULL: i32 = 0; +pub(super) const DT_HASH: i32 = 4; +pub(super) const DT_STRTAB: i32 = 5; +pub(super) const DT_SYMTAB: i32 = 6; +pub(super) const DT_SYMENT: i32 = 11; +pub(super) const DT_VERSYM: i32 = 0x6fff_fff0; +pub(super) const DT_VERDEF: i32 = 0x6fff_fffc; +pub(super) const STB_WEAK: u8 = 2; +pub(super) const STB_GLOBAL: u8 = 1; +pub(super) const STT_NOTYPE: u8 = 0; +pub(super) const STT_FUNC: u8 = 2; +pub(super) const STN_UNDEF: u32 = 0; +pub(super) const VER_FLG_BASE: u16 = 0x1; +pub(super) const VER_DEF_CURRENT: u16 = 1; +pub(super) const STV_DEFAULT: u8 = 0; +#[cfg(target_arch = "arm")] +pub(super) const EM_CURRENT: u16 = 40; // EM_ARM +#[cfg(target_arch = "x86")] +pub(super) const EM_CURRENT: u16 = 3; // EM_386 +#[cfg(target_arch = "powerpc64")] +pub(super) const EM_CURRENT: u16 = 21; // EM_PPC64 +#[cfg(any(target_arch = "mips", target_arch = "mips64"))] +pub(super) const EM_CURRENT: u16 = 8; // EM_MIPS +#[cfg(target_arch = "x86_64")] +pub(super) const EM_CURRENT: u16 = 62; // EM_X86_64 +#[cfg(target_arch = "aarch64")] +pub(super) const EM_CURRENT: u16 = 183; // EM_AARCH64 +#[cfg(target_arch = "riscv64")] +pub(super) const EM_CURRENT: u16 = 243; // EM_RISCV + +#[inline] +pub(super) const fn ELF_ST_VISIBILITY(o: u8) -> u8 { + o & 0x03 +} + +#[inline] +pub(super) const fn ELF_ST_BIND(val: u8) -> u8 { + val >> 4 +} + +#[inline] +pub(super) const fn ELF_ST_TYPE(val: u8) -> u8 { + val & 0xf +} + +#[repr(C)] +pub(super) struct Elf_Ehdr { + pub(super) e_ident: [u8; EI_NIDENT], + pub(super) e_type: u16, + pub(super) e_machine: u16, + pub(super) e_version: u32, + pub(super) e_entry: usize, + pub(super) e_phoff: usize, + pub(super) e_shoff: usize, + pub(super) e_flags: u32, + pub(super) e_ehsize: u16, + pub(super) e_phentsize: u16, + pub(super) e_phnum: u16, + pub(super) e_shentsize: u16, + pub(super) e_shnum: u16, + pub(super) e_shstrndx: u16, +} + +#[cfg(target_pointer_width = "32")] +#[repr(C)] +pub(super) struct Elf_Phdr { + pub(super) p_type: u32, + pub(super) p_offset: usize, + pub(super) p_vaddr: usize, + pub(super) p_paddr: usize, + pub(super) p_filesz: usize, + pub(super) p_memsz: usize, + pub(super) p_flags: u32, + pub(super) p_align: usize, +} + +#[cfg(target_pointer_width = "64")] +#[repr(C)] +pub(super) struct Elf_Phdr { + pub(super) p_type: u32, + pub(super) p_flags: u32, + pub(super) p_offset: usize, + pub(super) p_vaddr: usize, + pub(super) p_paddr: usize, + pub(super) p_filesz: usize, + pub(super) p_memsz: usize, + pub(super) p_align: usize, +} + +#[cfg(target_pointer_width = "32")] +#[repr(C)] +pub(super) struct Elf_Sym { + pub(super) st_name: u32, + pub(super) st_value: usize, + pub(super) st_size: usize, + pub(super) st_info: u8, + pub(super) st_other: u8, + pub(super) st_shndx: u16, +} + +#[cfg(target_pointer_width = "64")] +#[repr(C)] +pub(super) struct Elf_Sym { + pub(super) st_name: u32, + pub(super) st_info: u8, + pub(super) st_other: u8, + pub(super) st_shndx: u16, + pub(super) st_value: usize, + pub(super) st_size: usize, +} + +#[repr(C)] +pub(super) struct Elf_Dyn { + pub(super) d_tag: i32, + pub(super) d_val: usize, +} + +#[repr(C)] +pub(super) struct Elf_Verdef { + pub(super) vd_version: u16, + pub(super) vd_flags: u16, + pub(super) vd_ndx: u16, + pub(super) vd_cnt: u16, + pub(super) vd_hash: u32, + pub(super) vd_aux: u32, + pub(super) vd_next: u32, +} + +#[repr(C)] +pub(super) struct Elf_Verdaux { + pub(super) vda_name: u32, + pub(super) _vda_next: u32, +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/dir.rs b/vendor/rustix/src/backend/linux_raw/fs/dir.rs new file mode 100644 index 000000000..cfa347d03 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/fs/dir.rs @@ -0,0 +1,225 @@ +use crate::fd::{AsFd, BorrowedFd, OwnedFd}; +use crate::ffi::{CStr, CString}; +use crate::fs::{ + fcntl_getfl, fstat, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, Stat, StatFs, StatVfs, +}; +use crate::io; +use crate::process::fchdir; +use crate::utils::as_ptr; +use alloc::borrow::ToOwned; +use alloc::vec::Vec; +use core::fmt; +use core::mem::size_of; +use linux_raw_sys::general::{linux_dirent64, SEEK_SET}; + +/// `DIR*` +pub struct Dir { + /// The `OwnedFd` that we read directory entries from. + fd: OwnedFd, + + buf: Vec, + pos: usize, + next: Option, +} + +impl Dir { + /// Construct a `Dir` that reads entries from the given directory + /// file descriptor. + #[inline] + pub fn read_from(fd: Fd) -> io::Result { + Self::_read_from(fd.as_fd()) + } + + #[inline] + fn _read_from(fd: BorrowedFd<'_>) -> io::Result { + let flags = fcntl_getfl(fd)?; + let fd_for_dir = openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; + + Ok(Self { + fd: fd_for_dir, + buf: Vec::new(), + pos: 0, + next: None, + }) + } + + /// `rewinddir(self)` + #[inline] + pub fn rewind(&mut self) { + self.pos = self.buf.len(); + self.next = Some(0); + } + + /// `readdir(self)`, where `None` means the end of the directory. + pub fn read(&mut self) -> Option> { + if let Some(next) = self.next.take() { + match crate::backend::fs::syscalls::_seek(self.fd.as_fd(), next as i64, SEEK_SET) { + Ok(_) => (), + Err(err) => return Some(Err(err)), + } + } + + // Compute linux_dirent64 field offsets. + let z = linux_dirent64 { + d_ino: 0_u64, + d_off: 0_i64, + d_type: 0_u8, + d_reclen: 0_u16, + d_name: Default::default(), + }; + let base = as_ptr(&z) as usize; + let offsetof_d_reclen = (as_ptr(&z.d_reclen) as usize) - base; + let offsetof_d_name = (as_ptr(&z.d_name) as usize) - base; + let offsetof_d_ino = (as_ptr(&z.d_ino) as usize) - base; + let offsetof_d_type = (as_ptr(&z.d_type) as usize) - base; + + // Test if we need more entries, and if so, read more. + if self.buf.len() - self.pos < size_of::() { + match self.read_more()? { + Ok(()) => (), + Err(e) => return Some(Err(e)), + } + } + + // We successfully read an entry. Extract the fields. + let pos = self.pos; + + // Do an unaligned u16 load. + let d_reclen = u16::from_ne_bytes([ + self.buf[pos + offsetof_d_reclen], + self.buf[pos + offsetof_d_reclen + 1], + ]); + assert!(self.buf.len() - pos >= d_reclen as usize); + self.pos += d_reclen as usize; + + // Read the NUL-terminated name from the `d_name` field. Without + // `unsafe`, we need to scan for the NUL twice: once to obtain a size + // for the slice, and then once within `CStr::from_bytes_with_nul`. + let name_start = pos + offsetof_d_name; + let name_len = self.buf[name_start..] + .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 = name.to_owned(); + assert!(name.as_bytes().len() <= self.buf.len() - name_start); + + // Do an unaligned u64 load. + let d_ino = u64::from_ne_bytes([ + self.buf[pos + offsetof_d_ino], + self.buf[pos + offsetof_d_ino + 1], + self.buf[pos + offsetof_d_ino + 2], + self.buf[pos + offsetof_d_ino + 3], + self.buf[pos + offsetof_d_ino + 4], + self.buf[pos + offsetof_d_ino + 5], + self.buf[pos + offsetof_d_ino + 6], + self.buf[pos + offsetof_d_ino + 7], + ]); + + let d_type = self.buf[pos + offsetof_d_type]; + + // Check that our types correspond to the `linux_dirent64` types. + let _ = linux_dirent64 { + d_ino, + d_off: 0, + d_type, + d_reclen, + d_name: Default::default(), + }; + + Some(Ok(DirEntry { + d_ino, + d_type, + name, + })) + } + + fn read_more(&mut self) -> Option> { + let og_len = self.buf.len(); + // Capacity increment currently chosen by wild guess. + self.buf + .resize(self.buf.capacity() + 32 * size_of::(), 0); + let nread = match crate::backend::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) { + Ok(nread) => nread, + Err(err) => { + self.buf.resize(og_len, 0); + return Some(Err(err)); + } + }; + self.buf.resize(nread, 0); + self.pos = 0; + if nread == 0 { + None + } else { + Some(Ok(())) + } + } + + /// `fstat(self)` + #[inline] + pub fn stat(&self) -> io::Result { + fstat(&self.fd) + } + + /// `fstatfs(self)` + #[inline] + pub fn statfs(&self) -> io::Result { + fstatfs(&self.fd) + } + + /// `fstatvfs(self)` + #[inline] + pub fn statvfs(&self) -> io::Result { + fstatvfs(&self.fd) + } + + /// `fchdir(self)` + #[inline] + pub fn chdir(&self) -> io::Result<()> { + fchdir(&self.fd) + } +} + +impl Iterator for Dir { + type Item = io::Result; + + #[inline] + fn next(&mut self) -> Option { + Self::read(self) + } +} + +impl fmt::Debug for Dir { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Dir").field("fd", &self.fd).finish() + } +} + +/// `struct dirent` +#[derive(Debug)] +pub struct DirEntry { + d_ino: u64, + d_type: u8, + name: CString, +} + +impl DirEntry { + /// Returns the file name of this directory entry. + #[inline] + pub fn file_name(&self) -> &CStr { + &self.name + } + + /// Returns the type of this directory entry. + #[inline] + pub fn file_type(&self) -> FileType { + FileType::from_dirent_d_type(self.d_type) + } + + /// Return the inode number of this directory entry. + #[inline] + pub fn ino(&self) -> u64 { + self.d_ino + } +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/makedev.rs b/vendor/rustix/src/backend/linux_raw/fs/makedev.rs new file mode 100644 index 000000000..284ba2f10 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/fs/makedev.rs @@ -0,0 +1,19 @@ +use crate::fs::Dev; + +#[inline] +pub(crate) fn makedev(maj: u32, min: u32) -> Dev { + ((u64::from(maj) & 0xffff_f000_u64) << 32) + | ((u64::from(maj) & 0x0000_0fff_u64) << 8) + | ((u64::from(min) & 0xffff_ff00_u64) << 12) + | (u64::from(min) & 0x0000_00ff_u64) +} + +#[inline] +pub(crate) fn major(dev: Dev) -> u32 { + (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 +} + +#[inline] +pub(crate) fn minor(dev: Dev) -> u32 { + (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/mod.rs b/vendor/rustix/src/backend/linux_raw/fs/mod.rs new file mode 100644 index 000000000..015c6baec --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/fs/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod dir; +pub(crate) mod makedev; +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs new file mode 100644 index 000000000..ff58f0a7b --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/fs/syscalls.rs @@ -0,0 +1,1384 @@ +//! linux_raw syscalls supporting `rustix::fs`. +//! +//! # Safety +//! +//! 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_owned_fd, ret_usize, size_of, slice_mut, zero, +}; +#[cfg(target_pointer_width = "64")] +use super::super::conv::{loff_t, loff_t_from_u64, ret_u64}; +#[cfg(any( + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "mips64", + target_pointer_width = "32", +))] +use crate::fd::AsFd; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::ffi::CStr; +use crate::fs::{ + Access, Advice, AtFlags, FallocateFlags, FileType, FlockOperation, MemfdFlags, Mode, OFlags, + RenameFlags, ResolveFlags, SealFlags, Stat, StatFs, StatVfs, StatVfsMountFlags, StatxFlags, + Timestamps, +}; +use crate::io::{self, SeekFrom}; +use crate::process::{Gid, Uid}; +use core::convert::TryInto; +use core::mem::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_END, SEEK_SET, STATX__RESERVED, +}; +#[cfg(target_pointer_width = "32")] +use { + super::super::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 { + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + { + openat(crate::fs::cwd().as_fd(), filename, flags, mode) + } + #[cfg(all( + target_pointer_width = "32", + 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)) + } +} + +#[inline] +pub(crate) fn openat( + dirfd: BorrowedFd<'_>, + filename: &CStr, + flags: OFlags, + mode: Mode, +) -> io::Result { + #[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)) + } +} + +#[inline] +pub(crate) fn openat2( + dirfd: BorrowedFd<'_>, + pathname: &CStr, + flags: OFlags, + mode: Mode, + resolve: ResolveFlags, +) -> io::Result { + #[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::() + )) + } + #[cfg(target_pointer_width = "64")] + 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::() + )) + } +} + +#[inline] +pub(crate) fn chmod(filename: &CStr, mode: Mode) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_fchmodat, + raw_fd(AT_FDCWD), + filename, + mode + )) + } +} + +#[inline] +pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, filename: &CStr, mode: Mode) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_fchmodat, dirfd, filename, mode)) } +} + +#[inline] +pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_fchmod, fd, mode)) } +} + +#[inline] +pub(crate) fn chownat( + dirfd: BorrowedFd<'_>, + filename: &CStr, + owner: Option, + group: Option, + flags: AtFlags, +) -> io::Result<()> { + unsafe { + let (ow, gr) = crate::process::translate_fchown_args(owner, group); + ret(syscall_readonly!( + __NR_fchownat, + dirfd, + filename, + c_uint(ow), + c_uint(gr), + flags + )) + } +} + +#[inline] +pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option, group: Option) -> io::Result<()> { + unsafe { + let (ow, gr) = crate::process::translate_fchown_args(owner, group); + ret(syscall_readonly!(__NR_fchown, fd, c_uint(ow), c_uint(gr))) + } +} + +#[inline] +pub(crate) fn mknodat( + dirfd: BorrowedFd<'_>, + filename: &CStr, + file_type: FileType, + mode: Mode, + dev: u64, +) -> io::Result<()> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!( + __NR_mknodat, + dirfd, + filename, + (mode, file_type), + dev_t(dev)? + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_mknodat, + dirfd, + filename, + (mode, file_type), + dev_t(dev) + )) + } +} + +#[inline] +pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { + let (whence, offset) = match pos { + SeekFrom::Start(pos) => { + let pos: u64 = pos; + // Silently cast; we'll get `EINVAL` if the value is negative. + (SEEK_SET, pos as i64) + } + SeekFrom::End(offset) => (SEEK_END, offset), + SeekFrom::Current(offset) => (SEEK_CUR, offset), + }; + _seek(fd, offset, whence) +} + +#[inline] +pub(crate) fn _seek(fd: BorrowedFd<'_>, offset: i64, whence: c::c_uint) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!( + __NR__llseek, + fd, + // Don't use the hi/lo functions here because Linux's llseek + // takes its 64-bit argument differently from everything else. + pass_usize((offset >> 32) as usize), + pass_usize(offset as usize), + &mut result, + c_uint(whence) + ))?; + Ok(result.assume_init()) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_u64(syscall_readonly!( + __NR_lseek, + fd, + loff_t(offset), + c_uint(whence) + )) + } +} + +#[inline] +pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result { + _seek(fd, 0, SEEK_CUR).map(|x| x as u64) +} + +#[inline] +pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { + // + #[cfg(all( + target_pointer_width = "32", + any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"), + ))] + unsafe { + ret(syscall_readonly!( + __NR_ftruncate64, + fd, + zero(), + hi(length), + lo(length) + )) + } + #[cfg(all( + target_pointer_width = "32", + not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")), + ))] + unsafe { + ret(syscall_readonly!( + __NR_ftruncate64, + fd, + hi(length), + lo(length) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_ftruncate, + fd, + loff_t_from_u64(length) + )) + } +} + +#[inline] +pub(crate) fn fallocate( + fd: BorrowedFd<'_>, + mode: FallocateFlags, + offset: u64, + len: u64, +) -> io::Result<()> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!( + __NR_fallocate, + fd, + mode, + hi(offset), + lo(offset), + hi(len), + lo(len) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_fallocate, + fd, + mode, + loff_t_from_u64(offset), + loff_t_from_u64(len) + )) + } +} + +#[inline] +pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> io::Result<()> { + // On ARM, the arguments are reordered so that the len and pos argument + // pairs are aligned. And ARM has a custom syscall code for this. + #[cfg(target_arch = "arm")] + unsafe { + ret(syscall_readonly!( + __NR_arm_fadvise64_64, + fd, + advice, + hi(pos), + lo(pos), + hi(len), + lo(len) + )) + } + + // On powerpc, the arguments are reordered as on ARM. + #[cfg(target_arch = "powerpc")] + unsafe { + ret(syscall_readonly!( + __NR_fadvise64_64, + fd, + advice, + hi(pos), + lo(pos), + hi(len), + lo(len) + )) + } + // On mips, the arguments are not reordered, and padding is inserted + // instead to ensure alignment. + #[cfg(target_arch = "mips")] + unsafe { + ret(syscall_readonly!( + __NR_fadvise64, + fd, + zero(), + hi(pos), + lo(pos), + hi(len), + lo(len), + advice + )) + } + #[cfg(all( + target_pointer_width = "32", + not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")), + ))] + unsafe { + ret(syscall_readonly!( + __NR_fadvise64_64, + fd, + hi(pos), + lo(pos), + hi(len), + lo(len), + advice + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_fadvise64, + fd, + loff_t_from_u64(pos), + loff_t_from_u64(len), + advice + )) + } +} + +#[inline] +pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_fsync, fd)) } +} + +#[inline] +pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_fdatasync, fd)) } +} + +#[inline] +pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { + unsafe { ret(syscall!(__NR_flock, fd, c_uint(operation as c::c_uint))) } +} + +#[inline] +pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { + #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] + { + match 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), + } + } + + #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!(__NR_fstat, fd, &mut result))?; + Ok(result.assume_init()) + } +} + +#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] +fn fstat_old(fd: BorrowedFd<'_>) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(target_arch = "mips64")] + unsafe { + ret(syscall!(__NR_fstat, fd, &mut result))?; + stat_to_stat(result.assume_init()) + } + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall!(__NR_fstat64, fd, &mut result))?; + stat_to_stat(result.assume_init()) + } +} + +#[inline] +pub(crate) fn stat(filename: &CStr) -> io::Result { + #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] + { + match statx( + crate::fs::cwd().as_fd(), + filename, + AtFlags::empty(), + StatxFlags::BASIC_STATS, + ) { + Ok(x) => statx_to_stat(x), + Err(io::Errno::NOSYS) => stat_old(filename), + Err(err) => Err(err), + } + } + + #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!( + __NR_newfstatat, + raw_fd(AT_FDCWD), + filename, + &mut result, + c_uint(0) + ))?; + Ok(result.assume_init()) + } +} + +#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] +fn stat_old(filename: &CStr) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(target_arch = "mips64")] + unsafe { + ret(syscall!( + __NR_newfstatat, + raw_fd(AT_FDCWD), + filename, + &mut result, + c_uint(0) + ))?; + stat_to_stat(result.assume_init()) + } + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall!( + __NR_fstatat64, + raw_fd(AT_FDCWD), + filename, + &mut result, + c_uint(0) + ))?; + stat_to_stat(result.assume_init()) + } +} + +#[inline] +pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result { + #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] + { + match statx(dirfd, filename, flags, StatxFlags::BASIC_STATS) { + Ok(x) => statx_to_stat(x), + Err(io::Errno::NOSYS) => statat_old(dirfd, filename, flags), + Err(err) => Err(err), + } + } + + #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!( + __NR_newfstatat, + dirfd, + filename, + &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 { + let mut result = MaybeUninit::::uninit(); + + #[cfg(target_arch = "mips64")] + unsafe { + ret(syscall!( + __NR_newfstatat, + dirfd, + filename, + &mut result, + flags + ))?; + stat_to_stat(result.assume_init()) + } + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall!( + __NR_fstatat64, + dirfd, + filename, + &mut result, + flags + ))?; + stat_to_stat(result.assume_init()) + } +} + +#[inline] +pub(crate) fn lstat(filename: &CStr) -> io::Result { + #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] + { + match statx( + crate::fs::cwd().as_fd(), + filename, + AtFlags::SYMLINK_NOFOLLOW, + StatxFlags::BASIC_STATS, + ) { + Ok(x) => statx_to_stat(x), + Err(io::Errno::NOSYS) => lstat_old(filename), + Err(err) => Err(err), + } + } + + #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!( + __NR_newfstatat, + raw_fd(AT_FDCWD), + filename, + &mut result, + c_uint(AT_SYMLINK_NOFOLLOW) + ))?; + Ok(result.assume_init()) + } +} + +#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] +fn lstat_old(filename: &CStr) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(target_arch = "mips64")] + unsafe { + ret(syscall!( + __NR_newfstatat, + raw_fd(AT_FDCWD), + filename, + &mut result, + c_uint(AT_SYMLINK_NOFOLLOW) + ))?; + stat_to_stat(result.assume_init()) + } + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall!( + __NR_fstatat64, + raw_fd(AT_FDCWD), + filename, + &mut result, + c_uint(AT_SYMLINK_NOFOLLOW) + ))?; + stat_to_stat(result.assume_init()) + } +} + +/// Convert from a Linux `statx` value to rustix's `Stat`. +#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] +fn statx_to_stat(x: crate::fs::Statx) -> io::Result { + Ok(Stat { + st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor), + st_mode: x.stx_mode.into(), + st_nlink: x.stx_nlink.into(), + st_uid: x.stx_uid.into(), + st_gid: x.stx_gid.into(), + st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor), + st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blksize: x.stx_blksize.into(), + st_blocks: x.stx_blocks.into(), + st_atime: x + .stx_atime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_atime_nsec: x.stx_atime.tv_nsec.into(), + st_mtime: x + .stx_mtime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_mtime_nsec: x.stx_mtime.tv_nsec.into(), + st_ctime: x + .stx_ctime + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ctime_nsec: x.stx_ctime.tv_nsec.into(), + st_ino: x.stx_ino.into(), + }) +} + +/// Convert from a Linux `stat64` value to rustix's `Stat`. +#[cfg(target_pointer_width = "32")] +fn stat_to_stat(s64: linux_raw_sys::general::stat64) -> io::Result { + Ok(Stat { + st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_atime: s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_atime_nsec: s64 + .st_atime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_mtime: s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_mtime_nsec: s64 + .st_mtime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ctime: s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_ctime_nsec: s64 + .st_ctime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, + }) +} + +/// Convert from a Linux `stat` value to rustix's `Stat`. +#[cfg(target_arch = "mips64")] +fn stat_to_stat(s: linux_raw_sys::general::stat) -> io::Result { + Ok(Stat { + st_dev: s.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_mode: s.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_nlink: s.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_uid: s.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_gid: s.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_rdev: s.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_size: s.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blksize: s.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_blocks: s.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_atime: s.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_atime_nsec: s + .st_atime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_mtime: s.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_mtime_nsec: s + .st_mtime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ctime: s.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, + st_ctime_nsec: s + .st_ctime_nsec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + st_ino: s.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, + }) +} + +#[inline] +pub(crate) fn statx( + dirfd: BorrowedFd<'_>, + pathname: &CStr, + flags: AtFlags, + mask: StatxFlags, +) -> io::Result { + // If a future Linux kernel adds more fields to `struct statx` and users + // passing flags unknown to rustix in `StatxFlags`, we could end up + // writing outside of the buffer. To prevent this possibility, we mask off + // any flags that we don't know about. + // + // This includes `STATX__RESERVED`, which has a value that we know, but + // which could take on arbitrary new meaning in the future. Linux currently + // rejects this flag with `EINVAL`, so we do the same. + // + // This doesn't rely on `STATX_ALL` because [it's deprecated] and already + // doesn't represent all the known flags. + // + // [it's deprecated]: https://patchwork.kernel.org/project/linux-fsdevel/patch/20200505095915.11275-7-mszeredi@redhat.com/ + if (mask.bits() & STATX__RESERVED) == STATX__RESERVED { + return Err(io::Errno::INVAL); + } + let mask = mask & StatxFlags::all(); + + unsafe { + let mut statx_buf = MaybeUninit::::uninit(); + ret(syscall!( + __NR_statx, + dirfd, + pathname, + flags, + mask, + &mut statx_buf + ))?; + Ok(statx_buf.assume_init()) + } +} + +#[inline] +pub(crate) fn is_statx_available() -> bool { + unsafe { + // Call `statx` with null pointers so that if it fails for any reason + // other than `EFAULT`, we know it's not supported. + matches!( + ret(syscall!( + __NR_statx, + raw_fd(AT_FDCWD), + zero(), + zero(), + zero(), + zero() + )), + Err(io::Errno::FAULT) + ) + } +} + +#[inline] +pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!( + __NR_fstatfs64, + fd, + size_of::(), + &mut result + ))?; + Ok(result.assume_init()) + } + + #[cfg(target_pointer_width = "64")] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!(__NR_fstatfs, fd, &mut result))?; + Ok(result.assume_init()) + } +} + +#[inline] +pub(crate) fn fstatvfs(fd: BorrowedFd<'_>) -> io::Result { + // Linux doesn't have an `fstatvfs` syscall; we have to do `fstatfs` and + // translate the fields as best we can. + let statfs = fstatfs(fd)?; + + Ok(statfs_to_statvfs(statfs)) +} + +#[inline] +pub(crate) fn statfs(filename: &CStr) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!( + __NR_statfs64, + filename, + size_of::(), + &mut result + ))?; + Ok(result.assume_init()) + } + #[cfg(target_pointer_width = "64")] + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!(__NR_statfs, filename, &mut result))?; + Ok(result.assume_init()) + } +} + +#[inline] +pub(crate) fn statvfs(filename: &CStr) -> io::Result { + // Linux doesn't have a `statvfs` syscall; we have to do `statfs` and + // translate the fields as best we can. + let statfs = statfs(filename)?; + + Ok(statfs_to_statvfs(statfs)) +} + +fn statfs_to_statvfs(statfs: StatFs) -> StatVfs { + let __kernel_fsid_t { val } = statfs.f_fsid; + let [f_fsid_val0, f_fsid_val1]: [i32; 2] = val; + + StatVfs { + f_bsize: statfs.f_bsize as u64, + f_frsize: if statfs.f_frsize != 0 { + statfs.f_frsize + } else { + statfs.f_bsize + } as u64, + f_blocks: statfs.f_blocks as u64, + f_bfree: statfs.f_bfree as u64, + f_bavail: statfs.f_bavail as u64, + 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_namemax: statfs.f_namelen as u64, + } +} + +#[inline] +pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + unsafe { + ret_usize(syscall!( + __NR_readlinkat, + raw_fd(AT_FDCWD), + path, + buf_addr_mut, + buf_len + )) + } +} + +#[inline] +pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + unsafe { + ret_usize(syscall!( + __NR_readlinkat, + dirfd, + path, + buf_addr_mut, + buf_len + )) + } +} + +#[inline] +pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFL))) + .map(OFlags::from_bits_truncate) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFL))) + .map(OFlags::from_bits_truncate) + } +} + +#[inline] +pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFL), flags)) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!(__NR_fcntl, fd, c_uint(F_SETFL), flags)) + } +} + +#[inline] +pub(crate) fn fcntl_getlease(fd: BorrowedFd<'_>) -> io::Result { + #[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 { + #[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 { + #[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 { + #[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 { + #[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 { + #[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)) + } + #[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)) + } +} + +#[inline] +pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!( + __NR_fcntl64, + fd, + c_uint(F_ADD_SEALS), + seals + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_fcntl, + fd, + c_uint(F_ADD_SEALS), + seals + )) + } +} + +#[inline] +pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { + #[cfg(target_arch = "riscv64")] + unsafe { + ret(syscall_readonly!( + __NR_renameat2, + raw_fd(AT_FDCWD), + oldname, + raw_fd(AT_FDCWD), + newname, + c_uint(0) + )) + } + #[cfg(not(target_arch = "riscv64"))] + unsafe { + ret(syscall_readonly!( + __NR_renameat, + raw_fd(AT_FDCWD), + oldname, + raw_fd(AT_FDCWD), + newname + )) + } +} + +#[inline] +pub(crate) fn renameat( + old_dirfd: BorrowedFd<'_>, + oldname: &CStr, + new_dirfd: BorrowedFd<'_>, + newname: &CStr, +) -> io::Result<()> { + #[cfg(target_arch = "riscv64")] + unsafe { + ret(syscall_readonly!( + __NR_renameat2, + old_dirfd, + oldname, + new_dirfd, + newname, + c_uint(0) + )) + } + #[cfg(not(target_arch = "riscv64"))] + unsafe { + ret(syscall_readonly!( + __NR_renameat, + old_dirfd, + oldname, + new_dirfd, + newname + )) + } +} + +#[inline] +pub(crate) fn renameat2( + old_dirfd: BorrowedFd<'_>, + oldname: &CStr, + new_dirfd: BorrowedFd<'_>, + newname: &CStr, + flags: RenameFlags, +) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_renameat2, + old_dirfd, + oldname, + new_dirfd, + newname, + flags + )) + } +} + +#[inline] +pub(crate) fn unlink(pathname: &CStr) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_unlinkat, + raw_fd(AT_FDCWD), + pathname, + 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)) } +} + +#[inline] +pub(crate) fn rmdir(pathname: &CStr) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_unlinkat, + raw_fd(AT_FDCWD), + pathname, + c_uint(AT_REMOVEDIR) + )) + } +} + +#[inline] +pub(crate) fn link(oldname: &CStr, newname: &CStr) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_linkat, + raw_fd(AT_FDCWD), + oldname, + raw_fd(AT_FDCWD), + newname, + c_uint(0) + )) + } +} + +#[inline] +pub(crate) fn linkat( + old_dirfd: BorrowedFd<'_>, + oldname: &CStr, + new_dirfd: BorrowedFd<'_>, + newname: &CStr, + flags: AtFlags, +) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_linkat, + old_dirfd, + oldname, + new_dirfd, + newname, + flags + )) + } +} + +#[inline] +pub(crate) fn symlink(oldname: &CStr, newname: &CStr) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_symlinkat, + oldname, + raw_fd(AT_FDCWD), + newname + )) + } +} + +#[inline] +pub(crate) fn symlinkat(oldname: &CStr, dirfd: BorrowedFd<'_>, newname: &CStr) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_symlinkat, oldname, dirfd, newname)) } +} + +#[inline] +pub(crate) fn mkdir(pathname: &CStr, mode: Mode) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_mkdirat, + raw_fd(AT_FDCWD), + pathname, + mode + )) + } +} + +#[inline] +pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, pathname: &CStr, mode: Mode) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_mkdirat, dirfd, pathname, mode)) } +} + +#[inline] +pub(crate) fn getdents(fd: BorrowedFd<'_>, dirent: &mut [u8]) -> io::Result { + let (dirent_addr_mut, dirent_len) = slice_mut(dirent); + + unsafe { ret_usize(syscall!(__NR_getdents64, fd, dirent_addr_mut, dirent_len)) } +} + +#[inline] +pub(crate) fn utimensat( + dirfd: BorrowedFd<'_>, + pathname: &CStr, + times: &Timestamps, + flags: AtFlags, +) -> io::Result<()> { + _utimensat(dirfd, Some(pathname), times, flags) +} + +#[inline] +fn _utimensat( + dirfd: BorrowedFd<'_>, + pathname: Option<&CStr>, + times: &Timestamps, + flags: AtFlags, +) -> io::Result<()> { + // Assert that `Timestamps` has the expected layout. + let _ = unsafe { core::mem::transmute::(times.clone()) }; + + #[cfg(target_pointer_width = "32")] + unsafe { + match ret(syscall_readonly!( + __NR_utimensat_time64, + dirfd, + pathname, + by_ref(times), + flags + )) { + Err(io::Errno::NOSYS) => _utimensat_old(dirfd, pathname, times, flags), + otherwise => otherwise, + } + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_utimensat, + dirfd, + pathname, + by_ref(times), + flags + )) + } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn _utimensat_old( + dirfd: BorrowedFd<'_>, + pathname: Option<&CStr>, + times: &Timestamps, + flags: AtFlags, +) -> io::Result<()> { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + let old_times = [ + __kernel_old_timespec { + tv_sec: times + .last_access + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: times + .last_access + .tv_nsec + .try_into() + .map_err(|_| io::Errno::INVAL)?, + }, + __kernel_old_timespec { + tv_sec: times + .last_modification + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: times + .last_modification + .tv_nsec + .try_into() + .map_err(|_| io::Errno::INVAL)?, + }, + ]; + // The length of the array is fixed and not passed into the syscall. + let old_times_addr = slice_just_addr(&old_times); + ret(syscall_readonly!( + __NR_utimensat, + dirfd, + pathname, + old_times_addr, + flags + )) +} + +#[inline] +pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { + _utimensat(fd, None, times, AtFlags::empty()) +} + +pub(crate) fn accessat( + dirfd: BorrowedFd<'_>, + path: &CStr, + access: Access, + flags: AtFlags, +) -> io::Result<()> { + // 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()) + { + return unsafe { ret(syscall_readonly!(__NR_faccessat, dirfd, path, access)) }; + } + + if flags.bits() != AT_EACCESS { + return Err(io::Errno::INVAL); + } + + // TODO: Use faccessat2 in newer Linux versions. + Err(io::Errno::NOSYS) +} + +#[inline] +pub(crate) fn copy_file_range( + fd_in: BorrowedFd<'_>, + off_in: Option<&mut u64>, + fd_out: BorrowedFd<'_>, + off_out: Option<&mut u64>, + len: u64, +) -> io::Result { + let len: usize = len.try_into().unwrap_or(usize::MAX); + _copy_file_range(fd_in, off_in, fd_out, off_out, len, 0).map(|result| result as u64) +} + +#[inline] +fn _copy_file_range( + fd_in: BorrowedFd<'_>, + off_in: Option<&mut u64>, + fd_out: BorrowedFd<'_>, + off_out: Option<&mut u64>, + len: usize, + flags: c::c_uint, +) -> io::Result { + unsafe { + ret_usize(syscall!( + __NR_copy_file_range, + fd_in, + opt_mut(off_in), + fd_out, + opt_mut(off_out), + pass_usize(len), + c_uint(flags) + )) + } +} + +#[inline] +pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result { + unsafe { ret_owned_fd(syscall_readonly!(__NR_memfd_create, name, flags)) } +} + +#[inline] +pub(crate) fn sendfile( + out_fd: BorrowedFd<'_>, + in_fd: BorrowedFd<'_>, + offset: Option<&mut u64>, + count: usize, +) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + ret_usize(syscall!( + __NR_sendfile64, + out_fd, + in_fd, + opt_mut(offset), + pass_usize(count) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall!( + __NR_sendfile, + out_fd, + in_fd, + opt_mut(offset), + pass_usize(count) + )) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/fs/types.rs b/vendor/rustix/src/backend/linux_raw/fs/types.rs new file mode 100644 index 000000000..a8d225ede --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/fs/types.rs @@ -0,0 +1,646 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `*_OK` constants for use with [`accessat`]. + /// + /// [`accessat`]: fn.accessat.html + pub struct Access: c::c_uint { + /// `R_OK` + const READ_OK = linux_raw_sys::general::R_OK; + + /// `W_OK` + const WRITE_OK = linux_raw_sys::general::W_OK; + + /// `X_OK` + const EXEC_OK = linux_raw_sys::general::X_OK; + + /// `F_OK` + const EXISTS = linux_raw_sys::general::F_OK; + } +} + +bitflags! { + /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` + /// functions. + /// + /// [`openat`]: crate::fs::openat + /// [`statat`]: crate::fs::statat + pub struct AtFlags: c::c_uint { + /// `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_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; + + /// `AT_STATX_FORCE_SYNC` + const STATX_FORCE_SYNC = linux_raw_sys::general::AT_STATX_FORCE_SYNC; + + /// `AT_STATX_DONT_SYNC` + const STATX_DONT_SYNC = linux_raw_sys::general::AT_STATX_DONT_SYNC; + } +} + +bitflags! { + /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. + /// + /// [`openat`]: crate::fs::openat + /// [`chmodat`]: crate::fs::chmodat + /// [`fchmod`]: crate::fs::fchmod + pub struct Mode: RawMode { + /// `S_IRWXU` + const RWXU = linux_raw_sys::general::S_IRWXU; + + /// `S_IRUSR` + const RUSR = linux_raw_sys::general::S_IRUSR; + + /// `S_IWUSR` + const WUSR = linux_raw_sys::general::S_IWUSR; + + /// `S_IXUSR` + const XUSR = linux_raw_sys::general::S_IXUSR; + + /// `S_IRWXG` + const RWXG = linux_raw_sys::general::S_IRWXG; + + /// `S_IRGRP` + const RGRP = linux_raw_sys::general::S_IRGRP; + + /// `S_IWGRP` + const WGRP = linux_raw_sys::general::S_IWGRP; + + /// `S_IXGRP` + const XGRP = linux_raw_sys::general::S_IXGRP; + + /// `S_IRWXO` + const RWXO = linux_raw_sys::general::S_IRWXO; + + /// `S_IROTH` + const ROTH = linux_raw_sys::general::S_IROTH; + + /// `S_IWOTH` + const WOTH = linux_raw_sys::general::S_IWOTH; + + /// `S_IXOTH` + const XOTH = linux_raw_sys::general::S_IXOTH; + + /// `S_ISUID` + const SUID = linux_raw_sys::general::S_ISUID; + + /// `S_ISGID` + const SGID = linux_raw_sys::general::S_ISGID; + + /// `S_ISVTX` + const SVTX = linux_raw_sys::general::S_ISVTX; + } +} + +impl Mode { + /// Construct a `Mode` from the mode bits of the `st_mode` field of a + /// `Stat`. + #[inline] + pub const fn from_raw_mode(st_mode: RawMode) -> Self { + Self::from_bits_truncate(st_mode) + } + + /// Construct an `st_mode` value from `Stat`. + #[inline] + pub const fn as_raw_mode(self) -> RawMode { + self.bits() + } +} + +bitflags! { + /// `O_*` constants for use with [`openat`]. + /// + /// [`openat`]: crate::fs::openat + pub struct OFlags: c::c_uint { + /// `O_ACCMODE` + const ACCMODE = linux_raw_sys::general::O_ACCMODE; + + /// Similar to `ACCMODE`, but just includes the read/write flags, and + /// no other flags. + /// + /// Some implementations include `O_PATH` in `O_ACCMODE`, when + /// sometimes we really just want the read/write bits. Caution is + /// indicated, as the presence of `O_PATH` may mean that the read/write + /// bits don't have their usual meaning. + const RWMODE = linux_raw_sys::general::O_RDONLY | + linux_raw_sys::general::O_WRONLY | + linux_raw_sys::general::O_RDWR; + + /// `O_APPEND` + const APPEND = linux_raw_sys::general::O_APPEND; + + /// `O_CREAT` + #[doc(alias = "CREAT")] + const CREATE = linux_raw_sys::general::O_CREAT; + + /// `O_DIRECTORY` + const DIRECTORY = linux_raw_sys::general::O_DIRECTORY; + + /// `O_DSYNC`. Linux 2.6.32 only supports `O_SYNC`. + const DSYNC = linux_raw_sys::general::O_SYNC; + + /// `O_EXCL` + const EXCL = linux_raw_sys::general::O_EXCL; + + /// `O_FSYNC`. Linux 2.6.32 only supports `O_SYNC`. + const FSYNC = linux_raw_sys::general::O_SYNC; + + /// `O_NOFOLLOW` + const NOFOLLOW = linux_raw_sys::general::O_NOFOLLOW; + + /// `O_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; + + /// `O_RDONLY` + const RDONLY = linux_raw_sys::general::O_RDONLY; + + /// `O_WRONLY` + const WRONLY = linux_raw_sys::general::O_WRONLY; + + /// `O_RDWR` + const RDWR = linux_raw_sys::general::O_RDWR; + + /// `O_NOCTTY` + const NOCTTY = linux_raw_sys::general::O_NOCTTY; + + /// `O_RSYNC`. Linux 2.6.32 only supports `O_SYNC`. + const RSYNC = linux_raw_sys::general::O_SYNC; + + /// `O_SYNC` + const SYNC = linux_raw_sys::general::O_SYNC; + + /// `O_TRUNC` + const TRUNC = linux_raw_sys::general::O_TRUNC; + + /// `O_PATH` + const PATH = linux_raw_sys::general::O_PATH; + + /// `O_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; + + /// `O_TMPFILE` + const TMPFILE = linux_raw_sys::general::O_TMPFILE; + + /// `O_NOATIME` + const NOATIME = linux_raw_sys::general::O_NOATIME; + } +} + +bitflags! { + /// `RESOLVE_*` constants for use with [`openat2`]. + /// + /// [`openat2`]: crate::fs::openat2 + #[derive(Default)] + pub struct ResolveFlags: u64 { + /// `RESOLVE_NO_XDEV` + const NO_XDEV = linux_raw_sys::general::RESOLVE_NO_XDEV as u64; + + /// `RESOLVE_NO_MAGICLINKS` + const NO_MAGICLINKS = linux_raw_sys::general::RESOLVE_NO_MAGICLINKS as u64; + + /// `RESOLVE_NO_SYMLINKS` + const NO_SYMLINKS = linux_raw_sys::general::RESOLVE_NO_SYMLINKS as u64; + + /// `RESOLVE_BENEATH` + const BENEATH = linux_raw_sys::general::RESOLVE_BENEATH as u64; + + /// `RESOLVE_IN_ROOT` + const IN_ROOT = linux_raw_sys::general::RESOLVE_IN_ROOT as u64; + + /// `RESOLVE_CACHED` (since Linux 5.12) + const CACHED = linux_raw_sys::general::RESOLVE_CACHED as u64; + } +} + +bitflags! { + /// `RENAME_*` constants for use with [`renameat_with`]. + /// + /// [`renameat_with`]: crate::fs::renameat_with + pub struct RenameFlags: c::c_uint { + /// `RENAME_EXCHANGE` + const EXCHANGE = linux_raw_sys::general::RENAME_EXCHANGE; + + /// `RENAME_NOREPLACE` + const NOREPLACE = linux_raw_sys::general::RENAME_NOREPLACE; + + /// `RENAME_WHITEOUT` + const WHITEOUT = linux_raw_sys::general::RENAME_WHITEOUT; + } +} + +/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. +/// +/// [`mknodat`]: crate::fs::mknodat +/// [`Stat`]: crate::fs::Stat +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum FileType { + /// `S_IFREG` + RegularFile = linux_raw_sys::general::S_IFREG as isize, + + /// `S_IFDIR` + Directory = linux_raw_sys::general::S_IFDIR as isize, + + /// `S_IFLNK` + Symlink = linux_raw_sys::general::S_IFLNK as isize, + + /// `S_IFIFO` + Fifo = linux_raw_sys::general::S_IFIFO as isize, + + /// `S_IFSOCK` + Socket = linux_raw_sys::general::S_IFSOCK as isize, + + /// `S_IFCHR` + CharacterDevice = linux_raw_sys::general::S_IFCHR as isize, + + /// `S_IFBLK` + BlockDevice = linux_raw_sys::general::S_IFBLK as isize, + + /// An unknown filesystem object. + Unknown, +} + +impl FileType { + /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of + /// a `Stat`. + #[inline] + pub const fn from_raw_mode(st_mode: RawMode) -> Self { + match st_mode & linux_raw_sys::general::S_IFMT { + linux_raw_sys::general::S_IFREG => Self::RegularFile, + linux_raw_sys::general::S_IFDIR => Self::Directory, + linux_raw_sys::general::S_IFLNK => Self::Symlink, + linux_raw_sys::general::S_IFIFO => Self::Fifo, + linux_raw_sys::general::S_IFSOCK => Self::Socket, + linux_raw_sys::general::S_IFCHR => Self::CharacterDevice, + linux_raw_sys::general::S_IFBLK => Self::BlockDevice, + _ => Self::Unknown, + } + } + + /// Construct an `st_mode` value from `Stat`. + #[inline] + pub const fn as_raw_mode(self) -> RawMode { + match self { + Self::RegularFile => linux_raw_sys::general::S_IFREG, + Self::Directory => linux_raw_sys::general::S_IFDIR, + Self::Symlink => linux_raw_sys::general::S_IFLNK, + Self::Fifo => linux_raw_sys::general::S_IFIFO, + Self::Socket => linux_raw_sys::general::S_IFSOCK, + Self::CharacterDevice => linux_raw_sys::general::S_IFCHR, + Self::BlockDevice => linux_raw_sys::general::S_IFBLK, + Self::Unknown => linux_raw_sys::general::S_IFMT, + } + } + + /// Construct a `FileType` from the `d_type` field of a `dirent`. + #[inline] + pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { + match d_type as u32 { + linux_raw_sys::general::DT_REG => Self::RegularFile, + linux_raw_sys::general::DT_DIR => Self::Directory, + linux_raw_sys::general::DT_LNK => Self::Symlink, + linux_raw_sys::general::DT_SOCK => Self::Socket, + linux_raw_sys::general::DT_FIFO => Self::Fifo, + linux_raw_sys::general::DT_CHR => Self::CharacterDevice, + linux_raw_sys::general::DT_BLK => Self::BlockDevice, + // linux_raw_sys::general::DT_UNKNOWN | + _ => Self::Unknown, + } + } +} + +/// `POSIX_FADV_*` constants for use with [`fadvise`]. +/// +/// [`fadvise`]: crate::fs::fadvise +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(u32)] +pub enum Advice { + /// `POSIX_FADV_NORMAL` + Normal = linux_raw_sys::general::POSIX_FADV_NORMAL, + + /// `POSIX_FADV_SEQUENTIAL` + Sequential = linux_raw_sys::general::POSIX_FADV_SEQUENTIAL, + + /// `POSIX_FADV_RANDOM` + Random = linux_raw_sys::general::POSIX_FADV_RANDOM, + + /// `POSIX_FADV_NOREUSE` + NoReuse = linux_raw_sys::general::POSIX_FADV_NOREUSE, + + /// `POSIX_FADV_WILLNEED` + WillNeed = linux_raw_sys::general::POSIX_FADV_WILLNEED, + + /// `POSIX_FADV_DONTNEED` + DontNeed = linux_raw_sys::general::POSIX_FADV_DONTNEED, +} + +bitflags! { + /// `MFD_*` constants for use with [`memfd_create`]. + /// + /// [`memfd_create`]: crate::fs::memfd_create + pub struct MemfdFlags: c::c_uint { + /// `MFD_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::MFD_CLOEXEC; + + /// `MFD_ALLOW_SEALING` + const ALLOW_SEALING = linux_raw_sys::general::MFD_ALLOW_SEALING; + + /// `MFD_HUGETLB` (since Linux 4.14) + const HUGETLB = linux_raw_sys::general::MFD_HUGETLB; + + /// `MFD_HUGE_64KB` + const HUGE_64KB = linux_raw_sys::general::MFD_HUGE_64KB; + /// `MFD_HUGE_512JB` + const HUGE_512KB = linux_raw_sys::general::MFD_HUGE_512KB; + /// `MFD_HUGE_1MB` + const HUGE_1MB = linux_raw_sys::general::MFD_HUGE_1MB; + /// `MFD_HUGE_2MB` + const HUGE_2MB = linux_raw_sys::general::MFD_HUGE_2MB; + /// `MFD_HUGE_8MB` + const HUGE_8MB = linux_raw_sys::general::MFD_HUGE_8MB; + /// `MFD_HUGE_16MB` + const HUGE_16MB = linux_raw_sys::general::MFD_HUGE_16MB; + /// `MFD_HUGE_32MB` + const HUGE_32MB = linux_raw_sys::general::MFD_HUGE_32MB; + /// `MFD_HUGE_256MB` + const HUGE_256MB = linux_raw_sys::general::MFD_HUGE_256MB; + /// `MFD_HUGE_512MB` + const HUGE_512MB = linux_raw_sys::general::MFD_HUGE_512MB; + /// `MFD_HUGE_1GB` + const HUGE_1GB = linux_raw_sys::general::MFD_HUGE_1GB; + /// `MFD_HUGE_2GB` + const HUGE_2GB = linux_raw_sys::general::MFD_HUGE_2GB; + /// `MFD_HUGE_16GB` + const HUGE_16GB = linux_raw_sys::general::MFD_HUGE_16GB; + } +} + +bitflags! { + /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and + /// [`fcntl_get_seals`]. + /// + /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals + /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals + pub struct SealFlags: u32 { + /// `F_SEAL_SEAL`. + const SEAL = linux_raw_sys::general::F_SEAL_SEAL; + /// `F_SEAL_SHRINK`. + const SHRINK = linux_raw_sys::general::F_SEAL_SHRINK; + /// `F_SEAL_GROW`. + const GROW = linux_raw_sys::general::F_SEAL_GROW; + /// `F_SEAL_WRITE`. + const WRITE = linux_raw_sys::general::F_SEAL_WRITE; + /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) + const FUTURE_WRITE = linux_raw_sys::general::F_SEAL_FUTURE_WRITE; + } +} + +bitflags! { + /// `STATX_*` constants for use with [`statx`]. + /// + /// [`statx`]: crate::fs::statx + pub struct StatxFlags: u32 { + /// `STATX_TYPE` + const TYPE = linux_raw_sys::general::STATX_TYPE; + + /// `STATX_MODE` + const MODE = linux_raw_sys::general::STATX_MODE; + + /// `STATX_NLINK` + const NLINK = linux_raw_sys::general::STATX_NLINK; + + /// `STATX_UID` + const UID = linux_raw_sys::general::STATX_UID; + + /// `STATX_GID` + const GID = linux_raw_sys::general::STATX_GID; + + /// `STATX_ATIME` + const ATIME = linux_raw_sys::general::STATX_ATIME; + + /// `STATX_MTIME` + const MTIME = linux_raw_sys::general::STATX_MTIME; + + /// `STATX_CTIME` + const CTIME = linux_raw_sys::general::STATX_CTIME; + + /// `STATX_INO` + const INO = linux_raw_sys::general::STATX_INO; + + /// `STATX_SIZE` + const SIZE = linux_raw_sys::general::STATX_SIZE; + + /// `STATX_BLOCKS` + const BLOCKS = linux_raw_sys::general::STATX_BLOCKS; + + /// `STATX_BASIC_STATS` + const BASIC_STATS = linux_raw_sys::general::STATX_BASIC_STATS; + + /// `STATX_BTIME` + const BTIME = linux_raw_sys::general::STATX_BTIME; + + /// `STATX_MNT_ID` (since Linux 5.8) + const MNT_ID = linux_raw_sys::general::STATX_MNT_ID; + + /// `STATX_ALL` + const ALL = linux_raw_sys::general::STATX_ALL; + } +} + +bitflags! { + /// `FALLOC_FL_*` constants for use with [`fallocate`]. + /// + /// [`fallocate`]: crate::fs::fallocate + pub struct FallocateFlags: u32 { + /// `FALLOC_FL_KEEP_SIZE` + const KEEP_SIZE = linux_raw_sys::general::FALLOC_FL_KEEP_SIZE; + /// `FALLOC_FL_PUNCH_HOLE` + const PUNCH_HOLE = linux_raw_sys::general::FALLOC_FL_PUNCH_HOLE; + /// `FALLOC_FL_NO_HIDE_STALE` + const NO_HIDE_STALE = linux_raw_sys::general::FALLOC_FL_NO_HIDE_STALE; + /// `FALLOC_FL_COLLAPSE_RANGE` + const COLLAPSE_RANGE = linux_raw_sys::general::FALLOC_FL_COLLAPSE_RANGE; + /// `FALLOC_FL_ZERO_RANGE` + const ZERO_RANGE = linux_raw_sys::general::FALLOC_FL_ZERO_RANGE; + /// `FALLOC_FL_INSERT_RANGE` + const INSERT_RANGE = linux_raw_sys::general::FALLOC_FL_INSERT_RANGE; + /// `FALLOC_FL_UNSHARE_RANGE` + const UNSHARE_RANGE = linux_raw_sys::general::FALLOC_FL_UNSHARE_RANGE; + } +} + +bitflags! { + /// `ST_*` constants for use with [`StatVfs`]. + pub struct StatVfsMountFlags: u64 { + /// `ST_MANDLOCK` + const MANDLOCK = linux_raw_sys::general::MS_MANDLOCK as u64; + + /// `ST_NOATIME` + const NOATIME = linux_raw_sys::general::MS_NOATIME as u64; + + /// `ST_NODEV` + const NODEV = linux_raw_sys::general::MS_NODEV as u64; + + /// `ST_NODIRATIME` + const NODIRATIME = linux_raw_sys::general::MS_NODIRATIME as u64; + + /// `ST_NOEXEC` + const NOEXEC = linux_raw_sys::general::MS_NOEXEC as u64; + + /// `ST_NOSUID` + const NOSUID = linux_raw_sys::general::MS_NOSUID as u64; + + /// `ST_RDONLY` + const RDONLY = linux_raw_sys::general::MS_RDONLY as u64; + + /// `ST_RELATIME` + const RELATIME = linux_raw_sys::general::MS_RELATIME as u64; + + /// `ST_SYNCHRONOUS` + const SYNCHRONOUS = linux_raw_sys::general::MS_SYNCHRONOUS as u64; + } +} + +/// `LOCK_*` constants for use with [`flock`] +/// +/// [`flock`]: crate::fs::flock +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u32)] +pub enum FlockOperation { + /// `LOCK_SH` + LockShared = linux_raw_sys::general::LOCK_SH, + /// `LOCK_EX` + LockExclusive = linux_raw_sys::general::LOCK_EX, + /// `LOCK_UN` + Unlock = linux_raw_sys::general::LOCK_UN, + /// `LOCK_SH | LOCK_NB` + NonBlockingLockShared = linux_raw_sys::general::LOCK_SH | linux_raw_sys::general::LOCK_NB, + /// `LOCK_EX | LOCK_NB` + NonBlockingLockExclusive = linux_raw_sys::general::LOCK_EX | linux_raw_sys::general::LOCK_NB, + /// `LOCK_UN | LOCK_NB` + NonBlockingUnlock = linux_raw_sys::general::LOCK_UN | linux_raw_sys::general::LOCK_NB, +} + +/// `struct stat` for use with [`statat`] and [`fstat`]. +/// +/// [`statat`]: crate::fs::statat +/// [`fstat`]: crate::fs::fstat +// On 32-bit, and mips64, Linux's `struct stat64` has a 32-bit `st_mtime` and +// friends, so we use our own struct, populated from `statx` where possible, to +// avoid the y2038 bug. +#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[allow(missing_docs)] +pub struct Stat { + pub st_dev: u64, + pub st_mode: u32, + pub st_nlink: u32, + pub st_uid: u32, + pub st_gid: u32, + pub st_rdev: u64, + pub st_size: i64, + pub st_blksize: u32, + pub st_blocks: u64, + pub st_atime: u64, + pub st_atime_nsec: u32, + pub st_mtime: u64, + pub st_mtime_nsec: u32, + pub st_ctime: u64, + pub st_ctime_nsec: u32, + pub st_ino: u64, +} + +/// `struct stat` for use with [`statat`] and [`fstat`]. +/// +/// [`statat`]: crate::fs::statat +/// [`fstat`]: crate::fs::fstat +#[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] +pub type Stat = linux_raw_sys::general::stat; + +/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. +/// +/// [`statfs`]: crate::fs::statfs +/// [`fstatfs`]: crate::fs::fstatfs +#[allow(clippy::module_name_repetitions)] +pub type StatFs = linux_raw_sys::general::statfs64; + +/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`]. +/// +/// [`statvfs`]: crate::fs::statvfs +/// [`fstatvfs`]: crate::fs::fstatvfs +#[allow(missing_docs)] +pub struct StatVfs { + pub f_bsize: u64, + pub f_frsize: u64, + pub f_blocks: u64, + pub f_bfree: u64, + pub f_bavail: u64, + pub f_files: u64, + pub f_ffree: u64, + pub f_favail: u64, + pub f_fsid: u64, + pub f_flag: StatVfsMountFlags, + pub f_namemax: u64, +} + +/// `struct statx` for use with [`statx`]. +/// +/// [`statx`]: crate::fs::statx +pub type Statx = linux_raw_sys::general::statx; + +/// `struct statx_timestamp` for use with [`Statx`]. +pub type StatxTimestamp = linux_raw_sys::general::statx_timestamp; + +/// `mode_t` +#[cfg(not(any( + target_arch = "x86", + target_arch = "sparc", + target_arch = "avr", + target_arch = "arm", +)))] +pub type RawMode = linux_raw_sys::general::__kernel_mode_t; + +/// `mode_t +#[cfg(any( + target_arch = "x86", + target_arch = "sparc", + target_arch = "avr", + target_arch = "arm", +))] +// Don't use `__kernel_mode_t` since it's `u16` which differs from `st_size`. +pub type RawMode = c::c_uint; + +/// `dev_t` +// Within the kernel the dev_t is 32-bit, but userspace uses a 64-bit field. +pub type Dev = u64; + +/// `__fsword_t` +#[cfg(not(target_arch = "mips64"))] +pub type FsWord = linux_raw_sys::general::__fsword_t; + +/// `__fsword_t` +#[cfg(target_arch = "mips64")] +pub type FsWord = i64; + +pub use linux_raw_sys::general::{UTIME_NOW, UTIME_OMIT}; + +/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. +pub const PROC_SUPER_MAGIC: FsWord = linux_raw_sys::general::PROC_SUPER_MAGIC as FsWord; + +/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. +pub const NFS_SUPER_MAGIC: FsWord = linux_raw_sys::general::NFS_SUPER_MAGIC as FsWord; diff --git a/vendor/rustix/src/backend/linux_raw/io/epoll.rs b/vendor/rustix/src/backend/linux_raw/io/epoll.rs new file mode 100644 index 000000000..d55ad75b1 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/epoll.rs @@ -0,0 +1,555 @@ +//! epoll support. +//! +//! This is an experiment, and it isn't yet clear whether epoll is the right +//! level of abstraction at which to introduce safety. But it works fairly well +//! in simple examples 🙂. +//! +//! # Examples +//! +//! ```rust,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::{self, Epoll}; +//! use rustix::io::{ioctl_fionbio, read, write}; +//! use rustix::net::{ +//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4, +//! SocketType, +//! }; +//! use std::os::unix::io::AsRawFd; +//! +//! // Create a socket and listen on it. +//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; +//! 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::new(epoll::CreateFlags::CLOEXEC, epoll::Owning::new())?; +//! +//! // Remember the socket raw fd, which we use for comparisons only. +//! let raw_listen_sock = listen_sock.as_fd().as_raw_fd(); +//! +//! // Register the socket with the epoll object. +//! epoll.add(listen_sock, epoll::EventFlags::IN)?; +//! +//! // Process events. +//! let mut event_list = epoll::EventVec::with_capacity(4); +//! loop { +//! epoll.wait(&mut event_list, -1)?; +//! for (_event_flags, target) in &event_list { +//! if target.as_raw_fd() == raw_listen_sock { +//! // 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(&*target)?; +//! ioctl_fionbio(&conn_sock, true)?; +//! epoll.add(conn_sock, epoll::EventFlags::OUT | epoll::EventFlags::ET)?; +//! } else { +//! // Write a message to the stream and then unregister it. +//! write(&*target, b"hello\n")?; +//! let _ = epoll.del(target)?; +//! } +//! } +//! } +//! # } +//! # #[cfg(not(feature = "net"))] +//! # fn main() {} +//! ``` + +#![allow(unsafe_code)] + +use super::super::c; +use crate::backend::io::syscalls::{epoll_add, epoll_create, epoll_del, epoll_mod, epoll_wait}; +use crate::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}; +#[cfg(feature = "std")] +use crate::fd::{FromRawFd, IntoRawFd}; +use crate::io; +use alloc::vec::Vec; +use bitflags::bitflags; +use core::fmt; +use core::marker::PhantomData; +use core::ops::Deref; +use core::ptr::null; + +bitflags! { + /// `EPOLL_*` for use with [`Epoll::new`]. + pub struct CreateFlags: c::c_uint { + /// `EPOLL_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::EPOLL_CLOEXEC; + } +} + +bitflags! { + /// `EPOLL*` for use with [`Epoll::add`]. + #[derive(Default)] + pub struct EventFlags: u32 { + /// `EPOLLIN` + const IN = linux_raw_sys::general::EPOLLIN as u32; + + /// `EPOLLOUT` + const OUT = linux_raw_sys::general::EPOLLOUT as u32; + + /// `EPOLLPRI` + const PRI = linux_raw_sys::general::EPOLLPRI as u32; + + /// `EPOLLERR` + const ERR = linux_raw_sys::general::EPOLLERR as u32; + + /// `EPOLLHUP` + const HUP = linux_raw_sys::general::EPOLLHUP as u32; + + /// `EPOLLET` + const ET = linux_raw_sys::general::EPOLLET as u32; + + /// `EPOLLONESHOT` + const ONESHOT = linux_raw_sys::general::EPOLLONESHOT as u32; + + /// `EPOLLWAKEUP` + const WAKEUP = linux_raw_sys::general::EPOLLWAKEUP as u32; + + /// `EPOLLEXCLUSIVE` + const EXCLUSIVE = linux_raw_sys::general::EPOLLEXCLUSIVE as u32; + } +} + +/// A reference to a `T`. +pub struct Ref<'a, T> { + t: T, + _phantom: PhantomData<&'a T>, +} + +impl<'a, T> Ref<'a, T> { + #[inline] + fn new(t: T) -> Self { + Self { + t, + _phantom: PhantomData, + } + } + + #[inline] + fn consume(self) -> T { + self.t + } +} + +impl<'a, T> Deref for Ref<'a, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.t + } +} + +impl<'a, T: fmt::Debug> fmt::Debug for Ref<'a, T> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.t.fmt(fmt) + } +} + +/// A trait for data stored within an [`Epoll`] instance. +pub trait Context { + /// The type of an element owned by this context. + type Data; + + /// The type of a value used to refer to an element owned by this context. + type Target: AsFd; + + /// Assume ownership of `data`, and returning a `Target`. + fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target>; + + /// Encode `target` as a `u64`. The only requirement on this value is that + /// it be decodable by `decode`. + fn encode(&self, target: Ref<'_, Self::Target>) -> u64; + + /// Decode `raw`, which is a value encoded by `encode`, into a `Target`. + /// + /// # Safety + /// + /// `raw` must be a `u64` value returned from `encode`, from the same + /// context, and within the context's lifetime. + unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target>; + + /// Release ownership of the value referred to by `target` and return it. + fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data; +} + +/// A type implementing [`Context`] where the `Data` type is `BorrowedFd<'a>`. +pub struct Borrowing<'a> { + _phantom: PhantomData>, +} + +impl<'a> Context for Borrowing<'a> { + type Data = BorrowedFd<'a>; + type Target = BorrowedFd<'a>; + + #[inline] + fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { + Ref::new(data) + } + + #[inline] + fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { + target.as_raw_fd() as u64 + } + + #[inline] + unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { + Ref::new(BorrowedFd::<'a>::borrow_raw(raw as RawFd)) + } + + #[inline] + fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { + target.consume() + } +} + +/// A type implementing [`Context`] where the `Data` type is `T`, a type +/// implementing `From` and `From of OwnedFd`. +/// +/// This may be used with [`OwnedFd`], or higher-level types like +/// [`std::fs::File`] or [`std::net::TcpStream`]. +#[cfg(feature = "std")] +pub struct Owning<'context, T: Into + From> { + _phantom: PhantomData<&'context T>, +} + +#[cfg(feature = "std")] +impl<'context, T: Into + From> Owning<'context, T> { + /// Creates a new empty `Owning`. + #[allow(clippy::new_without_default)] // This is a specialized type that doesn't need to be generically constructible. + #[inline] + pub fn new() -> Self { + Self { + _phantom: PhantomData, + } + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> Context for Owning<'context, T> { + type Data = T; + type Target = BorrowedFd<'context>; + + #[inline] + fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { + let raw_fd = data.into().into_raw_fd(); + // Safety: `epoll` will assign ownership of the file descriptor to the + // kernel epoll object. We use `Into`+`IntoRawFd` to consume + // the `Data` and extract the raw file descriptor and then "borrow" it + // with `borrow_raw` knowing that the borrow won't outlive the + // kernel epoll object. + unsafe { Ref::new(BorrowedFd::<'context>::borrow_raw(raw_fd)) } + } + + #[inline] + fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { + target.as_fd().as_raw_fd() as u64 + } + + #[inline] + unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { + Ref::new(BorrowedFd::<'context>::borrow_raw(raw as RawFd)) + } + + #[inline] + fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { + let raw_fd = target.consume().as_raw_fd(); + + // Safety: The file descriptor was held by the kernel epoll object and + // is now being released, so we can create a new `OwnedFd` that assumes + // ownership. + unsafe { T::from(io_lifetimes::OwnedFd::from_raw_fd(raw_fd)) } + } +} + +/// An "epoll", an interface to an OS object allowing one to repeatedly wait +/// for events from a set of file descriptors efficiently. +pub struct Epoll { + epoll_fd: OwnedFd, + context: Context, +} + +impl Epoll { + /// `epoll_create1(flags)`—Creates a new `Epoll`. + /// + /// 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 new(flags: CreateFlags, context: Context) -> io::Result { + // Safety: We're calling `epoll_create1` via FFI and we know how it + // behaves. + Ok(Self { + epoll_fd: epoll_create(flags)?, + context, + }) + } + + /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an + /// `Epoll`. + /// + /// This registers interest in any of the events set in `events` occurring + /// on the file descriptor associated with `data`. + #[doc(alias = "epoll_ctl")] + pub fn add( + &self, + data: Context::Data, + event_flags: EventFlags, + ) -> io::Result> { + // Safety: We're calling `epoll_ctl` via FFI and we know how it + // behaves. + unsafe { + let target = self.context.acquire(data); + let raw_fd = target.as_fd().as_raw_fd(); + let encoded = self.context.encode(target); + epoll_add( + self.epoll_fd.as_fd(), + raw_fd, + &linux_raw_sys::general::epoll_event { + events: event_flags.bits(), + data: encoded, + }, + )?; + Ok(self.context.decode(encoded)) + } + } + + /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in + /// this `Epoll`. + /// + /// This sets the events of interest with `target` to `events`. + #[doc(alias = "epoll_ctl")] + pub fn mod_( + &self, + target: Ref<'_, Context::Target>, + event_flags: EventFlags, + ) -> io::Result<()> { + let raw_fd = target.as_fd().as_raw_fd(); + let encoded = self.context.encode(target); + // Safety: We're calling `epoll_ctl` via FFI and we know how it + // behaves. + unsafe { + epoll_mod( + self.epoll_fd.as_fd(), + raw_fd, + &linux_raw_sys::general::epoll_event { + events: event_flags.bits(), + data: encoded, + }, + ) + } + } + + /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in + /// this `Epoll`. + /// + /// This also returns the owning `Data`. + #[doc(alias = "epoll_ctl")] + pub fn del(&self, target: Ref<'_, Context::Target>) -> io::Result { + // Safety: We're calling `epoll_ctl` via FFI and we know how it + // behaves. + unsafe { + let raw_fd = target.as_fd().as_raw_fd(); + epoll_del(self.epoll_fd.as_fd(), raw_fd)?; + } + Ok(self.context.release(target)) + } + + /// `epoll_wait(self, events, timeout)`—Waits for registered events of + /// interest. + /// + /// For each event of interest, an element is written to `events`. On + /// success, this returns the number of written elements. + #[doc(alias = "epoll_wait")] + pub fn wait<'context>( + &'context self, + event_list: &mut EventVec<'context, Context>, + timeout: c::c_int, + ) -> io::Result<()> { + // Safety: We're calling `epoll_wait` via FFI and we know how it + // behaves. + unsafe { + event_list.events.set_len(0); + let nfds = epoll_wait( + self.epoll_fd.as_fd(), + event_list.events[..].as_mut_ptr().cast(), + event_list.events.capacity(), + timeout, + )?; + event_list.events.set_len(nfds); + event_list.context = &self.context; + } + + Ok(()) + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> AsRawFd for Epoll> { + fn as_raw_fd(&self) -> RawFd { + self.epoll_fd.as_raw_fd() + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> IntoRawFd for Epoll> { + fn into_raw_fd(self) -> RawFd { + self.epoll_fd.into_raw_fd() + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> FromRawFd for Epoll> { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + Self { + epoll_fd: OwnedFd::from_raw_fd(fd), + context: Owning::new(), + } + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> AsFd for Epoll> { + fn as_fd(&self) -> BorrowedFd<'_> { + self.epoll_fd.as_fd() + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> From>> + for OwnedFd +{ + fn from(epoll: Epoll>) -> Self { + epoll.epoll_fd + } +} + +#[cfg(feature = "std")] +impl<'context, T: AsFd + Into + From> From + for Epoll> +{ + fn from(fd: OwnedFd) -> Self { + Self { + epoll_fd: fd, + context: Owning::new(), + } + } +} + +/// An iterator over the `Event`s in an `EventVec`. +pub struct Iter<'context, Context: self::Context> { + iter: core::slice::Iter<'context, Event>, + context: *const Context, + _phantom: PhantomData<&'context Context>, +} + +impl<'context, Context: self::Context> Iterator for Iter<'context, Context> { + type Item = (EventFlags, Ref<'context, Context::Target>); + + fn next(&mut self) -> Option { + self.iter.next().map(|event| { + // Safety: `self.context` is guaranteed to be valid because we hold + // `'context` for it. And we know this event is associated with this + // context because `wait` sets both. + let decoded = unsafe { (*self.context).decode(event.encoded) }; + + (event.event_flags, decoded) + }) + } +} + +/// 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; `Context` implementations will simply + // need to deal with casting the value into and out of the `u64` + // themselves. + event_flags: EventFlags, + encoded: u64, +} + +/// A vector of `Event`s, plus context for interpreting them. +pub struct EventVec<'context, Context: self::Context> { + events: Vec, + context: *const Context, + _phantom: PhantomData<&'context Context>, +} + +impl<'context, Context: self::Context> EventVec<'context, Context> { + /// Constructs an `EventVec` with memory for `capacity` `Event`s. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + Self { + events: Vec::with_capacity(capacity), + context: null(), + _phantom: PhantomData, + } + } + + /// Returns the current `Event` capacity of this `EventVec`. + #[inline] + pub fn capacity(&self) -> usize { + self.events.capacity() + } + + /// Reserves enough memory for at least `additional` more `Event`s. + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.events.reserve(additional); + } + + /// Reserves enough memory for exactly `additional` more `Event`s. + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + self.events.reserve_exact(additional); + } + + /// Clears all the `Events` out of this `EventVec`. + #[inline] + pub fn clear(&mut self) { + self.events.clear(); + } + + /// Shrinks the capacity of this `EventVec` as much as possible. + #[inline] + pub fn shrink_to_fit(&mut self) { + self.events.shrink_to_fit(); + } + + /// Returns an iterator over the `Event`s in this `EventVec`. + #[inline] + pub fn iter(&self) -> Iter<'_, Context> { + Iter { + iter: self.events.iter(), + context: self.context, + _phantom: PhantomData, + } + } + + /// Returns the number of `Event`s logically contained in this `EventVec`. + #[inline] + pub fn len(&mut self) -> usize { + self.events.len() + } + + /// Tests whether this `EventVec` is logically empty. + #[inline] + pub fn is_empty(&mut self) -> bool { + self.events.is_empty() + } +} + +impl<'context, Context: self::Context> IntoIterator for &'context EventVec<'context, Context> { + type IntoIter = Iter<'context, Context>; + type Item = (EventFlags, Ref<'context, Context::Target>); + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} diff --git a/vendor/rustix/src/backend/linux_raw/io/errno.rs b/vendor/rustix/src/backend/linux_raw/io/errno.rs new file mode 100644 index 000000000..5c7b2fcd5 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/errno.rs @@ -0,0 +1,517 @@ +//! The `rustix` `Errno` type. +//! +//! This type holds an OS error code, which conceptually corresponds to an +//! `errno` value. +//! +//! # Safety +//! +//! Linux uses error codes in `-4095..0`; we use rustc attributes to describe +//! this restricted range of values. +#![allow(unsafe_code)] +#![cfg_attr(not(rustc_attrs), allow(unused_unsafe))] + +use super::super::c; +use crate::backend::fd::RawFd; +use crate::backend::reg::{RetNumber, RetReg}; +use crate::io; +use linux_raw_sys::errno; + +/// The error type for `rustix` APIs. +/// +/// This is similar to `std::io::Error`, but only holds an OS error code, +/// and no extra error value. +#[repr(transparent)] +#[doc(alias = "errno")] +#[derive(Eq, PartialEq, Hash, Copy, Clone)] +// Linux returns negated error codes, and we leave them in negated form, so +// error codes are in `-4095..0`. +#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0xf001))] +#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xffff))] +pub struct Errno(u16); + +impl Errno { + /// Extract an `Errno` value from a `std::io::Error`. + /// + /// This isn't a `From` conversion because it's expected to be relatively + /// uncommon. + #[cfg(feature = "std")] + #[inline] + pub fn from_io_error(io_err: &std::io::Error) -> Option { + io_err.raw_os_error().and_then(|raw| { + // `std::io::Error` could theoretically have arbitrary "OS error" + // values, so check that they're in Linux's range. + if (1..4096).contains(&raw) { + Some(Self::from_errno(raw as u32)) + } else { + None + } + }) + } + + /// Extract the raw OS error number from this error. + #[inline] + pub const fn raw_os_error(self) -> i32 { + (self.0 as i16 as i32).wrapping_neg() + } + + /// Construct an `Errno` from a raw OS error number. + #[inline] + pub const fn from_raw_os_error(raw: i32) -> Self { + Self::from_errno(raw as u32) + } + + /// 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. + let encoded = raw.wrapping_neg() as u16; + + // TODO: Use Range::contains, once that's `const`. + const_assert!(encoded >= 0xf001); + + // Safety: Linux syscalls return negated error values in the range + // `-4095..0`, which we just asserted. + unsafe { Self(encoded) } + } +} + +/// Check for an error from the result of a syscall which encodes a +/// `c::c_int` on success. +#[inline] +pub(in crate::backend) fn try_decode_c_int( + raw: RetReg, +) -> io::Result { + if raw.is_in_range(-4095..0) { + // Safety: `raw` must be in `-4095..0`, and we just checked that raw is + // in that range. + return Err(unsafe { Errno(raw.decode_error_code()) }); + } + + Ok(raw.decode_c_int()) +} + +/// Check for an error from the result of a syscall which encodes a +/// `c::c_uint` on success. +#[inline] +pub(in crate::backend) fn try_decode_c_uint( + raw: RetReg, +) -> io::Result { + if raw.is_in_range(-4095..0) { + // Safety: `raw` must be in `-4095..0`, and we just checked that raw is + // in that range. + return Err(unsafe { Errno(raw.decode_error_code()) }); + } + + Ok(raw.decode_c_uint()) +} + +/// Check for an error from the result of a syscall which encodes a `usize` on +/// success. +#[inline] +pub(in crate::backend) fn try_decode_usize(raw: RetReg) -> io::Result { + if raw.is_in_range(-4095..0) { + // Safety: `raw` must be in `-4095..0`, and we just checked that raw is + // in that range. + return Err(unsafe { Errno(raw.decode_error_code()) }); + } + + Ok(raw.decode_usize()) +} + +/// Check for an error from the result of a syscall which encodes a +/// `*mut c_void` on success. +#[inline] +pub(in crate::backend) fn try_decode_void_star( + raw: RetReg, +) -> io::Result<*mut c::c_void> { + if raw.is_in_range(-4095..0) { + // Safety: `raw` must be in `-4095..0`, and we just checked that raw is + // in that range. + return Err(unsafe { Errno(raw.decode_error_code()) }); + } + + Ok(raw.decode_void_star()) +} + +/// Check for an error from the result of a syscall which encodes a +/// `u64` on success. +#[cfg(target_pointer_width = "64")] +#[inline] +pub(in crate::backend) fn try_decode_u64(raw: RetReg) -> io::Result { + if raw.is_in_range(-4095..0) { + // Safety: `raw` must be in `-4095..0`, and we just checked that raw is + // in that range. + return Err(unsafe { Errno(raw.decode_error_code()) }); + } + + Ok(raw.decode_u64()) +} + +/// Check for an error from the result of a syscall which encodes a file +/// descriptor on success. +/// +/// # Safety +/// +/// This must only be used with syscalls which return file descriptors on +/// success. +#[inline] +pub(in crate::backend) unsafe fn try_decode_raw_fd( + raw: RetReg, +) -> io::Result { + // Instead of using `check_result` here, we just check for negative, since + // this function is only used for system calls which return file + // descriptors, and this produces smaller code. + if raw.is_negative() { + debug_assert!(raw.is_in_range(-4095..0)); + + // Tell the optimizer that we know the value is in the error range. + // This helps it avoid unnecessary integer conversions. + #[cfg(core_intrinsics)] + { + core::intrinsics::assume(raw.is_in_range(-4095..0)); + } + + return Err(Errno(raw.decode_error_code())); + } + + Ok(raw.decode_raw_fd()) +} + +/// Check for an error from the result of a syscall which encodes no value on +/// success. On success, return the unconsumed `raw` value. +/// +/// # Safety +/// +/// This must only be used with syscalls which return no value on success. +#[inline] +pub(in crate::backend) unsafe fn try_decode_void( + raw: RetReg, +) -> io::Result<()> { + // Instead of using `check_result` here, we just check for zero, since this + // function is only used for system calls which have no other return value, + // and this produces smaller code. + if raw.is_nonzero() { + debug_assert!(raw.is_in_range(-4095..0)); + + // Tell the optimizer that we know the value is in the error range. + // This helps it avoid unnecessary integer conversions. + #[cfg(core_intrinsics)] + { + core::intrinsics::assume(raw.is_in_range(-4095..0)); + } + + return Err(Errno(raw.decode_error_code())); + } + + raw.decode_void(); + + Ok(()) +} + +/// Check for an error from the result of a syscall which does not return on +/// success. On success, return the unconsumed `raw` value. +/// +/// # Safety +/// +/// This must only be used with syscalls which do not return on success. +#[cfg(feature = "runtime")] +#[inline] +pub(in crate::backend) unsafe fn try_decode_error(raw: RetReg) -> io::Errno { + debug_assert!(raw.is_in_range(-4095..0)); + + // Tell the optimizer that we know the value is in the error range. + // This helps it avoid unnecessary integer conversions. + #[cfg(core_intrinsics)] + { + core::intrinsics::assume(raw.is_in_range(-4095..0)); + } + + Errno(raw.decode_error_code()) +} + +/// Return the contained `usize` value. +#[cfg(not(debug_assertions))] +#[inline] +pub(in crate::backend) fn decode_usize_infallible(raw: RetReg) -> usize { + raw.decode_usize() +} + +impl Errno { + /// `EACCES` + #[doc(alias = "ACCES")] + pub const ACCESS: Self = Self::from_errno(errno::EACCES); + /// `EADDRINUSE` + pub const ADDRINUSE: Self = Self::from_errno(errno::EADDRINUSE); + /// `EADDRNOTAVAIL` + pub const ADDRNOTAVAIL: Self = Self::from_errno(errno::EADDRNOTAVAIL); + /// `EADV` + pub const ADV: Self = Self::from_errno(errno::EADV); + /// `EAFNOSUPPORT` + pub const AFNOSUPPORT: Self = Self::from_errno(errno::EAFNOSUPPORT); + /// `EAGAIN` + pub const AGAIN: Self = Self::from_errno(errno::EAGAIN); + /// `EALREADY` + pub const ALREADY: Self = Self::from_errno(errno::EALREADY); + /// `EBADE` + pub const BADE: Self = Self::from_errno(errno::EBADE); + /// `EBADF` + pub const BADF: Self = Self::from_errno(errno::EBADF); + /// `EBADFD` + pub const BADFD: Self = Self::from_errno(errno::EBADFD); + /// `EBADMSG` + pub const BADMSG: Self = Self::from_errno(errno::EBADMSG); + /// `EBADR` + pub const BADR: Self = Self::from_errno(errno::EBADR); + /// `EBADRQC` + pub const BADRQC: Self = Self::from_errno(errno::EBADRQC); + /// `EBADSLT` + pub const BADSLT: Self = Self::from_errno(errno::EBADSLT); + /// `EBFONT` + pub const BFONT: Self = Self::from_errno(errno::EBFONT); + /// `EBUSY` + pub const BUSY: Self = Self::from_errno(errno::EBUSY); + /// `ECANCELED` + pub const CANCELED: Self = Self::from_errno(errno::ECANCELED); + /// `ECHILD` + pub const CHILD: Self = Self::from_errno(errno::ECHILD); + /// `ECHRNG` + pub const CHRNG: Self = Self::from_errno(errno::ECHRNG); + /// `ECOMM` + pub const COMM: Self = Self::from_errno(errno::ECOMM); + /// `ECONNABORTED` + pub const CONNABORTED: Self = Self::from_errno(errno::ECONNABORTED); + /// `ECONNREFUSED` + pub const CONNREFUSED: Self = Self::from_errno(errno::ECONNREFUSED); + /// `ECONNRESET` + pub const CONNRESET: Self = Self::from_errno(errno::ECONNRESET); + /// `EDEADLK` + pub const DEADLK: Self = Self::from_errno(errno::EDEADLK); + /// `EDEADLOCK` + pub const DEADLOCK: Self = Self::from_errno(errno::EDEADLOCK); + /// `EDESTADDRREQ` + pub const DESTADDRREQ: Self = Self::from_errno(errno::EDESTADDRREQ); + /// `EDOM` + pub const DOM: Self = Self::from_errno(errno::EDOM); + /// `EDOTDOT` + pub const DOTDOT: Self = Self::from_errno(errno::EDOTDOT); + /// `EDQUOT` + pub const DQUOT: Self = Self::from_errno(errno::EDQUOT); + /// `EEXIST` + pub const EXIST: Self = Self::from_errno(errno::EEXIST); + /// `EFAULT` + pub const FAULT: Self = Self::from_errno(errno::EFAULT); + /// `EFBIG` + pub const FBIG: Self = Self::from_errno(errno::EFBIG); + /// `EHOSTDOWN` + pub const HOSTDOWN: Self = Self::from_errno(errno::EHOSTDOWN); + /// `EHOSTUNREACH` + pub const HOSTUNREACH: Self = Self::from_errno(errno::EHOSTUNREACH); + /// `EHWPOISON` + pub const HWPOISON: Self = Self::from_errno(errno::EHWPOISON); + /// `EIDRM` + pub const IDRM: Self = Self::from_errno(errno::EIDRM); + /// `EILSEQ` + pub const ILSEQ: Self = Self::from_errno(errno::EILSEQ); + /// `EINPROGRESS` + pub const INPROGRESS: Self = Self::from_errno(errno::EINPROGRESS); + /// `EINTR`. + /// + /// For a convenient way to retry system calls that exit with `INTR`, use + /// [`retry_on_intr`]. + /// + /// [`retry_on_intr`]: io::retry_on_intr + pub const INTR: Self = Self::from_errno(errno::EINTR); + /// `EINVAL` + pub const INVAL: Self = Self::from_errno(errno::EINVAL); + /// `EIO` + pub const IO: Self = Self::from_errno(errno::EIO); + /// `EISCONN` + pub const ISCONN: Self = Self::from_errno(errno::EISCONN); + /// `EISDIR` + pub const ISDIR: Self = Self::from_errno(errno::EISDIR); + /// `EISNAM` + pub const ISNAM: Self = Self::from_errno(errno::EISNAM); + /// `EKEYEXPIRED` + pub const KEYEXPIRED: Self = Self::from_errno(errno::EKEYEXPIRED); + /// `EKEYREJECTED` + pub const KEYREJECTED: Self = Self::from_errno(errno::EKEYREJECTED); + /// `EKEYREVOKED` + pub const KEYREVOKED: Self = Self::from_errno(errno::EKEYREVOKED); + /// `EL2HLT` + pub const L2HLT: Self = Self::from_errno(errno::EL2HLT); + /// `EL2NSYNC` + pub const L2NSYNC: Self = Self::from_errno(errno::EL2NSYNC); + /// `EL3HLT` + pub const L3HLT: Self = Self::from_errno(errno::EL3HLT); + /// `EL3RST` + pub const L3RST: Self = Self::from_errno(errno::EL3RST); + /// `ELIBACC` + pub const LIBACC: Self = Self::from_errno(errno::ELIBACC); + /// `ELIBBAD` + pub const LIBBAD: Self = Self::from_errno(errno::ELIBBAD); + /// `ELIBEXEC` + pub const LIBEXEC: Self = Self::from_errno(errno::ELIBEXEC); + /// `ELIBMAX` + pub const LIBMAX: Self = Self::from_errno(errno::ELIBMAX); + /// `ELIBSCN` + pub const LIBSCN: Self = Self::from_errno(errno::ELIBSCN); + /// `ELNRNG` + pub const LNRNG: Self = Self::from_errno(errno::ELNRNG); + /// `ELOOP` + pub const LOOP: Self = Self::from_errno(errno::ELOOP); + /// `EMEDIUMTYPE` + pub const MEDIUMTYPE: Self = Self::from_errno(errno::EMEDIUMTYPE); + /// `EMFILE` + pub const MFILE: Self = Self::from_errno(errno::EMFILE); + /// `EMLINK` + pub const MLINK: Self = Self::from_errno(errno::EMLINK); + /// `EMSGSIZE` + pub const MSGSIZE: Self = Self::from_errno(errno::EMSGSIZE); + /// `EMULTIHOP` + pub const MULTIHOP: Self = Self::from_errno(errno::EMULTIHOP); + /// `ENAMETOOLONG` + pub const NAMETOOLONG: Self = Self::from_errno(errno::ENAMETOOLONG); + /// `ENAVAIL` + pub const NAVAIL: Self = Self::from_errno(errno::ENAVAIL); + /// `ENETDOWN` + pub const NETDOWN: Self = Self::from_errno(errno::ENETDOWN); + /// `ENETRESET` + pub const NETRESET: Self = Self::from_errno(errno::ENETRESET); + /// `ENETUNREACH` + pub const NETUNREACH: Self = Self::from_errno(errno::ENETUNREACH); + /// `ENFILE` + pub const NFILE: Self = Self::from_errno(errno::ENFILE); + /// `ENOANO` + pub const NOANO: Self = Self::from_errno(errno::ENOANO); + /// `ENOBUFS` + pub const NOBUFS: Self = Self::from_errno(errno::ENOBUFS); + /// `ENOCSI` + pub const NOCSI: Self = Self::from_errno(errno::ENOCSI); + /// `ENODATA` + #[doc(alias = "NOATTR")] + pub const NODATA: Self = Self::from_errno(errno::ENODATA); + /// `ENODEV` + pub const NODEV: Self = Self::from_errno(errno::ENODEV); + /// `ENOENT` + pub const NOENT: Self = Self::from_errno(errno::ENOENT); + /// `ENOEXEC` + pub const NOEXEC: Self = Self::from_errno(errno::ENOEXEC); + /// `ENOKEY` + pub const NOKEY: Self = Self::from_errno(errno::ENOKEY); + /// `ENOLCK` + pub const NOLCK: Self = Self::from_errno(errno::ENOLCK); + /// `ENOLINK` + pub const NOLINK: Self = Self::from_errno(errno::ENOLINK); + /// `ENOMEDIUM` + pub const NOMEDIUM: Self = Self::from_errno(errno::ENOMEDIUM); + /// `ENOMEM` + pub const NOMEM: Self = Self::from_errno(errno::ENOMEM); + /// `ENOMSG` + pub const NOMSG: Self = Self::from_errno(errno::ENOMSG); + /// `ENONET` + pub const NONET: Self = Self::from_errno(errno::ENONET); + /// `ENOPKG` + pub const NOPKG: Self = Self::from_errno(errno::ENOPKG); + /// `ENOPROTOOPT` + pub const NOPROTOOPT: Self = Self::from_errno(errno::ENOPROTOOPT); + /// `ENOSPC` + pub const NOSPC: Self = Self::from_errno(errno::ENOSPC); + /// `ENOSR` + pub const NOSR: Self = Self::from_errno(errno::ENOSR); + /// `ENOSTR` + pub const NOSTR: Self = Self::from_errno(errno::ENOSTR); + /// `ENOSYS` + pub const NOSYS: Self = Self::from_errno(errno::ENOSYS); + /// `ENOTBLK` + pub const NOTBLK: Self = Self::from_errno(errno::ENOTBLK); + /// `ENOTCONN` + pub const NOTCONN: Self = Self::from_errno(errno::ENOTCONN); + /// `ENOTDIR` + pub const NOTDIR: Self = Self::from_errno(errno::ENOTDIR); + /// `ENOTEMPTY` + pub const NOTEMPTY: Self = Self::from_errno(errno::ENOTEMPTY); + /// `ENOTNAM` + pub const NOTNAM: Self = Self::from_errno(errno::ENOTNAM); + /// `ENOTRECOVERABLE` + pub const NOTRECOVERABLE: Self = Self::from_errno(errno::ENOTRECOVERABLE); + /// `ENOTSOCK` + pub const NOTSOCK: Self = Self::from_errno(errno::ENOTSOCK); + /// `ENOTSUP` + // On Linux, `ENOTSUP` has the same value as `EOPNOTSUPP`. + pub const NOTSUP: Self = Self::from_errno(errno::EOPNOTSUPP); + /// `ENOTTY` + pub const NOTTY: Self = Self::from_errno(errno::ENOTTY); + /// `ENOTUNIQ` + pub const NOTUNIQ: Self = Self::from_errno(errno::ENOTUNIQ); + /// `ENXIO` + pub const NXIO: Self = Self::from_errno(errno::ENXIO); + /// `EOPNOTSUPP` + pub const OPNOTSUPP: Self = Self::from_errno(errno::EOPNOTSUPP); + /// `EOVERFLOW` + pub const OVERFLOW: Self = Self::from_errno(errno::EOVERFLOW); + /// `EOWNERDEAD` + pub const OWNERDEAD: Self = Self::from_errno(errno::EOWNERDEAD); + /// `EPERM` + pub const PERM: Self = Self::from_errno(errno::EPERM); + /// `EPFNOSUPPORT` + pub const PFNOSUPPORT: Self = Self::from_errno(errno::EPFNOSUPPORT); + /// `EPIPE` + pub const PIPE: Self = Self::from_errno(errno::EPIPE); + /// `EPROTO` + pub const PROTO: Self = Self::from_errno(errno::EPROTO); + /// `EPROTONOSUPPORT` + pub const PROTONOSUPPORT: Self = Self::from_errno(errno::EPROTONOSUPPORT); + /// `EPROTOTYPE` + pub const PROTOTYPE: Self = Self::from_errno(errno::EPROTOTYPE); + /// `ERANGE` + pub const RANGE: Self = Self::from_errno(errno::ERANGE); + /// `EREMCHG` + pub const REMCHG: Self = Self::from_errno(errno::EREMCHG); + /// `EREMOTE` + pub const REMOTE: Self = Self::from_errno(errno::EREMOTE); + /// `EREMOTEIO` + pub const REMOTEIO: Self = Self::from_errno(errno::EREMOTEIO); + /// `ERESTART` + pub const RESTART: Self = Self::from_errno(errno::ERESTART); + /// `ERFKILL` + pub const RFKILL: Self = Self::from_errno(errno::ERFKILL); + /// `EROFS` + pub const ROFS: Self = Self::from_errno(errno::EROFS); + /// `ESHUTDOWN` + pub const SHUTDOWN: Self = Self::from_errno(errno::ESHUTDOWN); + /// `ESOCKTNOSUPPORT` + pub const SOCKTNOSUPPORT: Self = Self::from_errno(errno::ESOCKTNOSUPPORT); + /// `ESPIPE` + pub const SPIPE: Self = Self::from_errno(errno::ESPIPE); + /// `ESRCH` + pub const SRCH: Self = Self::from_errno(errno::ESRCH); + /// `ESRMNT` + pub const SRMNT: Self = Self::from_errno(errno::ESRMNT); + /// `ESTALE` + pub const STALE: Self = Self::from_errno(errno::ESTALE); + /// `ESTRPIPE` + pub const STRPIPE: Self = Self::from_errno(errno::ESTRPIPE); + /// `ETIME` + pub const TIME: Self = Self::from_errno(errno::ETIME); + /// `ETIMEDOUT` + pub const TIMEDOUT: Self = Self::from_errno(errno::ETIMEDOUT); + /// `E2BIG` + #[doc(alias = "2BIG")] + pub const TOOBIG: Self = Self::from_errno(errno::E2BIG); + /// `ETOOMANYREFS` + pub const TOOMANYREFS: Self = Self::from_errno(errno::ETOOMANYREFS); + /// `ETXTBSY` + pub const TXTBSY: Self = Self::from_errno(errno::ETXTBSY); + /// `EUCLEAN` + pub const UCLEAN: Self = Self::from_errno(errno::EUCLEAN); + /// `EUNATCH` + pub const UNATCH: Self = Self::from_errno(errno::EUNATCH); + /// `EUSERS` + pub const USERS: Self = Self::from_errno(errno::EUSERS); + /// `EWOULDBLOCK` + pub const WOULDBLOCK: Self = Self::from_errno(errno::EWOULDBLOCK); + /// `EXDEV` + pub const XDEV: Self = Self::from_errno(errno::EXDEV); + /// `EXFULL` + pub const XFULL: Self = Self::from_errno(errno::EXFULL); +} diff --git a/vendor/rustix/src/backend/linux_raw/io/io_slice.rs b/vendor/rustix/src/backend/linux_raw/io/io_slice.rs new file mode 100644 index 000000000..fc8e64698 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/io_slice.rs @@ -0,0 +1,98 @@ +//! 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; + +/// +#[derive(Copy, Clone)] +#[repr(transparent)] +pub struct IoSlice<'a> { + vec: c::iovec, + _p: PhantomData<&'a [u8]>, +} + +impl<'a> IoSlice<'a> { + /// + #[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, + } + } + + /// + #[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); + } + } + + /// + #[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) } + } +} + +/// +#[repr(transparent)] +pub struct IoSliceMut<'a> { + vec: c::iovec, + _p: PhantomData<&'a mut [u8]>, +} + +impl<'a> IoSliceMut<'a> { + /// + #[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, + } + } + + /// + #[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); + } + } + + /// + #[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) } + } + + /// + #[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 new file mode 100644 index 000000000..f5c2bf3c0 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/mod.rs @@ -0,0 +1,7 @@ +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/poll_fd.rs b/vendor/rustix/src/backend/linux_raw/io/poll_fd.rs new file mode 100644 index 000000000..252358331 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/poll_fd.rs @@ -0,0 +1,93 @@ +use crate::fd::{AsFd, BorrowedFd}; +use bitflags::bitflags; + +bitflags! { + /// `POLL*` flags for use with [`poll`]. + /// + /// [`poll`]: crate::io::poll + pub struct PollFlags: u16 { + /// `POLLIN` + const IN = linux_raw_sys::general::POLLIN as u16; + /// `POLLPRI` + const PRI = linux_raw_sys::general::POLLPRI as u16; + /// `POLLOUT` + const OUT = linux_raw_sys::general::POLLOUT as u16; + /// `POLLRDNORM` + const RDNORM = linux_raw_sys::general::POLLRDNORM as u16; + /// `POLLWRNORM` + const WRNORM = linux_raw_sys::general::POLLWRNORM as u16; + /// `POLLRDBAND` + const RDBAND = linux_raw_sys::general::POLLRDBAND as u16; + /// `POLLWRBAND` + const WRBAND = linux_raw_sys::general::POLLWRBAND as u16; + /// `POLLERR` + const ERR = linux_raw_sys::general::POLLERR as u16; + /// `POLLHUP` + const HUP = linux_raw_sys::general::POLLHUP as u16; + /// `POLLNVAL` + const NVAL = linux_raw_sys::general::POLLNVAL as u16; + /// `POLLRDHUP` + const RDHUP = linux_raw_sys::general::POLLRDHUP as u16; + } +} + +/// `struct pollfd`—File descriptor and flags for use with [`poll`]. +/// +/// [`poll`]: crate::io::poll +#[doc(alias = "pollfd")] +#[repr(C)] +#[derive(Debug, Clone)] +pub struct PollFd<'fd> { + pub(crate) fd: BorrowedFd<'fd>, + pub(crate) events: u16, + pub(crate) revents: u16, +} + +impl<'fd> PollFd<'fd> { + /// Constructs a new `PollFd` holding `fd` and `events`. + #[inline] + pub fn new(fd: &'fd Fd, events: PollFlags) -> Self { + Self::from_borrowed_fd(fd.as_fd(), events) + } + + /// Sets the contained file descriptor to `fd`. + #[inline] + pub fn set_fd(&mut self, fd: &'fd Fd) { + self.fd = fd.as_fd(); + } + + /// Clears the ready events. + #[inline] + pub fn clear_revents(&mut self) { + self.revents = 0; + } + + /// Constructs a new `PollFd` holding `fd` and `events`. + /// + /// This is the same as `new`, but can be used to avoid borrowing the + /// `BorrowedFd`, which can be tricky in situations where the `BorrowedFd` + /// is a temporary. + #[inline] + pub fn from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self { + Self { + fd, + events: events.bits(), + revents: 0, + } + } + + /// Returns the ready events. + #[inline] + pub fn revents(&self) -> PollFlags { + // Use `unwrap()` here because in theory we know we know all the bits + // the OS might set here, but OS's have added extensions in the past. + PollFlags::from_bits(self.revents).unwrap() + } +} + +impl<'fd> AsFd for PollFd<'fd> { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + self.fd.as_fd() + } +} diff --git a/vendor/rustix/src/backend/linux_raw/io/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs new file mode 100644 index 000000000..2cc7898af --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/syscalls.rs @@ -0,0 +1,676 @@ +//! linux_raw syscalls supporting `rustix::io`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![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, +}; +#[cfg(target_pointer_width = "32")] +use super::super::conv::{hi, lo}; +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, +}; +#[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, 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, sigset_t}, +}; + +#[inline] +pub(crate) fn read(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + + unsafe { ret_usize(syscall!(__NR_read, fd, buf_addr_mut, buf_len)) } +} + +#[inline] +pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], pos: u64) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + + // + #[cfg(all( + target_pointer_width = "32", + any(target_arch = "arm", target_arch = "mips", target_arch = "power"), + ))] + unsafe { + ret_usize(syscall!( + __NR_pread64, + fd, + buf_addr_mut, + buf_len, + zero(), + hi(pos), + lo(pos) + )) + } + #[cfg(all( + target_pointer_width = "32", + not(any(target_arch = "arm", target_arch = "mips", target_arch = "power")), + ))] + unsafe { + ret_usize(syscall!( + __NR_pread64, + fd, + buf_addr_mut, + buf_len, + hi(pos), + lo(pos) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall!( + __NR_pread64, + fd, + buf_addr_mut, + buf_len, + loff_t_from_u64(pos) + )) + } +} + +#[inline] +pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + + unsafe { ret_usize(syscall!(__NR_readv, fd, bufs_addr, bufs_len)) } +} + +#[inline] +pub(crate) fn preadv( + fd: BorrowedFd<'_>, + bufs: &mut [IoSliceMut<'_>], + pos: u64, +) -> io::Result { + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + + #[cfg(target_pointer_width = "32")] + unsafe { + ret_usize(syscall!( + __NR_preadv, + fd, + bufs_addr, + bufs_len, + hi(pos), + lo(pos) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall!( + __NR_preadv, + fd, + bufs_addr, + bufs_len, + loff_t_from_u64(pos) + )) + } +} + +#[inline] +pub(crate) fn preadv2( + fd: BorrowedFd<'_>, + bufs: &mut [IoSliceMut<'_>], + pos: u64, + flags: ReadWriteFlags, +) -> io::Result { + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + + #[cfg(target_pointer_width = "32")] + unsafe { + ret_usize(syscall!( + __NR_preadv2, + fd, + bufs_addr, + bufs_len, + hi(pos), + lo(pos), + flags + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall!( + __NR_preadv2, + fd, + bufs_addr, + bufs_len, + loff_t_from_u64(pos), + flags + )) + } +} + +#[inline] +pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result { + let (buf_addr, buf_len) = slice(buf); + + unsafe { ret_usize(syscall_readonly!(__NR_write, fd, buf_addr, buf_len)) } +} + +#[inline] +pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], pos: u64) -> io::Result { + let (buf_addr, buf_len) = slice(buf); + + // + #[cfg(all( + target_pointer_width = "32", + any(target_arch = "arm", target_arch = "mips", target_arch = "power"), + ))] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwrite64, + fd, + buf_addr, + buf_len, + zero(), + hi(pos), + lo(pos) + )) + } + #[cfg(all( + target_pointer_width = "32", + not(any(target_arch = "arm", target_arch = "mips", target_arch = "power")), + ))] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwrite64, + fd, + buf_addr, + buf_len, + hi(pos), + lo(pos) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwrite64, + fd, + buf_addr, + buf_len, + loff_t_from_u64(pos) + )) + } +} + +#[inline] +pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result { + 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 { + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + + #[cfg(target_pointer_width = "32")] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwritev, + fd, + bufs_addr, + bufs_len, + hi(pos), + lo(pos) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwritev, + fd, + bufs_addr, + bufs_len, + loff_t_from_u64(pos) + )) + } +} + +#[inline] +pub(crate) fn pwritev2( + fd: BorrowedFd<'_>, + bufs: &[IoSlice<'_>], + pos: u64, + flags: ReadWriteFlags, +) -> io::Result { + let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); + + #[cfg(target_pointer_width = "32")] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwritev2, + fd, + bufs_addr, + bufs_len, + hi(pos), + lo(pos), + flags + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_usize(syscall_readonly!( + __NR_pwritev2, + fd, + bufs_addr, + bufs_len, + loff_t_from_u64(pos), + flags + )) + } +} + +/// 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. + syscall_readonly!(__NR_close, raw_fd(fd)).decode_void(); +} + +#[inline] +pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result { + unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } +} + +#[inline] +pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!(__NR_ioctl, fd, c_uint(FIONREAD), &mut result))?; + Ok(result.assume_init() as u64) + } +} + +#[inline] +pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { + unsafe { + let data = c::c_int::from(value); + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(FIONBIO), + by_ref(&data) + )) + } +} + +#[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 { + let mut result = MaybeUninit::::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 { + let mut result = MaybeUninit::::uninit(); + unsafe { + ret(syscall!(__NR_ioctl, fd, c_uint(BLKPBSZGET), &mut result))?; + Ok(result.assume_init() as u32) + } +} + +#[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)?; + let mut not_socket = false; + if read { + // Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates + // the read side is shut down; an `EWOULDBLOCK` indicates the read + // side is still open. + // + // 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) + { + Ok(0) => read = false, + Err(err) => { + #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` + match err { + io::Errno::AGAIN | io::Errno::WOULDBLOCK => (), + io::Errno::NOTSOCK => not_socket = true, + _ => return Err(err), + } + } + Ok(_) => (), + } + } + if write && !not_socket { + // 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) { + // TODO or-patterns when we don't need 1.51 + Err(io::Errno::AGAIN) => (), + Err(io::Errno::WOULDBLOCK) => (), + Err(io::Errno::NOTSOCK) => (), + Err(io::Errno::PIPE) => write = false, + Err(err) => return Err(err), + Ok(_) => (), + } + } + Ok((read, write)) +} + +#[inline] +pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result { + unsafe { ret_owned_fd(syscall_readonly!(__NR_dup, fd)) } +} + +#[inline] +pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { + #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + { + // We don't need to worry about the difference between `dup2` and + // `dup3` when the file descriptors are equal because we have an + // `&mut OwnedFd` which means `fd` doesn't alias it. + dup3(fd, new, DupFlags::empty()) + } + + #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + unsafe { + ret_discarded_fd(syscall_readonly!(__NR_dup2, fd, new.as_fd())) + } +} + +#[inline] +pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { + unsafe { ret_discarded_fd(syscall_readonly!(__NR_dup3, fd, new.as_fd(), flags)) } +} + +#[inline] +pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFD))) + .map(FdFlags::from_bits_truncate) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFD))) + .map(FdFlags::from_bits_truncate) + } +} + +#[inline] +pub(crate) fn fcntl_setfd(fd: BorrowedFd<'_>, flags: FdFlags) -> io::Result<()> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFD), flags)) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!(__NR_fcntl, fd, c_uint(F_SETFD), flags)) + } +} + +#[cfg(target_os = "espidf")] +#[inline] +pub(crate) fn fcntl_dupfd(fd: BorrowedFd<'_>, min: RawFd) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_fcntl64, + fd, + c_uint(F_DUPFD), + raw_fd(min) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_fcntl, + fd, + c_uint(F_DUPFD), + raw_fd(min) + )) + } +} + +#[inline] +pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result { + #[cfg(target_pointer_width = "32")] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_fcntl64, + fd, + c_uint(F_DUPFD_CLOEXEC), + raw_fd(min) + )) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_fcntl, + fd, + c_uint(F_DUPFD_CLOEXEC), + raw_fd(min) + )) + } +} + +#[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 { + 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::() + )) + } + #[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 { + 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 { + #[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 { + 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 { + 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 new file mode 100644 index 000000000..51ab61d94 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io/types.rs @@ -0,0 +1,128 @@ +use super::super::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 + pub struct FdFlags: c::c_uint { + /// `FD_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::FD_CLOEXEC; + } +} + +bitflags! { + /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`]. + /// + /// [`preadv2`]: crate::io::preadv2 + /// [`pwritev2`]: crate::io::pwritev + pub struct ReadWriteFlags: c::c_uint { + /// `RWF_DSYNC` (since Linux 4.7) + const DSYNC = linux_raw_sys::general::RWF_DSYNC; + /// `RWF_HIPRI` (since Linux 4.6) + const HIPRI = linux_raw_sys::general::RWF_HIPRI; + /// `RWF_SYNC` (since Linux 4.7) + const SYNC = linux_raw_sys::general::RWF_SYNC; + /// `RWF_NOWAIT` (since Linux 4.14) + const NOWAIT = linux_raw_sys::general::RWF_NOWAIT; + /// `RWF_APPEND` (since Linux 4.16) + const APPEND = linux_raw_sys::general::RWF_APPEND; + } +} + +#[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 + 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/mod.rs b/vendor/rustix/src/backend/linux_raw/io_uring/mod.rs new file mode 100644 index 000000000..ef944f04d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io_uring/mod.rs @@ -0,0 +1 @@ +pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs b/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs new file mode 100644 index 000000000..196676985 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/io_uring/syscalls.rs @@ -0,0 +1,63 @@ +//! linux_raw syscalls supporting `rustix::io_uring`. +//! +//! # Safety +//! +//! See the `rustix::backend::syscalls` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use super::super::conv::{by_mut, c_uint, pass_usize, ret, ret_c_uint, ret_owned_fd}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterOp}; +use core::ffi::c_void; + +#[inline] +pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result { + unsafe { + ret_owned_fd(syscall!( + __NR_io_uring_setup, + c_uint(entries), + by_mut(params) + )) + } +} + +#[inline] +pub(crate) unsafe fn io_uring_register( + fd: BorrowedFd<'_>, + opcode: IoringRegisterOp, + arg: *const c_void, + nr_args: u32, +) -> io::Result<()> { + ret(syscall_readonly!( + __NR_io_uring_register, + fd, + c_uint(opcode as u32), + arg, + c_uint(nr_args) + )) +} + +#[inline] +pub(crate) unsafe fn io_uring_enter( + fd: BorrowedFd<'_>, + to_submit: u32, + min_complete: u32, + flags: IoringEnterFlags, + arg: *const c_void, + size: usize, +) -> io::Result { + // This is not `_readonly` because `io_uring_enter` waits for I/O to + // complete, and I/O could involve writing to memory buffers, which + // could be a side effect depended on by the caller. + ret_c_uint(syscall!( + __NR_io_uring_enter, + fd, + c_uint(to_submit), + c_uint(min_complete), + flags, + arg, + pass_usize(size) + )) +} diff --git a/vendor/rustix/src/backend/linux_raw/mm/mod.rs b/vendor/rustix/src/backend/linux_raw/mm/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/mm/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs new file mode 100644 index 000000000..8fa6a3ec3 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/mm/syscalls.rs @@ -0,0 +1,214 @@ +//! linux_raw syscalls supporting `rustix::io`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![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::fd::{BorrowedFd, OwnedFd}; +use crate::io; +#[cfg(target_pointer_width = "32")] +use core::convert::TryInto; +use linux_raw_sys::general::MAP_ANONYMOUS; + +#[inline] +pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { + unsafe { + ret(syscall!( + __NR_madvise, + addr, + pass_usize(len), + c_uint(advice as c::c_uint) + )) + } +} + +#[inline] +pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { + ret(syscall!(__NR_msync, addr, pass_usize(len), flags)) +} + +/// # Safety +/// +/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working +/// with memory pointed to by raw pointers is unsafe. +#[inline] +pub(crate) unsafe fn mmap( + addr: *mut c::c_void, + length: usize, + prot: ProtFlags, + flags: MapFlags, + fd: BorrowedFd<'_>, + offset: u64, +) -> io::Result<*mut c::c_void> { + #[cfg(target_pointer_width = "32")] + { + ret_void_star(syscall!( + __NR_mmap2, + addr, + pass_usize(length), + prot, + flags, + fd, + (offset / 4096) + .try_into() + .map(pass_usize) + .map_err(|_| io::Errno::INVAL)? + )) + } + #[cfg(target_pointer_width = "64")] + { + ret_void_star(syscall!( + __NR_mmap, + addr, + pass_usize(length), + prot, + flags, + fd, + loff_t_from_u64(offset) + )) + } +} + +/// # Safety +/// +/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working +/// with memory pointed to by raw pointers is unsafe. +#[inline] +pub(crate) unsafe fn mmap_anonymous( + addr: *mut c::c_void, + length: usize, + prot: ProtFlags, + flags: MapFlags, +) -> io::Result<*mut c::c_void> { + #[cfg(target_pointer_width = "32")] + { + ret_void_star(syscall!( + __NR_mmap2, + addr, + pass_usize(length), + prot, + c_uint(flags.bits() | MAP_ANONYMOUS), + no_fd(), + pass_usize(0) + )) + } + #[cfg(target_pointer_width = "64")] + { + ret_void_star(syscall!( + __NR_mmap, + addr, + pass_usize(length), + prot, + c_uint(flags.bits() | MAP_ANONYMOUS), + no_fd(), + loff_t_from_u64(0) + )) + } +} + +#[inline] +pub(crate) unsafe fn mprotect( + ptr: *mut c::c_void, + len: usize, + flags: MprotectFlags, +) -> io::Result<()> { + ret(syscall!(__NR_mprotect, ptr, pass_usize(len), flags)) +} + +/// # Safety +/// +/// `munmap` is primarily unsafe due to the `addr` parameter, as anything +/// working with memory pointed to by raw pointers is unsafe. +#[inline] +pub(crate) unsafe fn munmap(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(syscall!(__NR_munmap, addr, pass_usize(length))) +} + +/// # Safety +/// +/// `mremap` is primarily unsafe due to the `old_address` parameter, as +/// anything working with memory pointed to by raw pointers is unsafe. +#[inline] +pub(crate) unsafe fn mremap( + old_address: *mut c::c_void, + old_size: usize, + new_size: usize, + flags: MremapFlags, +) -> io::Result<*mut c::c_void> { + ret_void_star(syscall!( + __NR_mremap, + old_address, + pass_usize(old_size), + pass_usize(new_size), + flags + )) +} + +/// # Safety +/// +/// `mremap_fixed` is primarily unsafe due to the `old_address` and +/// `new_address` parameters, as anything working with memory pointed to by raw +/// pointers is unsafe. +#[inline] +pub(crate) unsafe fn mremap_fixed( + old_address: *mut c::c_void, + old_size: usize, + new_size: usize, + flags: MremapFlags, + new_address: *mut c::c_void, +) -> io::Result<*mut c::c_void> { + ret_void_star(syscall!( + __NR_mremap, + old_address, + pass_usize(old_size), + pass_usize(new_size), + flags, + new_address + )) +} + +/// # Safety +/// +/// `mlock` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(syscall!(__NR_mlock, addr, pass_usize(length))) +} + +/// # Safety +/// +/// `mlock_with` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn mlock_with( + addr: *mut c::c_void, + length: usize, + flags: MlockFlags, +) -> io::Result<()> { + ret(syscall!(__NR_mlock2, addr, pass_usize(length), flags)) +} + +/// # Safety +/// +/// `munlock` operates on raw pointers and may round out to the nearest page +/// boundaries. +#[inline] +pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { + ret(syscall!(__NR_munlock, addr, pass_usize(length))) +} + +#[inline] +pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result { + ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags)) +} diff --git a/vendor/rustix/src/backend/linux_raw/mm/types.rs b/vendor/rustix/src/backend/linux_raw/mm/types.rs new file mode 100644 index 000000000..a58dd76be --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/mm/types.rs @@ -0,0 +1,208 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `PROT_*` flags for use with [`mmap`]. + /// + /// For `PROT_NONE`, use `ProtFlags::empty()`. + /// + /// [`mmap`]: crate::io::mmap + pub struct ProtFlags: u32 { + /// `PROT_READ` + const READ = linux_raw_sys::general::PROT_READ; + /// `PROT_WRITE` + const WRITE = linux_raw_sys::general::PROT_WRITE; + /// `PROT_EXEC` + const EXEC = linux_raw_sys::general::PROT_EXEC; + } +} + +bitflags! { + /// `PROT_*` flags for use with [`mprotect`]. + /// + /// For `PROT_NONE`, use `MprotectFlags::empty()`. + /// + /// [`mprotect`]: crate::io::mprotect + pub struct MprotectFlags: u32 { + /// `PROT_READ` + const READ = linux_raw_sys::general::PROT_READ; + /// `PROT_WRITE` + const WRITE = linux_raw_sys::general::PROT_WRITE; + /// `PROT_EXEC` + const EXEC = linux_raw_sys::general::PROT_EXEC; + /// `PROT_GROWSUP` + const GROWSUP = linux_raw_sys::general::PROT_GROWSUP; + /// `PROT_GROWSDOWN` + const GROWSDOWN = linux_raw_sys::general::PROT_GROWSDOWN; + } +} + +bitflags! { + /// `MAP_*` flags for use with [`mmap`]. + /// + /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. + /// + /// [`mmap`]: crate::io::mmap + /// [`mmap_anonymous`]: crates::io::mmap_anonymous + pub struct MapFlags: u32 { + /// `MAP_SHARED` + const SHARED = linux_raw_sys::general::MAP_SHARED; + /// `MAP_SHARED_VALIDATE` (since Linux 4.15) + const SHARED_VALIDATE = linux_raw_sys::general::MAP_SHARED_VALIDATE; + /// `MAP_PRIVATE` + const PRIVATE = linux_raw_sys::general::MAP_PRIVATE; + /// `MAP_DENYWRITE` + const DENYWRITE = linux_raw_sys::general::MAP_DENYWRITE; + /// `MAP_FIXED` + const FIXED = linux_raw_sys::general::MAP_FIXED; + /// `MAP_FIXED_NOREPLACE` (since Linux 4.17) + const FIXED_NOREPLACE = linux_raw_sys::general::MAP_FIXED_NOREPLACE; + /// `MAP_GROWSDOWN` + const GROWSDOWN = linux_raw_sys::general::MAP_GROWSDOWN; + /// `MAP_HUGETLB` + const HUGETLB = linux_raw_sys::general::MAP_HUGETLB; + /// `MAP_HUGE_2MB` (since Linux 3.8) + const HUGE_2MB = linux_raw_sys::general::MAP_HUGE_2MB; + /// `MAP_HUGE_1GB` (since Linux 3.8) + const HUGE_1GB = linux_raw_sys::general::MAP_HUGE_1GB; + /// `MAP_LOCKED` + const LOCKED = linux_raw_sys::general::MAP_LOCKED; + /// `MAP_NORESERVE` + const NORESERVE = linux_raw_sys::general::MAP_NORESERVE; + /// `MAP_POPULATE` + const POPULATE = linux_raw_sys::general::MAP_POPULATE; + /// `MAP_STACK` + const STACK = linux_raw_sys::general::MAP_STACK; + /// `MAP_SYNC` (since Linux 4.15) + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + const SYNC = linux_raw_sys::general::MAP_SYNC; + /// `MAP_UNINITIALIZED` + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + const UNINITIALIZED = linux_raw_sys::general::MAP_UNINITIALIZED; + } +} + +bitflags! { + /// `MREMAP_*` flags for use with [`mremap`]. + /// + /// For `MREMAP_FIXED`, see [`mremap_fixed`]. + /// + /// [`mremap`]: crate::io::mremap + /// [`mremap_fixed`]: crate::io::mremap_fixed + pub struct MremapFlags: u32 { + /// `MREMAP_MAYMOVE` + const MAYMOVE = linux_raw_sys::general::MREMAP_MAYMOVE; + /// `MREMAP_DONTUNMAP` (since Linux 5.7) + const DONTUNMAP = linux_raw_sys::general::MREMAP_DONTUNMAP; + } +} + +bitflags! { + /// `MLOCK_*` flags for use with [`mlock_with`]. + /// + /// [`mlock_with`]: crate::io::mlock_with + pub struct MlockFlags: u32 { + /// `MLOCK_ONFAULT` + const ONFAULT = linux_raw_sys::general::MLOCK_ONFAULT; + } +} + +bitflags! { + /// `MS_*` flags for use with [`msync`]. + /// + /// [`msync`]: crate::io::msync + pub struct MsyncFlags: u32 { + /// `MS_SYNC`—Requests an update and waits for it to complete. + const SYNC = linux_raw_sys::general::MS_SYNC; + /// `MS_ASYNC`—Specifies that an update be scheduled, but the call + /// returns immediately. + const ASYNC = linux_raw_sys::general::MS_ASYNC; + /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same + /// file (so that they can be updated with the fresh values just + /// written). + const INVALIDATE = linux_raw_sys::general::MS_INVALIDATE; + } +} + +bitflags! { + /// `O_*` flags for use with [`userfaultfd`]. + /// + /// [`userfaultfd`]: crate::io::userfaultfd + pub struct UserfaultfdFlags: c::c_uint { + /// `O_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; + /// `O_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; + } +} + +/// `POSIX_MADV_*` constants for use with [`madvise`]. +/// +/// [`madvise`]: crate::mm::madvise +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(u32)] +#[non_exhaustive] +pub enum Advice { + /// `POSIX_MADV_NORMAL` + Normal = linux_raw_sys::general::MADV_NORMAL, + + /// `POSIX_MADV_SEQUENTIAL` + Sequential = linux_raw_sys::general::MADV_SEQUENTIAL, + + /// `POSIX_MADV_RANDOM` + Random = linux_raw_sys::general::MADV_RANDOM, + + /// `POSIX_MADV_WILLNEED` + WillNeed = linux_raw_sys::general::MADV_WILLNEED, + + /// `MADV_DONTNEED` + LinuxDontNeed = linux_raw_sys::general::MADV_DONTNEED, + + /// `MADV_FREE` (since Linux 4.5) + LinuxFree = linux_raw_sys::general::MADV_FREE, + /// `MADV_REMOVE` + LinuxRemove = linux_raw_sys::general::MADV_REMOVE, + /// `MADV_DONTFORK` + LinuxDontFork = linux_raw_sys::general::MADV_DONTFORK, + /// `MADV_DOFORK` + LinuxDoFork = linux_raw_sys::general::MADV_DOFORK, + /// `MADV_HWPOISON` + LinuxHwPoison = linux_raw_sys::general::MADV_HWPOISON, + /// `MADV_SOFT_OFFLINE` + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + LinuxSoftOffline = linux_raw_sys::general::MADV_SOFT_OFFLINE, + /// `MADV_MERGEABLE` + LinuxMergeable = linux_raw_sys::general::MADV_MERGEABLE, + /// `MADV_UNMERGEABLE` + LinuxUnmergeable = linux_raw_sys::general::MADV_UNMERGEABLE, + /// `MADV_HUGEPAGE` (since Linux 2.6.38) + LinuxHugepage = linux_raw_sys::general::MADV_HUGEPAGE, + /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) + LinuxNoHugepage = linux_raw_sys::general::MADV_NOHUGEPAGE, + /// `MADV_DONTDUMP` (since Linux 3.4) + LinuxDontDump = linux_raw_sys::general::MADV_DONTDUMP, + /// `MADV_DODUMP` (since Linux 3.4) + LinuxDoDump = linux_raw_sys::general::MADV_DODUMP, + /// `MADV_WIPEONFORK` (since Linux 4.14) + LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK, + /// `MADV_KEEPONFORK` (since Linux 4.14) + LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK, + /// `MADV_COLD` (since Linux 5.4) + LinuxCold = linux_raw_sys::general::MADV_COLD, + /// `MADV_PAGEOUT` (since Linux 5.4) + LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT, + /// `MADV_POPULATE_READ` (since Linux 5.14) + LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ, + /// `MADV_POPULATE_WRITE` (since Linux 5.14) + LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE, +} + +impl Advice { + /// `POSIX_MADV_DONTNEED` + /// + /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because + /// Linux's `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See + /// `LinuxDontNeed` for the Linux behavior. + #[allow(non_upper_case_globals)] + pub const DontNeed: Self = Self::Normal; +} diff --git a/vendor/rustix/src/backend/linux_raw/mod.rs b/vendor/rustix/src/backend/linux_raw/mod.rs new file mode 100644 index 000000000..231dc37b6 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/mod.rs @@ -0,0 +1,68 @@ +//! The linux_raw backend. +//! +//! This makes Linux syscalls directly, without going through libc. +//! +//! # Safety +//! +//! These files performs raw system calls, and sometimes passes them +//! uninitialized memory buffers. The signatures in this file are currently +//! manually maintained and must correspond with the signatures of the actual +//! Linux syscalls. +//! +//! Some of this could be auto-generated from the Linux header file +//! , but we often need more information than it provides, +//! such as which pointers are array slices, out parameters, or in-out +//! parameters, which integers are owned or borrowed file descriptors, etc. + +#[macro_use] +mod arch; +mod conv; +mod elf; +mod reg; +#[cfg(any(feature = "time", target_arch = "x86"))] +mod vdso; +#[cfg(any(feature = "time", target_arch = "x86"))] +mod vdso_wrappers; + +#[cfg(feature = "fs")] +pub(crate) mod fs; +pub(crate) mod io; +#[cfg(feature = "io_uring")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))] +pub(crate) mod io_uring; +#[cfg(feature = "mm")] +pub(crate) mod mm; +#[cfg(feature = "net")] +pub(crate) mod net; +#[cfg(any( + feature = "param", + feature = "runtime", + feature = "time", + target_arch = "x86", +))] +pub(crate) mod param; +pub(crate) mod process; +#[cfg(feature = "rand")] +pub(crate) mod rand; +#[cfg(feature = "runtime")] +pub(crate) mod runtime; +#[cfg(feature = "termios")] +pub(crate) mod termios; +#[cfg(feature = "thread")] +pub(crate) mod thread; +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}; +} + +#[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; diff --git a/vendor/rustix/src/backend/linux_raw/net/addr.rs b/vendor/rustix/src/backend/linux_raw/net/addr.rs new file mode 100644 index 000000000..d5683f34e --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/addr.rs @@ -0,0 +1,172 @@ +//! IPv4, IPv6, and Socket addresses. +//! +//! # Safety +//! +//! Linux's IPv6 type contains a union. +#![allow(unsafe_code)] + +use super::super::c; +use crate::ffi::CStr; +use crate::{io, path}; +use core::convert::TryInto; +use core::{fmt, slice}; + +/// `struct sockaddr_un` +#[derive(Clone)] +#[doc(alias = "sockaddr_un")] +pub struct SocketAddrUnix { + pub(crate) unix: c::sockaddr_un, + len: c::socklen_t, +} + +impl SocketAddrUnix { + /// Construct a new Unix-domain address from a filesystem path. + #[inline] + pub fn new(path: P) -> io::Result { + path.into_with_c_str(Self::_new) + } + + #[inline] + fn _new(path: &CStr) -> io::Result { + let mut unix = Self::init(); + let bytes = path.to_bytes_with_nul(); + if bytes.len() > unix.sun_path.len() { + return Err(io::Errno::NAMETOOLONG); + } + for (i, b) in bytes.iter().enumerate() { + unix.sun_path[i] = *b as c::c_char; + } + let len = offsetof_sun_path() + bytes.len(); + let len = len.try_into().unwrap(); + Ok(Self { unix, len }) + } + + /// Construct a new abstract Unix-domain address from a byte slice. + #[inline] + pub fn new_abstract_name(name: &[u8]) -> io::Result { + 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 len = offsetof_sun_path() + 1 + name.len(); + let len = len.try_into().unwrap(); + Ok(Self { unix, len }) + } + + fn init() -> c::sockaddr_un { + c::sockaddr_un { + sun_family: c::AF_UNIX as _, + sun_path: [0; 108], + } + } + + /// For a filesystem path address, return the path. + #[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 { + 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(), + ))) + } + } else { + None + } + } + + /// For an abstract address, return the identifier. + #[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 { + 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())) } + } else { + None + } + } + + #[inline] + pub(crate) fn addr_len(&self) -> c::socklen_t { + self.len + } + + #[inline] + pub(crate) fn len(&self) -> usize { + self.addr_len() as usize + } +} + +impl PartialEq for SocketAddrUnix { + #[inline] + fn eq(&self, other: &Self) -> bool { + let self_len = self.len() - offsetof_sun_path(); + let other_len = other.len() - offsetof_sun_path(); + self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) + } +} + +impl Eq for SocketAddrUnix {} + +impl PartialOrd for SocketAddrUnix { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + 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]) + } +} + +impl Ord for SocketAddrUnix { + #[inline] + fn cmp(&self, other: &Self) -> core::cmp::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 { + #[inline] + fn hash(&self, state: &mut H) { + let self_len = self.len() - offsetof_sun_path(); + self.unix.sun_path[..self_len].hash(state) + } +} + +impl fmt::Debug for SocketAddrUnix { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(path) = self.path() { + path.fmt(fmt) + } else if let Some(name) = self.abstract_name() { + name.fmt(fmt) + } else { + "(unnamed)".fmt(fmt) + } + } +} + +/// `struct sockaddr_storage` as a raw struct. +pub type SocketAddrStorage = c::sockaddr; + +/// Return the offset of the `sun_path` field of `sockaddr_un`. +#[inline] +pub(crate) fn offsetof_sun_path() -> usize { + let z = c::sockaddr_un { + sun_family: 0_u16, + sun_path: [0; 108], + }; + (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) +} diff --git a/vendor/rustix/src/backend/linux_raw/net/mod.rs b/vendor/rustix/src/backend/linux_raw/net/mod.rs new file mode 100644 index 000000000..f2273db1b --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/mod.rs @@ -0,0 +1,6 @@ +pub(crate) mod addr; +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/read_sockaddr.rs b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs new file mode 100644 index 000000000..b9bc09b96 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/read_sockaddr.rs @@ -0,0 +1,175 @@ +//! The BSD sockets API requires us to read the `ss_family` field before +//! we can interpret the rest of a `sockaddr` produced by the kernel. +#![allow(unsafe_code)] + +use super::super::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`. +#[repr(C)] +struct sockaddr_header { + ss_family: u16, +} + +/// Read the `ss_family` field from a socket address returned from the OS. +/// +/// # Safety +/// +/// `storage` must point to a valid socket address returned from the OS. +#[inline] +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::general::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { + ss_family: 0_u16, + __data: [0; 126_usize], + }, + }, + }, + }; + + (*storage.cast::()).ss_family +} + +/// Set the `ss_family` field of a socket address to `AF_UNSPEC`, so that we +/// can test for `AF_UNSPEC` to test whether it was stored to. +#[inline] +pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) { + (*storage.cast::()).ss_family = c::AF_UNSPEC as _; +} + +/// Read a socket address encoded in a platform-specific format. +/// +/// # Safety +/// +/// `storage` must point to valid socket address storage. +pub(crate) unsafe fn read_sockaddr( + storage: *const c::sockaddr, + len: usize, +) -> io::Result { + let offsetof_sun_path = super::addr::offsetof_sun_path(); + + if len < size_of::() { + return Err(io::Errno::INVAL); + } + match read_ss_family(storage).into() { + c::AF_INET => { + if len < size_of::() { + return Err(io::Errno::INVAL); + } + let decode = *storage.cast::(); + Ok(SocketAddrAny::V4(SocketAddrV4::new( + Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), + u16::from_be(decode.sin_port), + ))) + } + c::AF_INET6 => { + if len < size_of::() { + return Err(io::Errno::INVAL); + } + let decode = *storage.cast::(); + Ok(SocketAddrAny::V6(SocketAddrV6::new( + Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), + u16::from_be(decode.sin6_port), + u32::from_be(decode.sin6_flowinfo), + decode.sin6_scope_id, + ))) + } + c::AF_UNIX => { + if len < offsetof_sun_path { + return Err(io::Errno::INVAL); + } + if len == offsetof_sun_path { + Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..])?)) + } else { + let decode = *storage.cast::(); + assert_eq!( + decode.sun_path[len - 1 - offsetof_sun_path], + b'\0' as c::c_char + ); + Ok(SocketAddrAny::Unix(SocketAddrUnix::new( + decode.sun_path[..len - 1 - offsetof_sun_path] + .iter() + .map(|c| *c as u8) + .collect::>(), + )?)) + } + } + _ => Err(io::Errno::NOTSUP), + } +} + +/// Read a socket address returned from the OS. +/// +/// # Safety +/// +/// `storage` must point to a valid socket address returned from the OS. +pub(crate) unsafe fn maybe_read_sockaddr_os( + storage: *const c::sockaddr, + len: usize, +) -> Option { + if len == 0 { + None + } else { + Some(read_sockaddr_os(storage, len)) + } +} + +/// Read a socket address returned from the OS. +/// +/// # Safety +/// +/// `storage` must point to a valid socket address returned from the OS. +pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) -> SocketAddrAny { + let offsetof_sun_path = super::addr::offsetof_sun_path(); + + assert!(len >= size_of::()); + match read_ss_family(storage).into() { + c::AF_INET => { + assert!(len >= size_of::()); + let decode = *storage.cast::(); + SocketAddrAny::V4(SocketAddrV4::new( + Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), + u16::from_be(decode.sin_port), + )) + } + c::AF_INET6 => { + assert!(len >= size_of::()); + let decode = *storage.cast::(); + SocketAddrAny::V6(SocketAddrV6::new( + Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), + u16::from_be(decode.sin6_port), + u32::from_be(decode.sin6_flowinfo), + decode.sin6_scope_id, + )) + } + c::AF_UNIX => { + assert!(len >= offsetof_sun_path); + if len == offsetof_sun_path { + SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) + } else { + let decode = *storage.cast::(); + assert_eq!( + decode.sun_path[len - 1 - offsetof_sun_path], + b'\0' as c::c_char + ); + SocketAddrAny::Unix( + SocketAddrUnix::new( + decode.sun_path[..len - 1 - offsetof_sun_path] + .iter() + .map(|c| *c as u8) + .collect::>(), + ) + .unwrap(), + ) + } + } + other => unimplemented!("{:?}", other), + } +} diff --git a/vendor/rustix/src/backend/linux_raw/net/send_recv.rs b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs new file mode 100644 index 000000000..888e81e2b --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/send_recv.rs @@ -0,0 +1,42 @@ +use super::super::c; +use bitflags::bitflags; + +bitflags! { + /// `MSG_*` + pub struct SendFlags: u32 { + /// `MSG_CONFIRM` + const CONFIRM = c::MSG_CONFIRM; + /// `MSG_DONTROUTE` + const DONTROUTE = c::MSG_DONTROUTE; + /// `MSG_DONTWAIT` + const DONTWAIT = c::MSG_DONTWAIT; + /// `MSG_EOT` + const EOT = c::MSG_EOR; + /// `MSG_MORE` + const MORE = c::MSG_MORE; + /// `MSG_NOSIGNAL` + const NOSIGNAL = c::MSG_NOSIGNAL; + /// `MSG_OOB` + const OOB = c::MSG_OOB; + } +} + +bitflags! { + /// `MSG_*` + pub struct RecvFlags: u32 { + /// `MSG_CMSG_CLOEXEC` + const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; + /// `MSG_DONTWAIT` + const DONTWAIT = c::MSG_DONTWAIT; + /// `MSG_ERRQUEUE` + const ERRQUEUE = c::MSG_ERRQUEUE; + /// `MSG_OOB` + const OOB = c::MSG_OOB; + /// `MSG_PEEK` + const PEEK = c::MSG_PEEK; + /// `MSG_TRUNC` + const TRUNC = c::MSG_TRUNC; + /// `MSG_WAITALL` + const WAITALL = c::MSG_WAITALL; + } +} diff --git a/vendor/rustix/src/backend/linux_raw/net/syscalls.rs b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs new file mode 100644 index 000000000..7b9947a03 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/syscalls.rs @@ -0,0 +1,1248 @@ +//! linux_raw syscalls supporting `rustix::net`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![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::read_sockaddr::{initialize_family_to_unspec, maybe_read_sockaddr_os, read_sockaddr_os}; +use super::send_recv::{RecvFlags, SendFlags}; +use super::types::{AcceptFlags, AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; +use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; +use crate::fd::{BorrowedFd, OwnedFd}; +use crate::io; +use crate::net::{SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; +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::{ + 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, + }, +}; + +#[inline] +pub(crate) fn socket( + family: AddressFamily, + type_: SocketType, + protocol: Protocol, +) -> io::Result { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret_owned_fd(syscall_readonly!(__NR_socket, family, type_, protocol)) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SOCKET), + slice_just_addr::, _>(&[ + family.into(), + type_.into(), + protocol.into(), + ]) + )) + } +} + +#[inline] +pub(crate) fn socket_with( + family: AddressFamily, + type_: SocketType, + flags: SocketFlags, + protocol: Protocol, +) -> io::Result { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_socket, + family, + (type_, flags), + protocol + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SOCKET), + slice_just_addr::, _>(&[ + family.into(), + (type_, flags).into(), + protocol.into(), + ]) + )) + } +} + +#[inline] +pub(crate) fn socketpair( + family: AddressFamily, + type_: SocketType, + flags: SocketFlags, + protocol: Protocol, +) -> io::Result<(OwnedFd, OwnedFd)> { + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(syscall!( + __NR_socketpair, + family, + (type_, flags), + protocol, + &mut result + ))?; + let [fd0, fd1] = result.assume_init(); + Ok((fd0, fd1)) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_SOCKETPAIR), + slice_just_addr::, _>(&[ + family.into(), + (type_, flags).into(), + protocol.into(), + (&mut result).into(), + ]) + ))?; + let [fd0, fd1] = result.assume_init(); + Ok((fd0, fd1)) + } +} + +#[inline] +pub(crate) fn accept(fd: BorrowedFd<'_>) -> io::Result { + #[cfg(not(target_arch = "x86"))] + unsafe { + let fd = ret_owned_fd(syscall_readonly!(__NR_accept, fd, zero(), zero()))?; + Ok(fd) + } + #[cfg(target_arch = "x86")] + unsafe { + let fd = ret_owned_fd(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_ACCEPT), + slice_just_addr::, _>(&[fd.into(), zero(), zero()]) + ))?; + Ok(fd) + } +} + +#[inline] +pub(crate) fn accept_with(fd: BorrowedFd<'_>, flags: AcceptFlags) -> io::Result { + #[cfg(not(target_arch = "x86"))] + unsafe { + let fd = ret_owned_fd(syscall_readonly!(__NR_accept4, fd, zero(), zero(), flags))?; + Ok(fd) + } + #[cfg(target_arch = "x86")] + unsafe { + let fd = ret_owned_fd(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_ACCEPT4), + slice_just_addr::, _>(&[fd.into(), zero(), zero(), flags.into()]) + ))?; + Ok(fd) + } +} + +#[inline] +pub(crate) fn acceptfrom(fd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option)> { + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + let fd = ret_owned_fd(syscall!( + __NR_accept, + fd, + &mut storage, + by_mut(&mut addrlen) + ))?; + Ok(( + fd, + maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), + )) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + let fd = ret_owned_fd(syscall!( + __NR_socketcall, + x86_sys(SYS_ACCEPT), + slice_just_addr::, _>(&[ + fd.into(), + (&mut storage).into(), + by_mut(&mut addrlen), + ]) + ))?; + Ok(( + fd, + maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), + )) + } +} + +#[inline] +pub(crate) fn acceptfrom_with( + fd: BorrowedFd<'_>, + flags: AcceptFlags, +) -> io::Result<(OwnedFd, Option)> { + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + let fd = ret_owned_fd(syscall!( + __NR_accept4, + fd, + &mut storage, + by_mut(&mut addrlen), + flags + ))?; + Ok(( + fd, + maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), + )) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + let fd = ret_owned_fd(syscall!( + __NR_socketcall, + x86_sys(SYS_ACCEPT4), + slice_just_addr::, _>(&[ + fd.into(), + (&mut storage).into(), + by_mut(&mut addrlen), + flags.into(), + ]) + ))?; + Ok(( + fd, + maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), + )) + } +} + +#[inline] +pub(crate) fn shutdown(fd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_shutdown, + fd, + c_uint(how as c::c_uint) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SHUTDOWN), + slice_just_addr::, _>(&[fd.into(), c_uint(how as c::c_uint)]) + )) + } +} + +#[inline] +pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result { + let (buf_addr, buf_len) = slice(buf); + + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "riscv64", + target_arch = "x86", + target_arch = "x86_64", + )))] + unsafe { + ret_usize(syscall_readonly!(__NR_send, fd, buf_addr, buf_len, flags)) + } + #[cfg(any( + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "riscv64", + target_arch = "x86_64", + ))] + unsafe { + ret_usize(syscall_readonly!( + __NR_sendto, + fd, + buf_addr, + buf_len, + flags, + zero(), + zero() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_usize(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SEND), + slice_just_addr::, _>(&[fd.into(), buf_addr, buf_len, flags.into()]) + )) + } +} + +#[inline] +pub(crate) fn sendto_v4( + fd: BorrowedFd<'_>, + buf: &[u8], + flags: SendFlags, + addr: &SocketAddrV4, +) -> io::Result { + let (buf_addr, buf_len) = slice(buf); + + #[cfg(not(target_arch = "x86"))] + unsafe { + ret_usize(syscall_readonly!( + __NR_sendto, + fd, + buf_addr, + buf_len, + flags, + by_ref(&encode_sockaddr_v4(addr)), + size_of::() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_usize(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SENDTO), + slice_just_addr::, _>(&[ + fd.into(), + buf_addr, + buf_len, + flags.into(), + by_ref(&encode_sockaddr_v4(addr)), + size_of::(), + ]) + )) + } +} + +#[inline] +pub(crate) fn sendto_v6( + fd: BorrowedFd<'_>, + buf: &[u8], + flags: SendFlags, + addr: &SocketAddrV6, +) -> io::Result { + let (buf_addr, buf_len) = slice(buf); + + #[cfg(not(target_arch = "x86"))] + unsafe { + ret_usize(syscall_readonly!( + __NR_sendto, + fd, + buf_addr, + buf_len, + flags, + by_ref(&encode_sockaddr_v6(addr)), + size_of::() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_usize(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SENDTO), + slice_just_addr::, _>(&[ + fd.into(), + buf_addr, + buf_len, + flags.into(), + by_ref(&encode_sockaddr_v6(addr)), + size_of::(), + ]) + )) + } +} + +#[inline] +pub(crate) fn sendto_unix( + fd: BorrowedFd<'_>, + buf: &[u8], + flags: SendFlags, + addr: &SocketAddrUnix, +) -> io::Result { + let (buf_addr, buf_len) = slice(buf); + + #[cfg(not(target_arch = "x86"))] + unsafe { + ret_usize(syscall_readonly!( + __NR_sendto, + fd, + buf_addr, + buf_len, + flags, + by_ref(&addr.unix), + socklen_t(addr.addr_len()) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_usize(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SENDTO), + slice_just_addr::, _>(&[ + fd.into(), + buf_addr, + buf_len, + flags.into(), + by_ref(&addr.unix), + socklen_t(addr.addr_len()), + ]) + )) + } +} + +#[inline] +pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "riscv64", + target_arch = "x86", + target_arch = "x86_64", + )))] + unsafe { + ret_usize(syscall!(__NR_recv, fd, buf_addr_mut, buf_len, flags)) + } + #[cfg(any( + target_arch = "aarch64", + target_arch = "mips64", + target_arch = "riscv64", + target_arch = "x86_64", + ))] + unsafe { + ret_usize(syscall!( + __NR_recvfrom, + fd, + buf_addr_mut, + buf_len, + flags, + zero(), + zero() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_RECV), + slice_just_addr::, _>(&[ + fd.into(), + buf_addr_mut, + buf_len, + flags.into(), + ]) + )) + } +} + +#[inline] +pub(crate) fn recvfrom( + fd: BorrowedFd<'_>, + buf: &mut [u8], + flags: RecvFlags, +) -> io::Result<(usize, Option)> { + let (buf_addr_mut, buf_len) = slice_mut(buf); + + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + + unsafe { + // `recvfrom` does not write to the storage if the socket is + // connection-oriented sockets, so we initialize the family field to + // `AF_UNSPEC` so that we can detect this case. + initialize_family_to_unspec(storage.as_mut_ptr()); + + #[cfg(not(target_arch = "x86"))] + let nread = ret_usize(syscall!( + __NR_recvfrom, + fd, + buf_addr_mut, + buf_len, + flags, + &mut storage, + by_mut(&mut addrlen) + ))?; + #[cfg(target_arch = "x86")] + let nread = ret_usize(syscall!( + __NR_socketcall, + x86_sys(SYS_RECVFROM), + slice_just_addr::, _>(&[ + fd.into(), + buf_addr_mut, + buf_len, + flags.into(), + (&mut storage).into(), + by_mut(&mut addrlen), + ]) + ))?; + + Ok(( + nread, + maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), + )) + } +} + +#[inline] +pub(crate) fn getpeername(fd: BorrowedFd<'_>) -> io::Result> { + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + ret(syscall!( + __NR_getpeername, + fd, + &mut storage, + by_mut(&mut addrlen) + ))?; + Ok(maybe_read_sockaddr_os( + &storage.assume_init(), + addrlen.try_into().unwrap(), + )) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_GETPEERNAME), + slice_just_addr::, _>(&[ + fd.into(), + (&mut storage).into(), + by_mut(&mut addrlen), + ]) + ))?; + Ok(maybe_read_sockaddr_os( + &storage.assume_init(), + addrlen.try_into().unwrap(), + )) + } +} + +#[inline] +pub(crate) fn getsockname(fd: BorrowedFd<'_>) -> io::Result { + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + ret(syscall!( + __NR_getsockname, + fd, + &mut storage, + by_mut(&mut addrlen) + ))?; + Ok(read_sockaddr_os( + &storage.assume_init(), + addrlen.try_into().unwrap(), + )) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut addrlen = core::mem::size_of::() as socklen_t; + let mut storage = MaybeUninit::::uninit(); + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_GETSOCKNAME), + slice_just_addr::, _>(&[ + fd.into(), + (&mut storage).into(), + by_mut(&mut addrlen), + ]) + ))?; + Ok(read_sockaddr_os( + &storage.assume_init(), + addrlen.try_into().unwrap(), + )) + } +} + +#[inline] +pub(crate) fn bind_v4(fd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_bind, + fd, + by_ref(&encode_sockaddr_v4(addr)), + size_of::() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_BIND), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&encode_sockaddr_v4(addr)), + size_of::(), + ]) + )) + } +} + +#[inline] +pub(crate) fn bind_v6(fd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_bind, + fd, + by_ref(&encode_sockaddr_v6(addr)), + size_of::() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_BIND), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&encode_sockaddr_v6(addr)), + size_of::(), + ]) + )) + } +} + +#[inline] +pub(crate) fn bind_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_bind, + fd, + by_ref(&addr.unix), + socklen_t(addr.addr_len()) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_BIND), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&addr.unix), + socklen_t(addr.addr_len()), + ]) + )) + } +} + +#[inline] +pub(crate) fn connect_v4(fd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_connect, + fd, + by_ref(&encode_sockaddr_v4(addr)), + size_of::() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_CONNECT), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&encode_sockaddr_v4(addr)), + size_of::(), + ]) + )) + } +} + +#[inline] +pub(crate) fn connect_v6(fd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_connect, + fd, + by_ref(&encode_sockaddr_v6(addr)), + size_of::() + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_CONNECT), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&encode_sockaddr_v6(addr)), + size_of::(), + ]) + )) + } +} + +#[inline] +pub(crate) fn connect_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_connect, + fd, + by_ref(&addr.unix), + socklen_t(addr.addr_len()) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_CONNECT), + slice_just_addr::, _>(&[ + fd.into(), + by_ref(&addr.unix), + socklen_t(addr.addr_len()), + ]) + )) + } +} + +#[inline] +pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_LISTEN), + slice_just_addr::, _>(&[fd.into(), c_int(backlog)]) + )) + } +} + +pub(crate) mod sockopt { + use super::{c, BorrowedFd}; + use crate::io; + 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(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { + use super::*; + + let mut optlen = core::mem::size_of::(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + #[cfg(not(target_arch = "x86"))] + unsafe { + let mut value = MaybeUninit::::uninit(); + ret(syscall!( + __NR_getsockopt, + fd, + c_uint(level), + c_uint(optname), + &mut value, + by_mut(&mut optlen) + ))?; + + assert_eq!( + optlen as usize, + core::mem::size_of::(), + "unexpected getsockopt size" + ); + Ok(value.assume_init()) + } + #[cfg(target_arch = "x86")] + unsafe { + let mut value = MaybeUninit::::uninit(); + ret(syscall!( + __NR_socketcall, + x86_sys(SYS_GETSOCKOPT), + slice_just_addr::, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + (&mut value).into(), + by_mut(&mut optlen), + ]) + ))?; + assert_eq!( + optlen as usize, + core::mem::size_of::(), + "unexpected getsockopt size" + ); + Ok(value.assume_init()) + } + } + + #[inline] + fn setsockopt( + fd: BorrowedFd<'_>, + level: u32, + optname: u32, + value: T, + ) -> io::Result<()> { + use super::*; + + let optlen = core::mem::size_of::().try_into().unwrap(); + debug_assert!( + optlen as usize >= core::mem::size_of::(), + "Socket APIs don't ever use `bool` directly" + ); + + #[cfg(not(target_arch = "x86"))] + unsafe { + ret(syscall_readonly!( + __NR_setsockopt, + fd, + c_uint(level), + c_uint(optname), + by_ref(&value), + socklen_t(optlen) + )) + } + #[cfg(target_arch = "x86")] + unsafe { + ret(syscall_readonly!( + __NR_socketcall, + x86_sys(SYS_SETSOCKOPT), + slice_just_addr::, _>(&[ + fd.into(), + c_uint(level), + c_uint(optname), + by_ref(&value), + socklen_t(optlen), + ]) + )) + } + } + + #[inline] + pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) + } + + #[inline] + pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_REUSEADDR, + from_bool(reuseaddr), + ) + } + + #[inline] + pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { + setsockopt( + fd, + c::SOL_SOCKET as _, + c::SO_BROADCAST, + from_bool(broadcast), + ) + } + + #[inline] + pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) + } + + #[inline] + pub(crate) fn set_socket_linger( + fd: BorrowedFd<'_>, + linger: Option, + ) -> io::Result<()> { + // Convert `linger` to seconds, rounding up. + let l_linger = if let Some(linger) = linger { + let mut l_linger = linger.as_secs(); + if linger.subsec_nanos() != 0 { + l_linger = l_linger.checked_add(1).ok_or(io::Errno::INVAL)?; + } + l_linger.try_into().map_err(|_e| io::Errno::INVAL)? + } else { + 0 + }; + let linger = c::linger { + l_onoff: c::c_int::from(linger.is_some()), + l_linger, + }; + setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) + } + + #[inline] + pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { + 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 + }) + } + + #[inline] + pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { + setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) + } + + #[inline] + pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) + } + + #[inline] + pub(crate) fn set_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, + ) -> io::Result<()> { + let time = duration_to_linux(timeout)?; + let optname = match id { + Timeout::Recv => SO_RCVTIMEO_NEW, + Timeout::Send => SO_SNDTIMEO_NEW, + }; + match setsockopt(fd, c::SOL_SOCKET, optname, time) { + Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { + set_socket_timeout_old(fd, id, timeout) + } + otherwise => otherwise, + } + } + + /// Same as `set_socket_timeout` but uses `timeval` instead of + /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. + fn set_socket_timeout_old( + fd: BorrowedFd<'_>, + id: Timeout, + timeout: Option, + ) -> io::Result<()> { + let time = duration_to_linux_old(timeout)?; + let optname = match id { + Timeout::Recv => SO_RCVTIMEO_OLD, + Timeout::Send => SO_SNDTIMEO_OLD, + }; + setsockopt(fd, c::SOL_SOCKET, optname, time) + } + + #[inline] + pub(crate) fn get_socket_timeout( + fd: BorrowedFd<'_>, + id: Timeout, + ) -> io::Result> { + let optname = match id { + Timeout::Recv => SO_RCVTIMEO_NEW, + Timeout::Send => SO_SNDTIMEO_NEW, + }; + let time: __kernel_timespec = match getsockopt(fd, c::SOL_SOCKET, optname) { + Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { + return get_socket_timeout_old(fd, id) + } + otherwise => otherwise?, + }; + Ok(duration_from_linux(time)) + } + + /// Same as `get_socket_timeout` but uses `timeval` instead of + /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. + fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { + let optname = match id { + Timeout::Recv => SO_RCVTIMEO_OLD, + Timeout::Send => SO_SNDTIMEO_OLD, + }; + let time: timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; + Ok(duration_from_linux_old(time)) + } + + /// Convert a C `timespec` to a Rust `Option`. + #[inline] + fn duration_from_linux(time: __kernel_timespec) -> Option { + if time.tv_sec == 0 && time.tv_nsec == 0 { + None + } else { + Some( + Duration::from_secs(time.tv_sec as u64) + Duration::from_nanos(time.tv_nsec as u64), + ) + } + } + + /// Like `duration_from_linux` but uses Linux's old 32-bit `timeval`. + fn duration_from_linux_old(time: timeval) -> Option { + if time.tv_sec == 0 && time.tv_usec == 0 { + None + } else { + Some( + Duration::from_secs(time.tv_sec as u64) + + Duration::from_micros(time.tv_usec as u64), + ) + } + } + + /// Convert a Rust `Option` to a C `timespec`. + #[inline] + fn duration_to_linux(timeout: Option) -> io::Result<__kernel_timespec> { + Ok(match timeout { + Some(timeout) => { + if timeout == DURATION_ZERO { + return Err(io::Errno::INVAL); + } + let mut timeout = __kernel_timespec { + tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), + tv_nsec: timeout.subsec_nanos().into(), + }; + if timeout.tv_sec == 0 && timeout.tv_nsec == 0 { + timeout.tv_nsec = 1; + } + timeout + } + None => __kernel_timespec { + tv_sec: 0, + tv_nsec: 0, + }, + }) + } + + /// Like `duration_to_linux` but uses Linux's old 32-bit `timeval`. + fn duration_to_linux_old(timeout: Option) -> io::Result { + Ok(match timeout { + Some(timeout) => { + if timeout == DURATION_ZERO { + return Err(io::Errno::INVAL); + } + + // `subsec_micros` rounds down, so we use `subsec_nanos` and + // manually round up. + let mut timeout = timeval { + tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), + tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => timeval { + tv_sec: 0, + tv_usec: 0, + }, + }) + } + + #[inline] + pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) + } + + #[inline] + pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) + } + + #[inline] + pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) + } + + #[inline] + pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) + } + + #[inline] + pub(crate) fn set_ip_multicast_loop( + fd: BorrowedFd<'_>, + multicast_loop: bool, + ) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IP_MULTICAST_LOOP, + from_bool(multicast_loop), + ) + } + + #[inline] + pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) + } + + #[inline] + pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) + } + + #[inline] + pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) + } + + #[inline] + pub(crate) fn set_ipv6_multicast_loop( + fd: BorrowedFd<'_>, + multicast_loop: bool, + ) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IPV6 as _, + c::IPV6_MULTICAST_LOOP, + from_bool(multicast_loop), + ) + } + + #[inline] + pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) + } + + #[inline] + pub(crate) fn set_ipv6_multicast_hops( + fd: BorrowedFd<'_>, + multicast_hops: u32, + ) -> io::Result<()> { + setsockopt( + fd, + c::IPPROTO_IP as _, + c::IPV6_MULTICAST_LOOP, + multicast_hops, + ) + } + + #[inline] + pub(crate) fn get_ipv6_multicast_hops(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_IP as _, c::IPV6_MULTICAST_LOOP) + } + + #[inline] + pub(crate) fn set_ip_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + ) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_ipv6_add_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, + ) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_ip_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv4Addr, + interface: &Ipv4Addr, + ) -> io::Result<()> { + let mreq = to_imr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_ipv6_drop_membership( + fd: BorrowedFd<'_>, + multiaddr: &Ipv6Addr, + interface: u32, + ) -> io::Result<()> { + let mreq = to_ipv6mr(multiaddr, interface); + setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) + } + + #[inline] + pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { + setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) + } + + #[inline] + pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { + getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) + } + + #[inline] + fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { + c::ip_mreq { + imr_multiaddr: to_imr_addr(multiaddr), + imr_interface: to_imr_addr(interface), + } + } + + #[inline] + fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { + c::in_addr { + s_addr: u32::from_ne_bytes(addr.octets()), + } + } + + #[inline] + fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { + c::ipv6_mreq { + ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), + ipv6mr_ifindex: to_ipv6mr_interface(interface), + } + } + + #[inline] + fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { + c::in6_addr { + in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { + u6_addr8: multiaddr.octets(), + }, + } + } + + #[inline] + fn to_ipv6mr_interface(interface: u32) -> c::c_int { + interface as c::c_int + } + + #[inline] + fn from_bool(value: bool) -> c::c_uint { + c::c_uint::from(value) + } + + #[inline] + fn to_bool(value: c::c_uint) -> bool { + value != 0 + } +} diff --git a/vendor/rustix/src/backend/linux_raw/net/types.rs b/vendor/rustix/src/backend/linux_raw/net/types.rs new file mode 100644 index 000000000..b8f786b3f --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/types.rs @@ -0,0 +1,282 @@ +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] +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` + #[allow(non_upper_case_globals)] + 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_*` +#[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_WR`—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 [`accept_with`] and [`acceptfrom_with`]. + /// + /// [`accept_with`]: crate::net::accept_with + /// [`acceptfrom_with`]: crate::net::acceptfrom_with + pub struct AcceptFlags: c::c_uint { + /// `SOCK_NONBLOCK` + const NONBLOCK = c::O_NONBLOCK; + /// `SOCK_CLOEXEC` + const CLOEXEC = c::O_CLOEXEC; + } +} + +bitflags! { + /// `SOCK_*` constants for use with [`socket`]. + /// + /// [`socket`]: crate::net::socket + 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 new file mode 100644 index 000000000..17abd96a0 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/net/write_sockaddr.rs @@ -0,0 +1,60 @@ +//! The BSD sockets API requires us to read the `ss_family` field before +//! we can interpret the rest of a `sockaddr` produced by the kernel. +#![allow(unsafe_code)] + +use super::super::c; +use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; +use core::mem::size_of; + +pub(crate) unsafe fn write_sockaddr( + addr: &SocketAddrAny, + storage: *mut SocketAddrStorage, +) -> usize { + match addr { + SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage), + SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage), + SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage), + } +} + +pub(crate) unsafe fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { + c::sockaddr_in { + sin_family: c::AF_INET as _, + sin_port: u16::to_be(v4.port()), + sin_addr: c::in_addr { + s_addr: u32::from_ne_bytes(v4.ip().octets()), + }, + __pad: [0_u8; 8], + } +} + +unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize { + let encoded = encode_sockaddr_v4(v4); + core::ptr::write(storage.cast(), encoded); + size_of::() +} + +pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { + c::sockaddr_in6 { + sin6_family: c::AF_INET6 as _, + 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 { + u6_addr8: v6.ip().octets(), + }, + }, + sin6_scope_id: v6.scope_id(), + } +} + +unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize { + let encoded = encode_sockaddr_v6(v6); + core::ptr::write(storage.cast(), encoded); + size_of::() +} + +unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize { + core::ptr::write(storage.cast(), unix.unix); + unix.len() +} diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs new file mode 100644 index 000000000..20a3d5da6 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/param/auxv.rs @@ -0,0 +1,370 @@ +//! Linux auxv support. +//! +//! # Safety +//! +//! 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::fd::OwnedFd; +#[cfg(feature = "param")] +use crate::ffi::CStr; +use crate::fs::{Mode, OFlags}; +use crate::utils::{as_ptr, check_raw_pointer}; +use alloc::vec::Vec; +use core::ffi::c_void; +use core::mem::size_of; +use core::ptr::{null_mut, read_unaligned, NonNull}; +#[cfg(feature = "runtime")] +use core::slice; +use core::sync::atomic::Ordering::Relaxed; +use core::sync::atomic::{AtomicPtr, AtomicUsize}; +use linux_raw_sys::general::{ + AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_PHDR, AT_PHENT, + AT_PHNUM, AT_SYSINFO_EHDR, +}; + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn page_size() -> usize { + let mut page_size = PAGE_SIZE.load(Relaxed); + + if page_size == 0 { + init_from_proc_self_auxv(); + page_size = PAGE_SIZE.load(Relaxed); + } + + page_size +} + +#[cfg(feature = "param")] +#[inline] +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(); + ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed); + } + + ticks as u64 +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn linux_hwcap() -> (usize, usize) { + let mut hwcap = HWCAP.load(Relaxed); + let mut hwcap2 = HWCAP2.load(Relaxed); + + if hwcap == 0 || hwcap2 == 0 { + init_from_proc_self_auxv(); + hwcap = HWCAP.load(Relaxed); + hwcap2 = HWCAP2.load(Relaxed); + } + + (hwcap, hwcap2) +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn linux_execfn() -> &'static CStr { + let mut execfn = EXECFN.load(Relaxed); + + if execfn.is_null() { + init_from_proc_self_auxv(); + execfn = EXECFN.load(Relaxed); + } + + // Safety: We assume the `AT_EXECFN` value provided by the kernel is a + // valid pointer to a valid NUL-terminated array of bytes. + unsafe { CStr::from_ptr(execfn.cast()) } +} + +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) { + let mut phdr = PHDR.load(Relaxed); + let mut phnum = PHNUM.load(Relaxed); + + if phdr.is_null() || phnum == 0 { + init_from_proc_self_auxv(); + phdr = PHDR.load(Relaxed); + phnum = PHNUM.load(Relaxed); + } + + (phdr.cast(), phnum) +} + +#[cfg(feature = "runtime")] +#[inline] +pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] { + let (phdr, phnum) = exe_phdrs(); + + // Safety: We assume the `AT_PHDR` and `AT_PHNUM` values provided by the + // kernel form a valid slice. + unsafe { slice::from_raw_parts(phdr.cast(), phnum) } +} + +/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, +/// so if we don't see it, this function returns a null pointer. +#[inline] +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(); + ehdr = SYSINFO_EHDR.load(Relaxed); + } + + ehdr +} + +static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0); +static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0); +static HWCAP: AtomicUsize = AtomicUsize::new(0); +static HWCAP2: AtomicUsize = AtomicUsize::new(0); +static SYSINFO_EHDR: AtomicPtr = AtomicPtr::new(null_mut()); +static PHDR: AtomicPtr = AtomicPtr::new(null_mut()); +static PHNUM: AtomicUsize = AtomicUsize::new(0); +static EXECFN: AtomicPtr = AtomicPtr::new(null_mut()); + +/// On non-Mustang platforms, we read the aux vector from /proc/self/auxv. +fn init_from_proc_self_auxv() { + // 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 _ = init_from_auxv_file(file); +} + +/// Process auxv entries from the open file `auxv`. +fn init_from_auxv_file(auxv: OwnedFd) -> Option<()> { + let mut buffer = Vec::::with_capacity(512); + loop { + let cur = buffer.len(); + + // Request one extra byte; `Vec` will often allocate more. + buffer.reserve(1); + + // Use all the space it allocated. + buffer.resize(buffer.capacity(), 0); + + // Read up to that many bytes. + let n = match crate::io::read(&auxv, &mut buffer[cur..]) { + Err(crate::io::Errno::INTR) => 0, + Err(_err) => panic!(), + Ok(0) => break, + Ok(n) => n, + }; + + // Account for the number of bytes actually read. + buffer.resize(cur + n, 0_u8); + } + + // Safety: We loaded from an auxv file into the buffer. + unsafe { init_from_auxp(buffer.as_ptr().cast()) } +} + +/// Process auxv entries from the auxv array pointed to by `auxp`. +/// +/// # Safety +/// +/// This must be passed a pointer to an auxv array. +/// +/// The buffer contains `Elf_aux_t` elements, though it need not be aligned; +/// function uses `read_unaligned` to read from it. +unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) -> Option<()> { + let mut pagesz = 0; + let mut clktck = 0; + let mut hwcap = 0; + let mut hwcap2 = 0; + let mut phdr = null_mut(); + let mut phnum = 0; + let mut execfn = null_mut(); + let mut sysinfo_ehdr = null_mut(); + let mut phent = 0; + + loop { + let Elf_auxv_t { a_type, a_val } = read_unaligned(auxp); + + match a_type as _ { + AT_PAGESZ => pagesz = a_val as usize, + AT_CLKTCK => clktck = a_val as usize, + AT_HWCAP => hwcap = a_val as usize, + AT_HWCAP2 => hwcap2 = a_val as usize, + AT_PHDR => phdr = check_raw_pointer::(a_val as *mut _)?.as_ptr(), + AT_PHNUM => phnum = a_val as usize, + AT_PHENT => phent = a_val as usize, + AT_EXECFN => execfn = check_raw_pointer::(a_val as *mut _)?.as_ptr(), + AT_BASE => check_interpreter_base(a_val.cast())?, + AT_SYSINFO_EHDR => sysinfo_ehdr = check_vdso_base(a_val as *mut _)?.as_ptr(), + AT_NULL => break, + _ => (), + } + auxp = auxp.add(1); + } + + assert_eq!(phent, size_of::()); + + // The base and sysinfo_ehdr (if present) matches our platform. Accept + // the aux values. + PAGE_SIZE.store(pagesz, Relaxed); + CLOCK_TICKS_PER_SECOND.store(clktck, Relaxed); + HWCAP.store(hwcap, Relaxed); + HWCAP2.store(hwcap2, Relaxed); + PHDR.store(phdr, Relaxed); + PHNUM.store(phnum, Relaxed); + EXECFN.store(execfn, Relaxed); + SYSINFO_EHDR.store(sysinfo_ehdr, Relaxed); + + Some(()) +} + +/// Check that `base` is a valid pointer to the program interpreter. +/// +/// `base` is some value we got from a `AT_BASE` aux record somewhere, +/// which hopefully holds the value of the program interpreter in memory. Do a +/// series of checks to be as sure as we can that it's safe to use. +unsafe fn check_interpreter_base(base: *const Elf_Ehdr) -> Option<()> { + check_elf_base(base)?; + Some(()) +} + +/// Check that `base` is a valid pointer to the kernel-provided vDSO. +/// +/// `base` is some value we got from a `AT_SYSINFO_EHDR` aux record somewhere, +/// which hopefully holds the value of the kernel-provided vDSO in memory. Do a +/// series of checks to be as sure as we can that it's safe to use. +unsafe fn check_vdso_base(base: *const Elf_Ehdr) -> Option> { + // In theory, we could check that we're not attempting to parse our own ELF + // image, as an additional check. However, older Linux toolchains don't + // support this, and Rust's `#[linkage = "extern_weak"]` isn't stable yet, + // so just disable this for now. + /* + { + extern "C" { + static __ehdr_start: c::c_void; + } + + let ehdr_start: *const c::c_void = &__ehdr_start; + if base == ehdr_start { + return None; + } + } + */ + + let hdr = check_elf_base(base)?; + + // Check that the ELF is not writable, since that would indicate that this + // isn't the ELF we think it is. Here we're just using `clock_getres` just + // 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}; + if ret(syscall!( + __NR_clock_getres, + c_uint(linux_raw_sys::general::CLOCK_MONOTONIC), + base + )) != Err(crate::io::Errno::FAULT) + { + // We can't gracefully fail here because we would seem to have just + // mutated some unknown memory. + #[cfg(feature = "std")] + { + std::process::abort(); + } + #[cfg(all(not(feature = "std"), feature = "rustc-dep-of-std"))] + { + core::intrinsics::abort(); + } + } + } + + Some(hdr) +} + +/// Check that `base` is a valid pointer to an ELF image. +unsafe fn check_elf_base(base: *const Elf_Ehdr) -> Option> { + // If we're reading a 64-bit auxv on a 32-bit platform, we'll see + // a zero `a_val` because `AT_*` values are never greater than + // `u32::MAX`. Zero is used by libc's `getauxval` to indicate + // errors, so it should never be a valid value. + if base.is_null() { + return None; + } + + let hdr = match check_raw_pointer::(base as *mut _) { + Some(hdr) => hdr, + None => return None, + }; + + let hdr = hdr.as_ref(); + if hdr.e_ident[..SELFMAG] != ELFMAG { + return None; // Wrong ELF magic + } + if !matches!(hdr.e_ident[EI_OSABI], ELFOSABI_SYSV | ELFOSABI_LINUX) { + return None; // Unrecognized ELF OS ABI + } + if hdr.e_ident[EI_ABIVERSION] != ELFABIVERSION { + return None; // Unrecognized ELF ABI version + } + if hdr.e_type != ET_DYN { + return None; // Wrong ELF type + } + + // If ELF is extended, we'll need to adjust. + if hdr.e_ident[EI_VERSION] != EV_CURRENT + || hdr.e_ehsize as usize != size_of::() + || hdr.e_phentsize as usize != size_of::() + { + return None; + } + // We don't currently support extra-large numbers of segments. + if hdr.e_phnum == PN_XNUM { + return None; + } + + // If `e_phoff` is zero, it's more likely that we're looking at memory that + // has been zeroed than that the kernel has somehow aliased the `Ehdr` and + // the `Phdr`. + if hdr.e_phoff < size_of::() { + return None; + } + + // Verify that the `EI_CLASS`/`EI_DATA`/`e_machine` fields match the + // architecture we're running as. This helps catch cases where we're + // running under QEMU. + if hdr.e_ident[EI_CLASS] != ELFCLASS { + return None; // Wrong ELF class + } + if hdr.e_ident[EI_DATA] != ELFDATA { + return None; // Wrong ELF data + } + if hdr.e_machine != EM_CURRENT { + return None; // Wrong machine type + } + + Some(NonNull::new_unchecked(as_ptr(hdr) as *mut _)) +} + +// ELF ABI + +#[repr(C)] +#[derive(Copy, Clone)] +struct Elf_auxv_t { + a_type: usize, + + // Some of the values in the auxv array are pointers, so we make `a_val` a + // pointer, in order to preserve their provenance. For the values which are + // integers, we cast this to `usize`. + a_val: *const c_void, +} diff --git a/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs new file mode 100644 index 000000000..1597fd727 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/param/libc_auxv.rs @@ -0,0 +1,74 @@ +//! Linux auxv support, using libc. +//! +//! # Safety +//! +//! This uses raw pointers to locate and read the kernel-provided auxv array. +#![allow(unsafe_code)] + +#[cfg(any(feature = "param", feature = "runtime"))] +use super::super::c; +use super::super::elf::*; +#[cfg(feature = "param")] +use crate::ffi::CStr; +#[cfg(feature = "runtime")] +use core::slice; + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn page_size() -> usize { + unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn clock_ticks_per_second() -> u64 { + unsafe { libc::getauxval(libc::AT_CLKTCK) as u64 } +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn linux_hwcap() -> (usize, usize) { + unsafe { + ( + libc::getauxval(libc::AT_HWCAP) as usize, + libc::getauxval(libc::AT_HWCAP2) as usize, + ) + } +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn linux_execfn() -> &'static CStr { + unsafe { + let execfn = libc::getauxval(libc::AT_EXECFN) as *const c::c_char; + CStr::from_ptr(execfn.cast()) + } +} + +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) { + unsafe { + ( + libc::getauxval(libc::AT_PHDR) as *const c::c_void, + libc::getauxval(libc::AT_PHNUM) as usize, + ) + } +} + +#[cfg(feature = "runtime")] +#[inline] +pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] { + let (phdr, phnum) = exe_phdrs(); + + // Safety: We assume the `AT_PHDR` and `AT_PHNUM` values provided by the + // kernel form a valid slice. + unsafe { slice::from_raw_parts(phdr.cast(), phnum) } +} + +/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, +/// so if we don't see it, this function returns a null pointer. +#[inline] +pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { + unsafe { libc::getauxval(linux_raw_sys::general::AT_SYSINFO_EHDR.into()) as *const Elf_Ehdr } +} diff --git a/vendor/rustix/src/backend/linux_raw/param/mod.rs b/vendor/rustix/src/backend/linux_raw/param/mod.rs new file mode 100644 index 000000000..956282074 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/param/mod.rs @@ -0,0 +1,12 @@ +// On Mustang, origin is in control of program startup and can access the +// incoming aux values on the stack. +// +// With "use-libc-auxv" enabled, use libc's `getauxval`. +// +// Otherwise, we read aux values from /proc/self/auxv. +#[cfg_attr(target_vendor = "mustang", path = "mustang_auxv.rs")] +#[cfg_attr( + all(not(target_vendor = "mustang"), feature = "use-libc-auxv"), + path = "libc_auxv.rs" +)] +pub(crate) mod auxv; diff --git a/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs b/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs new file mode 100644 index 000000000..e9b89b500 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/param/mustang_auxv.rs @@ -0,0 +1,159 @@ +//! Linux auxv support, for Mustang. +//! +//! # Safety +//! +//! This uses raw pointers to locate and read the kernel-provided auxv array. +#![allow(unsafe_code)] + +use super::super::c; +use super::super::elf::*; +#[cfg(feature = "param")] +use crate::ffi::CStr; +use core::ffi::c_void; +use core::mem::size_of; +use core::ptr::{null, read}; +#[cfg(feature = "runtime")] +use core::slice; +use linux_raw_sys::general::{ + AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_PHDR, AT_PHENT, AT_PHNUM, + AT_SYSINFO_EHDR, +}; + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn page_size() -> usize { + // Safety: This is initialized during program startup. + unsafe { PAGE_SIZE } +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn clock_ticks_per_second() -> u64 { + // Safety: This is initialized during program startup. + unsafe { CLOCK_TICKS_PER_SECOND as u64 } +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn linux_hwcap() -> (usize, usize) { + // Safety: This is initialized during program startup. + unsafe { (HWCAP, HWCAP2) } +} + +#[cfg(feature = "param")] +#[inline] +pub(crate) fn linux_execfn() -> &'static CStr { + // Safety: This is initialized during program startup. And we + // assume it's a valid pointer to a NUL-terminated string. + unsafe { CStr::from_ptr(EXECFN.0.cast()) } +} + +#[cfg(feature = "runtime")] +#[inline] +pub(crate) fn exe_phdrs() -> (*const c_void, usize) { + // Safety: This is initialized during program startup. + unsafe { (PHDR.0.cast(), PHNUM) } +} + +#[cfg(feature = "runtime")] +#[inline] +pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] { + let (phdr, phnum) = exe_phdrs(); + + // Safety: We assume the `AT_PHDR` and `AT_PHNUM` values provided by the + // kernel form a valid slice. + unsafe { slice::from_raw_parts(phdr.cast(), phnum) } +} + +/// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations, +/// so if we don't see it, this function returns a null pointer. +#[inline] +pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { + // Safety: This is initialized during program startup. + unsafe { SYSINFO_EHDR.0 } +} + +/// A const pointer to `T` that implements [`Sync`]. +#[repr(transparent)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct SyncConstPtr(*const T); +unsafe impl Sync for SyncConstPtr {} + +impl SyncConstPtr { + /// Creates a `SyncConstPointer` from a raw pointer. + /// + /// Behavior is undefined if `ptr` is actually not + /// safe to share across threads. + pub const unsafe fn new(ptr: *const T) -> Self { + Self(ptr) + } +} + +static mut PAGE_SIZE: usize = 0; +static mut CLOCK_TICKS_PER_SECOND: usize = 0; +static mut HWCAP: usize = 0; +static mut HWCAP2: usize = 0; +static mut SYSINFO_EHDR: SyncConstPtr = unsafe { SyncConstPtr::new(null()) }; +static mut PHDR: SyncConstPtr = unsafe { SyncConstPtr::new(null()) }; +static mut PHNUM: usize = 0; +static mut EXECFN: SyncConstPtr = unsafe { SyncConstPtr::new(null()) }; + +/// On mustang, we export a function to be called during initialization, and +/// passed a pointer to the original environment variable block set up by the +/// OS. +pub(crate) unsafe fn init(envp: *mut *mut u8) { + init_from_envp(envp); +} + +/// # Safety +/// +/// This must be passed a pointer to the environment variable buffer +/// provided by the kernel, which is followed in memory by the auxv array. +unsafe fn init_from_envp(mut envp: *mut *mut u8) { + while !(*envp).is_null() { + envp = envp.add(1); + } + init_from_auxp(envp.add(1).cast()) +} + +/// Process auxv entries from the auxv array pointed to by `auxp`. +/// +/// # Safety +/// +/// This must be passed a pointer to an auxv array. +/// +/// The buffer contains `Elf_aux_t` elements, though it need not be aligned; +/// function uses `read_unaligned` to read from it. +unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { + loop { + let Elf_auxv_t { a_type, a_val } = read(auxp); + + match a_type as _ { + AT_PAGESZ => PAGE_SIZE = a_val as usize, + AT_CLKTCK => CLOCK_TICKS_PER_SECOND = a_val as usize, + AT_HWCAP => HWCAP = a_val as usize, + AT_HWCAP2 => HWCAP2 = a_val as usize, + AT_PHDR => PHDR = SyncConstPtr::new(a_val.cast::()), + AT_PHNUM => PHNUM = a_val as usize, + AT_PHENT => assert_eq!(a_val as usize, size_of::()), + AT_EXECFN => EXECFN = SyncConstPtr::new(a_val.cast::()), + AT_SYSINFO_EHDR => SYSINFO_EHDR = SyncConstPtr::new(a_val.cast::()), + AT_NULL => break, + _ => (), + } + auxp = auxp.add(1); + } +} + +// ELF ABI + +#[repr(C)] +#[derive(Copy, Clone)] +struct Elf_auxv_t { + a_type: usize, + + // Some of the values in the auxv array are pointers, so we make `a_val` a + // pointer, in order to preserve their provenance. For the values which are + // integers, we cast this to `usize`. + a_val: *const c_void, +} diff --git a/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs b/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs new file mode 100644 index 000000000..10c5f478e --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/process/cpu_set.rs @@ -0,0 +1,47 @@ +#![allow(non_snake_case)] + +use super::types::RawCpuSet; +use core::mem::size_of_val; + +#[inline] +pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] |= 1 << offset +} + +#[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; + } +} + +#[inline] +pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); // 32, 64 etc + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + cpuset.bits[idx] &= !(1 << offset) +} + +#[inline] +pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { + let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); + let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); + (cpuset.bits[idx] & (1 << offset)) != 0 +} + +#[inline] +pub(crate) fn CPU_COUNT_S(size_in_bytes: usize, cpuset: &RawCpuSet) -> u32 { + let size_of_mask = size_of_val(&cpuset.bits[0]); + let idx = size_in_bytes / size_of_mask; + cpuset.bits[..idx] + .iter() + .fold(0, |acc, i| acc + i.count_ones()) +} + +#[inline] +pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { + CPU_COUNT_S(core::mem::size_of::(), cpuset) +} diff --git a/vendor/rustix/src/backend/linux_raw/process/mod.rs b/vendor/rustix/src/backend/linux_raw/process/mod.rs new file mode 100644 index 000000000..9b2c25f91 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/process/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod cpu_set; +pub(crate) mod syscalls; +pub(crate) mod types; +pub(crate) mod wait; diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs new file mode 100644 index 000000000..ac62e6944 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs @@ -0,0 +1,560 @@ +//! linux_raw syscalls supporting `rustix::process`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![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_just_addr, slice_mut, zero, +}; +use super::types::{RawCpuSet, RawUname}; +use crate::fd::BorrowedFd; +use crate::ffi::CStr; +use crate::io; +use crate::process::{ + Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, RawNonZeroPid, RawPid, Resource, Rlimit, + Signal, Uid, WaitOptions, WaitStatus, +}; +use core::convert::TryInto; +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, +}; + +#[inline] +pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_chdir, filename)) } +} + +#[inline] +pub(crate) fn fchdir(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_fchdir, fd)) } +} + +#[inline] +pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + unsafe { ret_usize(syscall!(__NR_getcwd, buf_addr_mut, buf_len)) } +} + +#[inline] +pub(crate) fn membarrier_query() -> MembarrierQuery { + unsafe { + match ret_c_uint(syscall!( + __NR_membarrier, + 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) + } + Err(_) => MembarrierQuery::empty(), + } + } +} + +#[inline] +pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { + unsafe { ret(syscall!(__NR_membarrier, cmd, c_uint(0))) } +} + +#[inline] +pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { + unsafe { + ret(syscall!( + __NR_membarrier, + cmd, + c_uint(membarrier_cmd_flag::MEMBARRIER_CMD_FLAG_CPU as _), + cpu + )) + } +} + +#[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 { + unsafe { + let ppid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getppid)) as __kernel_pid_t; + Pid::from_raw(ppid as u32) + } +} + +#[inline] +pub(crate) fn getpgid(pid: Option) -> io::Result { + 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, + ))) + } +} + +#[inline] +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; + debug_assert!(pgid > 0); + Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid as u32)) + } + + // 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; + 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) + } +} + +#[inline] +pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { + unsafe { + // The raw linux syscall returns the size (in bytes) of the `cpumask_t` + // data type that is used internally by the kernel to represent the CPU + // set bit mask. + let size = ret_usize(syscall!( + __NR_sched_getaffinity, + c_uint(Pid::as_raw(pid)), + size_of::(), + by_mut(&mut cpuset.bits) + ))?; + let bytes = (cpuset as *mut RawCpuSet).cast::(); + 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::() - size); + Ok(()) + } +} + +#[inline] +pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_sched_setaffinity, + c_uint(Pid::as_raw(pid)), + size_of::(), + slice_just_addr(&cpuset.bits) + )) + } +} + +#[inline] +pub(crate) fn sched_yield() { + unsafe { + // See the documentation for [`crate::process::sched_yield`] for why + // errors are ignored. + syscall_readonly!(__NR_sched_yield).decode_void(); + } +} + +#[inline] +pub(crate) fn uname() -> RawUname { + let mut uname = MaybeUninit::::uninit(); + unsafe { + ret(syscall!(__NR_uname, &mut uname)).unwrap(); + uname.assume_init() + } +} + +#[inline] +pub(crate) fn nice(inc: i32) -> io::Result { + 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); + setpriority_process(None, priority)?; + Ok(priority) +} + +#[inline] +pub(crate) fn getpriority_user(uid: Uid) -> io::Result { + unsafe { + Ok(20 + - ret_c_int(syscall_readonly!( + __NR_getpriority, + c_uint(PRIO_USER), + c_uint(uid.as_raw()) + ))?) + } +} + +#[inline] +pub(crate) fn getpriority_pgrp(pgid: Option) -> io::Result { + unsafe { + Ok(20 + - ret_c_int(syscall_readonly!( + __NR_getpriority, + c_uint(PRIO_PGRP), + c_uint(Pid::as_raw(pgid)) + ))?) + } +} + +#[inline] +pub(crate) fn getpriority_process(pid: Option) -> io::Result { + unsafe { + Ok(20 + - ret_c_int(syscall_readonly!( + __NR_getpriority, + c_uint(PRIO_PROCESS), + c_uint(Pid::as_raw(pid)) + ))?) + } +} + +#[inline] +pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_setpriority, + c_uint(PRIO_USER), + c_uint(uid.as_raw()), + c_int(priority) + )) + } +} + +#[inline] +pub(crate) fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_setpriority, + c_uint(PRIO_PGRP), + c_uint(Pid::as_raw(pgid)), + c_int(priority) + )) + } +} + +#[inline] +pub(crate) fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_setpriority, + c_uint(PRIO_PROCESS), + c_uint(Pid::as_raw(pid)), + c_int(priority) + )) + } +} + +#[inline] +pub(crate) fn getrlimit(limit: Resource) -> Rlimit { + let mut result = MaybeUninit::::uninit(); + unsafe { + match ret(syscall!( + __NR_prlimit64, + c_uint(0), + limit, + null::(), + &mut result + )) { + Ok(()) => rlimit_from_linux(result.assume_init()), + Err(err) => { + debug_assert_eq!(err, io::Errno::NOSYS); + getrlimit_old(limit) + } + } + } +} + +/// The old 32-bit-only `getrlimit` syscall, for when we lack the new +/// `prlimit64`. +unsafe fn getrlimit_old(limit: Resource) -> Rlimit { + let mut result = MaybeUninit::::uninit(); + + // On these platforms, `__NR_getrlimit` is called `__NR_ugetrlimit`. + #[cfg(any( + target_arch = "arm", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "x86", + ))] + { + ret_infallible(syscall!(__NR_ugetrlimit, limit, &mut result)); + } + + // On these platforms, it's just `__NR_getrlimit`. + #[cfg(not(any( + target_arch = "arm", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "x86", + )))] + { + ret_infallible(syscall!(__NR_getrlimit, limit, &mut result)); + } + + rlimit_from_linux_old(result.assume_init()) +} + +#[inline] +pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { + unsafe { + let lim = rlimit_to_linux(new.clone()); + match ret(syscall_readonly!( + __NR_prlimit64, + c_uint(0), + limit, + by_ref(&lim), + null_mut::() + )) { + Ok(()) => Ok(()), + Err(io::Errno::NOSYS) => setrlimit_old(limit, new), + Err(err) => Err(err), + } + } +} + +/// The old 32-bit-only `setrlimit` syscall, for when we lack the new +/// `prlimit64`. +unsafe fn setrlimit_old(limit: Resource, new: Rlimit) -> io::Result<()> { + let lim = rlimit_to_linux_old(new)?; + ret(syscall_readonly!(__NR_setrlimit, limit, by_ref(&lim))) +} + +#[inline] +pub(crate) fn prlimit(pid: Option, limit: Resource, new: Rlimit) -> io::Result { + let lim = rlimit_to_linux(new); + let mut result = MaybeUninit::::uninit(); + unsafe { + match ret(syscall!( + __NR_prlimit64, + c_uint(Pid::as_raw(pid)), + limit, + by_ref(&lim), + &mut result + )) { + Ok(()) => Ok(rlimit_from_linux(result.assume_init())), + Err(err) => Err(err), + } + } +} + +/// Convert a Rust [`Rlimit`] to a C `rlimit64`. +#[inline] +fn rlimit_from_linux(lim: rlimit64) -> Rlimit { + let current = if lim.rlim_cur == RLIM64_INFINITY as _ { + None + } else { + Some(lim.rlim_cur) + }; + let maximum = if lim.rlim_max == RLIM64_INFINITY as _ { + None + } else { + Some(lim.rlim_max) + }; + Rlimit { current, maximum } +} + +/// Convert a C `rlimit64` to a Rust `Rlimit`. +#[inline] +fn rlimit_to_linux(lim: Rlimit) -> rlimit64 { + let rlim_cur = match lim.current { + Some(r) => r, + None => RLIM64_INFINITY as _, + }; + let rlim_max = match lim.maximum { + Some(r) => r, + None => RLIM64_INFINITY as _, + }; + rlimit64 { rlim_cur, rlim_max } +} + +/// Like `rlimit_from_linux` but uses Linux's old 32-bit `rlimit`. +#[allow(clippy::useless_conversion)] +fn rlimit_from_linux_old(lim: rlimit) -> Rlimit { + let current = if lim.rlim_cur == RLIM_INFINITY as _ { + None + } else { + Some(lim.rlim_cur.into()) + }; + let maximum = if lim.rlim_max == RLIM_INFINITY as _ { + None + } else { + Some(lim.rlim_max.into()) + }; + Rlimit { current, maximum } +} + +/// Like `rlimit_to_linux` but uses Linux's old 32-bit `rlimit`. +#[allow(clippy::useless_conversion)] +fn rlimit_to_linux_old(lim: Rlimit) -> io::Result { + let rlim_cur = match lim.current { + Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, + None => RLIM_INFINITY as _, + }; + let rlim_max = match lim.maximum { + Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, + None => RLIM_INFINITY as _, + }; + Ok(rlimit { rlim_cur, rlim_max }) +} + +#[inline] +pub(crate) fn wait(waitopts: WaitOptions) -> io::Result> { + _waitpid(!0, waitopts) +} + +#[inline] +pub(crate) fn waitpid( + pid: Option, + waitopts: WaitOptions, +) -> io::Result> { + _waitpid(Pid::as_raw(pid), waitopts) +} + +#[inline] +pub(crate) fn _waitpid( + pid: RawPid, + waitopts: WaitOptions, +) -> io::Result> { + unsafe { + let mut status = MaybeUninit::::uninit(); + let pid = ret_c_uint(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()), + ) + })) + } +} + +#[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 setsid() -> io::Result { + unsafe { + let pid = ret_usize(syscall_readonly!(__NR_setsid))?; + debug_assert!(pid > 0); + Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( + pid as u32, + ))) + } +} + +#[inline] +pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_kill, pid, sig)) } +} + +#[inline] +pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_kill, negative_pid(pid), sig)) } +} + +#[inline] +pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_kill, pass_usize(0), sig)) } +} + +#[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 { + ret_c_int(syscall!(__NR_prctl, c_int(option), arg2, arg3, arg4, arg5)) +} diff --git a/vendor/rustix/src/backend/linux_raw/process/types.rs b/vendor/rustix/src/backend/linux_raw/process/types.rs new file mode 100644 index 000000000..53e2c7db1 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/process/types.rs @@ -0,0 +1,246 @@ +use super::super::c; +use linux_raw_sys::general::membarrier_cmd; + +/// A command for use with [`membarrier`] and [`membarrier_cpu`]. +/// +/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. +/// +/// [`membarrier`]: crate::process::membarrier +/// [`membarrier_cpu`]: crate::process::membarrier_cpu +/// [`membarrier_query`]: crate::process::membarrier_query +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[repr(u32)] +pub enum MembarrierCommand { + /// `MEMBARRIER_CMD_GLOBAL` + #[doc(alias = "Shared")] + #[doc(alias = "MEMBARRIER_CMD_SHARED")] + Global = membarrier_cmd::MEMBARRIER_CMD_GLOBAL as _, + /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` + GlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_GLOBAL_EXPEDITED as _, + /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` + RegisterGlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as _, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` + PrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED as _, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` + RegisterPrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as _, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` + PrivateExpeditedSyncCore = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as _, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` + RegisterPrivateExpeditedSyncCore = + membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as _, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + PrivateExpeditedRseq = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as _, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + RegisterPrivateExpeditedRseq = + membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as _, +} + +/// A resource value for use with [`getrlimit`], [`setrlimit`], and +/// [`prlimit`]. +/// +/// [`getrlimit`]: crate::process::getrlimit +/// [`setrlimit`]: crate::process::setrlimit +/// [`prlimit`]: crate::process::prlimit +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum Resource { + /// `RLIMIT_CPU` + Cpu = linux_raw_sys::general::RLIMIT_CPU, + /// `RLIMIT_FSIZE` + Fsize = linux_raw_sys::general::RLIMIT_FSIZE, + /// `RLIMIT_DATA` + Data = linux_raw_sys::general::RLIMIT_DATA, + /// `RLIMIT_STACK` + Stack = linux_raw_sys::general::RLIMIT_STACK, + /// `RLIMIT_CORE` + Core = linux_raw_sys::general::RLIMIT_CORE, + /// `RLIMIT_RSS` + Rss = linux_raw_sys::general::RLIMIT_RSS, + /// `RLIMIT_NPROC` + Nproc = linux_raw_sys::general::RLIMIT_NPROC, + /// `RLIMIT_NOFILE` + Nofile = linux_raw_sys::general::RLIMIT_NOFILE, + /// `RLIMIT_MEMLOCK` + Memlock = linux_raw_sys::general::RLIMIT_MEMLOCK, + /// `RLIMIT_AS` + As = linux_raw_sys::general::RLIMIT_AS, + /// `RLIMIT_LOCKS` + Locks = linux_raw_sys::general::RLIMIT_LOCKS, + /// `RLIMIT_SIGPENDING` + Sigpending = linux_raw_sys::general::RLIMIT_SIGPENDING, + /// `RLIMIT_MSGQUEUE` + Msgqueue = linux_raw_sys::general::RLIMIT_MSGQUEUE, + /// `RLIMIT_NICE` + Nice = linux_raw_sys::general::RLIMIT_NICE, + /// `RLIMIT_RTPRIO` + Rtprio = linux_raw_sys::general::RLIMIT_RTPRIO, + /// `RLIMIT_RTTIME` + Rttime = linux_raw_sys::general::RLIMIT_RTTIME, +} + +/// A signal number for use with [`kill_process`] and [`kill_process_group`]. +/// +/// [`kill_process`]: crate::process::kill_process +/// [`kill_process_group`]: crate::process::kill_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 { + 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 `SIGABRT`. +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 { + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + pub(crate) bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] + pub(crate) bits: [u64; 16], +} + +#[inline] +pub(crate) fn raw_cpu_set_new() -> RawCpuSet { + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + { + RawCpuSet { bits: [0; 32] } + } + #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] + { + RawCpuSet { bits: [0; 16] } + } +} + +pub(crate) const CPU_SETSIZE: usize = 8 * core::mem::size_of::(); diff --git a/vendor/rustix/src/backend/linux_raw/process/wait.rs b/vendor/rustix/src/backend/linux_raw/process/wait.rs new file mode 100644 index 000000000..701b4ac0c --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/process/wait.rs @@ -0,0 +1,39 @@ +// The functions replacing the C macros use the same names as in libc. +#![allow(non_snake_case)] + +pub(crate) use linux_raw_sys::general::{WCONTINUED, WNOHANG, WUNTRACED}; + +#[inline] +pub(crate) fn WIFSTOPPED(status: u32) -> bool { + (status & 0xff) == 0x7f +} + +#[inline] +pub(crate) fn WSTOPSIG(status: u32) -> u32 { + (status >> 8) & 0xff +} + +#[inline] +pub(crate) fn WIFCONTINUED(status: u32) -> bool { + status == 0xffff +} + +#[inline] +pub(crate) fn WIFSIGNALED(status: u32) -> bool { + ((status & 0x7f) + 1) as i8 >= 2 +} + +#[inline] +pub(crate) fn WTERMSIG(status: u32) -> u32 { + status & 0x7f +} + +#[inline] +pub(crate) fn WIFEXITED(status: u32) -> bool { + (status & 0x7f) == 0 +} + +#[inline] +pub(crate) fn WEXITSTATUS(status: u32) -> u32 { + (status >> 8) & 0xff +} diff --git a/vendor/rustix/src/backend/linux_raw/rand/mod.rs b/vendor/rustix/src/backend/linux_raw/rand/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/rand/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs b/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs new file mode 100644 index 000000000..5533f75e0 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/rand/syscalls.rs @@ -0,0 +1,17 @@ +//! linux_raw syscalls supporting `rustix::rand`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use super::super::conv::{ret_usize, slice_mut}; +use crate::io; +use crate::rand::GetRandomFlags; + +#[inline] +pub(crate) fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result { + let (buf_addr_mut, buf_len) = slice_mut(buf); + unsafe { ret_usize(syscall!(__NR_getrandom, buf_addr_mut, buf_len, flags)) } +} diff --git a/vendor/rustix/src/backend/linux_raw/rand/types.rs b/vendor/rustix/src/backend/linux_raw/rand/types.rs new file mode 100644 index 000000000..75f17443e --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/rand/types.rs @@ -0,0 +1,15 @@ +use bitflags::bitflags; + +bitflags! { + /// `GRND_*` flags for use with [`getrandom`]. + /// + /// [`getrandom`]: crate::rand::getrandom + pub struct GetRandomFlags: u32 { + /// `GRND_RANDOM` + const RANDOM = linux_raw_sys::general::GRND_RANDOM; + /// `GRND_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::GRND_NONBLOCK; + /// `GRND_INSECURE` + const INSECURE = linux_raw_sys::general::GRND_INSECURE; + } +} diff --git a/vendor/rustix/src/backend/linux_raw/reg.rs b/vendor/rustix/src/backend/linux_raw/reg.rs new file mode 100644 index 000000000..afe99c5f4 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/reg.rs @@ -0,0 +1,258 @@ +//! Encapsulation for system call arguments and return values. +//! +//! The inline-asm and outline-asm code paths do some amount of reordering +//! of arguments; to ensure that we don't accidentally misroute an argument +//! or return value, we use distinct types for each argument index and +//! return value. +//! +//! # Safety +//! +//! The `ToAsm` and `FromAsm` traits are unsafe to use; they should only be +//! used by the syscall code which executes actual syscall machine +//! instructions. + +#![allow(unsafe_code)] + +use super::c; +use super::fd::RawFd; +use core::marker::PhantomData; + +pub(super) trait ToAsm: private::Sealed { + /// Convert `self` to a `usize` ready to be passed to a syscall + /// machine instruction. + /// + /// # Safety + /// + /// This should be used immediately before the syscall instruction, and + /// the returned value shouldn't be used for any other purpose. + #[must_use] + unsafe fn to_asm(self) -> *mut Opaque; +} + +pub(super) trait FromAsm: private::Sealed { + /// Convert `raw` from a value produced by a syscall machine instruction + /// into a `Self`. + /// + /// # Safety + /// + /// This should be used immediately after the syscall instruction, and + /// the operand value shouldn't be used for any other purpose. + #[must_use] + unsafe fn from_asm(raw: *mut Opaque) -> Self; +} + +/// To preserve provenance, syscall arguments and return values are passed as +/// pointer types. They need a type to point to, so we define a custom private +/// type, to prevent it from being used for anything else. +#[repr(transparent)] +pub(super) struct Opaque(c::c_void); + +// Argument numbers. +pub(super) struct A0(()); +pub(super) struct A1(()); +pub(super) struct A2(()); +pub(super) struct A3(()); +pub(super) struct A4(()); +pub(super) struct A5(()); +#[cfg(target_arch = "mips")] +pub(super) struct A6(()); +#[cfg(target_arch = "x86")] +pub(super) struct SocketArg; + +pub(super) trait ArgNumber: private::Sealed {} +impl ArgNumber for A0 {} +impl ArgNumber for A1 {} +impl ArgNumber for A2 {} +impl ArgNumber for A3 {} +impl ArgNumber for A4 {} +impl ArgNumber for A5 {} +#[cfg(target_arch = "mips")] +impl ArgNumber for A6 {} +#[cfg(target_arch = "x86")] +impl ArgNumber for SocketArg {} + +// Return value numbers. +pub(super) struct R0(()); + +pub(super) trait RetNumber: private::Sealed {} +impl RetNumber for R0 {} + +/// Syscall arguments use register-sized types. We use a newtype to +/// discourage accidental misuse of the raw integer values. +/// +/// This type doesn't implement `Clone` or `Copy`; it should be used exactly +/// once. And it has a lifetime to ensure that it doesn't outlive any resources +/// it might be pointing to. +#[repr(transparent)] +#[must_use] +pub(super) struct ArgReg<'a, Num: ArgNumber> { + raw: *mut Opaque, + _phantom: PhantomData<(&'a (), Num)>, +} + +impl<'a, Num: ArgNumber> ToAsm for ArgReg<'a, Num> { + #[inline] + unsafe fn to_asm(self) -> *mut Opaque { + self.raw + } +} + +/// Syscall return values use register-sized types. We use a newtype to +/// discourage accidental misuse of the raw integer values. +/// +/// This type doesn't implement `Clone` or `Copy`; it should be used exactly +/// once. +#[repr(transparent)] +#[must_use] +pub(super) struct RetReg { + raw: *mut Opaque, + _phantom: PhantomData, +} + +impl RetReg { + #[inline] + pub(super) fn decode_usize(self) -> usize { + debug_assert!(!(-4095..0).contains(&(self.raw as isize))); + self.raw as usize + } + + #[inline] + pub(super) fn decode_raw_fd(self) -> RawFd { + let bits = self.decode_usize(); + let raw_fd = bits as RawFd; + + // Converting `raw` to `RawFd` should be lossless. + debug_assert_eq!(raw_fd as usize, bits); + + raw_fd + } + + #[inline] + pub(super) fn decode_c_int(self) -> c::c_int { + let bits = self.decode_usize(); + let c_int_ = bits as c::c_int; + + // Converting `raw` to `c_int` should be lossless. + debug_assert_eq!(c_int_ as usize, bits); + + c_int_ + } + + #[inline] + pub(super) fn decode_c_uint(self) -> c::c_uint { + let bits = self.decode_usize(); + let c_uint_ = bits as c::c_uint; + + // Converting `raw` to `c_uint` should be lossless. + debug_assert_eq!(c_uint_ as usize, bits); + + c_uint_ + } + + #[inline] + pub(super) fn decode_void_star(self) -> *mut c::c_void { + self.raw.cast() + } + + #[cfg(target_pointer_width = "64")] + #[inline] + pub(super) fn decode_u64(self) -> u64 { + self.decode_usize() as u64 + } + + #[inline] + pub(super) fn decode_void(self) { + let ignore = self.decode_usize(); + debug_assert_eq!(ignore, 0); + } + + #[inline] + pub(super) fn decode_error_code(self) -> u16 { + let bits = self.raw as usize; + + // `raw` must be in `-4095..0`. Linux always returns errors in + // `-4095..0`, and we double-check it here. + debug_assert!((-4095..0).contains(&(bits as isize))); + + bits as u16 + } + + #[inline] + pub(super) fn is_nonzero(&self) -> bool { + !self.raw.is_null() + } + + #[inline] + pub(super) fn is_negative(&self) -> bool { + (self.raw as isize) < 0 + } + + #[inline] + pub(super) fn is_in_range(&self, range: core::ops::Range) -> bool { + range.contains(&(self.raw as isize)) + } +} + +impl FromAsm for RetReg { + #[inline] + unsafe fn from_asm(raw: *mut Opaque) -> Self { + Self { + raw, + _phantom: PhantomData, + } + } +} + +#[repr(transparent)] +pub(super) struct SyscallNumber<'a> { + nr: usize, + _phantom: PhantomData<&'a ()>, +} + +impl<'a> ToAsm for SyscallNumber<'a> { + #[inline] + unsafe fn to_asm(self) -> *mut Opaque { + self.nr as usize as *mut Opaque + } +} + +/// Encode a system call argument as an `ArgReg`. +#[inline] +pub(super) fn raw_arg<'a, Num: ArgNumber>(raw: *mut Opaque) -> ArgReg<'a, Num> { + ArgReg { + raw, + _phantom: PhantomData, + } +} + +/// Encode a system call number (a `__NR_*` constant) as a `SyscallNumber`. +#[inline] +pub(super) const fn nr<'a>(nr: u32) -> SyscallNumber<'a> { + SyscallNumber { + nr: nr as usize, + _phantom: PhantomData, + } +} + +/// Seal our various traits using the technique documented [here]. +/// +/// [here]: https://rust-lang.github.io/api-guidelines/future-proofing.html +mod private { + pub trait Sealed {} + + // Implement for those same types, but no others. + impl<'a, Num: super::ArgNumber> Sealed for super::ArgReg<'a, Num> {} + impl Sealed for super::RetReg {} + impl<'a> Sealed for super::SyscallNumber<'a> {} + impl Sealed for super::A0 {} + impl Sealed for super::A1 {} + impl Sealed for super::A2 {} + impl Sealed for super::A3 {} + impl Sealed for super::A4 {} + impl Sealed for super::A5 {} + #[cfg(target_arch = "mips")] + impl Sealed for super::A6 {} + #[cfg(target_arch = "x86")] + impl Sealed for super::SocketArg {} + impl Sealed for super::R0 {} +} diff --git a/vendor/rustix/src/backend/linux_raw/runtime/mod.rs b/vendor/rustix/src/backend/linux_raw/runtime/mod.rs new file mode 100644 index 000000000..0b48649ce --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/runtime/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod syscalls; +pub(crate) mod tls; diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs new file mode 100644 index 000000000..a331786f9 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs @@ -0,0 +1,107 @@ +//! linux_raw syscalls supporting `rustix::runtime`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use super::super::c; +#[cfg(target_arch = "x86")] +use super::super::conv::by_mut; +use super::super::conv::{c_int, c_uint, ret, ret_c_uint, ret_error, ret_usize_infallible, zero}; +#[cfg(feature = "fs")] +use crate::fd::BorrowedFd; +use crate::ffi::CStr; +#[cfg(feature = "fs")] +use crate::fs::AtFlags; +use crate::io; +use crate::process::{Pid, RawNonZeroPid}; +use linux_raw_sys::general::{__kernel_pid_t, PR_SET_NAME, SIGCHLD}; +#[cfg(target_arch = "x86_64")] +use {super::super::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; + +#[inline] +pub(crate) unsafe fn fork() -> io::Result> { + let pid = ret_c_uint(syscall_readonly!( + __NR_clone, + c_uint(SIGCHLD), + zero(), + zero(), + zero(), + zero() + ))?; + Ok(Pid::from_raw(pid)) +} + +#[cfg(feature = "fs")] +pub(crate) unsafe fn execveat( + dirfd: BorrowedFd<'_>, + path: &CStr, + args: *const *const u8, + env_vars: *const *const u8, + flags: AtFlags, +) -> io::Errno { + ret_error(syscall_readonly!( + __NR_execveat, + dirfd, + path, + args, + env_vars, + flags + )) +} + +pub(crate) unsafe fn execve( + path: &CStr, + args: *const *const u8, + env_vars: *const *const u8, +) -> io::Errno { + ret_error(syscall_readonly!(__NR_execve, path, args, env_vars)) +} + +pub(crate) mod tls { + #[cfg(target_arch = "x86")] + use super::super::tls::UserDesc; + use super::*; + + #[cfg(target_arch = "x86")] + #[inline] + pub(crate) unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { + ret(syscall!(__NR_set_thread_area, by_mut(u_info))) + } + + #[cfg(target_arch = "arm")] + #[inline] + pub(crate) unsafe fn arm_set_tls(data: *mut c::c_void) -> io::Result<()> { + ret(syscall_readonly!(__ARM_NR_set_tls, data)) + } + + #[cfg(target_arch = "x86_64")] + #[inline] + pub(crate) unsafe fn set_fs(data: *mut c::c_void) { + ret_infallible(syscall_readonly!( + __NR_arch_prctl, + c_uint(ARCH_SET_FS), + data + )) + } + + #[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)) + } + + #[inline] + pub(crate) unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { + ret(syscall_readonly!(__NR_prctl, c_uint(PR_SET_NAME), name)) + } + + #[inline] + pub(crate) fn exit_thread(code: c::c_int) -> ! { + unsafe { syscall_noreturn!(__NR_exit, 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 new file mode 100644 index 000000000..43ed25d7d --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/runtime/tls.rs @@ -0,0 +1,57 @@ +#![allow(unsafe_code)] + +use super::super::c; +use super::super::elf::*; +use super::super::param::auxv::exe_phdrs_slice; +use core::ptr::null; + +/// For use with [`set_thread_area`]. +/// +/// [`set_thread_area`]: crate::runtime::set_thread_area +#[cfg(target_arch = "x86")] +pub type UserDesc = linux_raw_sys::general::user_desc; + +pub(crate) fn startup_tls_info() -> StartupTlsInfo { + let mut base = null(); + let mut tls_phdr = null(); + let mut stack_size = 0; + + let phdrs = exe_phdrs_slice(); + + // Safety: We assume the phdr array pointer and length the kernel provided + // to the process describe a valid phdr array. + unsafe { + for phdr in phdrs { + match phdr.p_type { + PT_PHDR => base = phdrs.as_ptr().cast::().offset(-(phdr.p_vaddr as isize)), + PT_TLS => tls_phdr = phdr, + PT_GNU_STACK => stack_size = phdr.p_memsz, + _ => {} + } + } + + StartupTlsInfo { + addr: base.cast::().add((*tls_phdr).p_vaddr).cast(), + mem_size: (*tls_phdr).p_memsz, + file_size: (*tls_phdr).p_filesz, + align: (*tls_phdr).p_align, + stack_size, + } + } +} + +/// The values returned from [`startup_tls_info`]. +/// +/// [`startup_tls_info`]: crate::runtime::startup_tls_info +pub struct StartupTlsInfo { + /// The base address of the TLS segment. + pub addr: *const c::c_void, + /// The size of the memory region. + pub mem_size: usize, + /// The size beyond which all memory is zero-initialized. + pub file_size: usize, + /// The required alignment for the TLS segment. + pub align: usize, + /// The requested minimum size for stacks. + pub stack_size: usize, +} diff --git a/vendor/rustix/src/backend/linux_raw/termios/mod.rs b/vendor/rustix/src/backend/linux_raw/termios/mod.rs new file mode 100644 index 000000000..1e0181a99 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/termios/mod.rs @@ -0,0 +1,2 @@ +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 new file mode 100644 index 000000000..a8dda5f81 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/termios/syscalls.rs @@ -0,0 +1,252 @@ +//! linux_raw syscalls supporting `rustix::termios`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![allow(unsafe_code)] +#![allow(clippy::undocumented_unsafe_blocks)] + +use super::super::conv::{by_ref, c_uint, ret}; +use crate::fd::BorrowedFd; +use crate::io; +use crate::process::{Pid, RawNonZeroPid}; +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, +}; +#[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::ioctl::{ + TCFLSH, TCGETS, TCSBRK, TCSETS, TCXONC, TIOCGPGRP, TIOCGSID, TIOCGWINSZ, TIOCSPGRP, TIOCSWINSZ, +}; + +#[inline] +pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGWINSZ), &mut result))?; + Ok(result.assume_init()) + } +} + +#[inline] +pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + let mut result = MaybeUninit::::uninit(); + ret(syscall!(__NR_ioctl, fd, c_uint(TCGETS), &mut result))?; + Ok(result.assume_init()) + } +} + +#[inline] +pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result { + unsafe { + let mut result = MaybeUninit::<__kernel_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, + ))) + } +} + +#[inline] +pub(crate) fn tcsetattr( + fd: BorrowedFd, + optional_actions: OptionalActions, + termios: &Termios, +) -> 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] +pub(crate) fn tcsendbreak(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TCSBRK), c_uint(0))) } +} + +#[inline] +pub(crate) fn tcdrain(fd: BorrowedFd) -> io::Result<()> { + unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TCSBRK), c_uint(1))) } +} + +#[inline] +pub(crate) fn tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(TCFLSH), + c_uint(queue_selector as u32) + )) + } +} + +#[inline] +pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_ioctl, + fd, + c_uint(TCXONC), + c_uint(action as u32) + )) + } +} + +#[inline] +pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result { + unsafe { + let mut result = MaybeUninit::<__kernel_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, + ))) + } +} + +#[inline] +pub(crate) fn tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()> { + unsafe { + ret(syscall!( + __NR_ioctl, + fd, + c_uint(TIOCSWINSZ), + by_ref(&winsize) + )) + } +} + +#[inline] +pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { + unsafe { ret(syscall!(__NR_ioctl, fd, c_uint(TIOCSPGRP), pid)) } +} + +#[inline] +#[must_use] +#[allow(clippy::missing_const_for_fn)] +pub(crate) fn cfgetospeed(termios: &Termios) -> u32 { + termios.c_cflag & CBAUD +} + +#[inline] +#[must_use] +#[allow(clippy::missing_const_for_fn)] +pub(crate) fn cfgetispeed(termios: &Termios) -> u32 { + termios.c_cflag & CBAUD +} + +#[inline] +pub(crate) fn cfmakeraw(termios: &mut Termios) { + // From the Linux [`cfmakeraw` man page]: + // + // [`cfmakeraw` man 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; + + // Musl and glibc also do these: + termios.c_cc[VMIN] = 1; + termios.c_cc[VTIME] = 0; +} + +#[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; + Ok(()) +} + +#[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; + 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(()) +} + +#[inline] +pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { + // On error, Linux will return either `EINVAL` (2.6.32) or `ENOTTY` + // (otherwise), because we assume we're never passing an invalid + // file descriptor (which would get `EBADF`). Either way, an error + // means we don't have a tty. + tcgetwinsize(fd).is_ok() +} + +#[cfg(feature = "procfs")] +pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { + let fd_stat = super::super::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 { + return Err(crate::io::Errno::NOTTY); + } + + // Check that `fd` is really a tty. + tcgetwinsize(fd)?; + + // Get a fd to '/proc/self/fd'. + let proc_self_fd = io::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)?; + + // 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 + // adding a NUL terminator. + if r == buf.len() { + return Err(io::Errno::RANGE); + } + buf[r] = 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(); + + 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(crate::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 new file mode 100644 index 000000000..88db4e1c9 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/termios/types.rs @@ -0,0 +1,460 @@ +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. + Now = linux_raw_sys::general::TCSANOW, + + /// `TCSADRAIN`—Make the change after all output has been transmitted. + Drain = linux_raw_sys::general::TCSADRAIN, + + /// `TCSAFLUSH`—Discard any pending input and then make the change + /// after all output has been transmitted. + 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. + IFlush = linux_raw_sys::general::TCIFLUSH, + + /// `TCOFLUSH`—Flush data written but not transmitted. + OFlush = linux_raw_sys::general::TCOFLUSH, + + /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. + 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. + OOff = linux_raw_sys::general::TCOOFF, + + /// `TCOON`—Restart suspended output. + OOn = linux_raw_sys::general::TCOON, + + /// `TCIOFF`—Transmits a STOP byte. + IOff = linux_raw_sys::general::TCIOFF, + + /// `TCION`—Transmits a START byte. + IOn = linux_raw_sys::general::TCION, +} + +/// `struct termios` for use with [`tcgetattr`]. +/// +/// [`tcgetattr`]: crate::termios::tcgetattr +pub type Termios = linux_raw_sys::general::termios; + +/// `struct winsize` for use with [`tcgetwinsize`]. +/// +/// [`tcgetwinsize`]: crate::termios::tcgetwinsize +pub type Winsize = linux_raw_sys::general::winsize; + +/// `tcflag_t`—A type for the flags fields of [`Termios`]. +pub type Tcflag = linux_raw_sys::general::tcflag_t; + +/// `speed_t`—A return type for [`cfsetspeed`] and similar. +/// +/// [`cfsetspeed`]: crate::termios::cfsetspeed +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; + +/// `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 new file mode 100644 index 000000000..9e087f9f1 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/thread/futex.rs @@ -0,0 +1,39 @@ +bitflags::bitflags! { + /// Flags for use with [`futex`]. + /// + /// [`futex`]: crate::thread::futex + pub struct FutexFlags: u32 { + /// `FUTEX_PRIVATE_FLAG` + const PRIVATE = linux_raw_sys::general::FUTEX_PRIVATE_FLAG; + /// `FUTEX_CLOCK_REALTIME` + const CLOCK_REALTIME = linux_raw_sys::general::FUTEX_CLOCK_REALTIME; + } +} + +/// Operations for use with [`futex`]. +/// +/// [`futex`]: crate::thread::futex +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(u32)] +pub enum FutexOperation { + /// `FUTEX_WAIT` + Wait = linux_raw_sys::general::FUTEX_WAIT, + /// `FUTEX_WAKE` + Wake = linux_raw_sys::general::FUTEX_WAKE, + /// `FUTEX_FD` + Fd = linux_raw_sys::general::FUTEX_FD, + /// `FUTEX_REQUEUE` + Requeue = linux_raw_sys::general::FUTEX_REQUEUE, + /// `FUTEX_CMP_REQUEUE` + CmpRequeue = linux_raw_sys::general::FUTEX_CMP_REQUEUE, + /// `FUTEX_WAKE_OP` + WakeOp = linux_raw_sys::general::FUTEX_WAKE_OP, + /// `FUTEX_LOCK_PI` + LockPi = linux_raw_sys::general::FUTEX_LOCK_PI, + /// `FUTEX_UNLOCK_PI` + UnlockPi = linux_raw_sys::general::FUTEX_UNLOCK_PI, + /// `FUTEX_TRYLOCK_PI` + TrylockPi = linux_raw_sys::general::FUTEX_TRYLOCK_PI, + /// `FUTEX_WAIT_BITSET` + WaitBitset = linux_raw_sys::general::FUTEX_WAIT_BITSET, +} diff --git a/vendor/rustix/src/backend/linux_raw/thread/mod.rs b/vendor/rustix/src/backend/linux_raw/thread/mod.rs new file mode 100644 index 000000000..8bb80c33a --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/thread/mod.rs @@ -0,0 +1,4 @@ +mod futex; +pub(crate) mod syscalls; + +pub use futex::{FutexFlags, FutexOperation}; diff --git a/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs b/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs new file mode 100644 index 000000000..99c632e7e --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/thread/syscalls.rs @@ -0,0 +1,290 @@ +//! linux_raw syscalls supporting `rustix::thread`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![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::fd::BorrowedFd; +use crate::io; +use crate::process::{Pid, RawNonZeroPid}; +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, +}; + +#[inline] +pub(crate) fn clock_nanosleep_relative( + id: ClockId, + req: &__kernel_timespec, +) -> NanosleepRelativeResult { + #[cfg(target_pointer_width = "32")] + unsafe { + let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); + match ret(syscall!( + __NR_clock_nanosleep_time64, + id, + c_int(0), + by_ref(req), + &mut rem + )) + .or_else(|err| { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + if err == io::Errno::NOSYS { + clock_nanosleep_relative_old(id, req, &mut rem) + } else { + Err(err) + } + }) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), + Err(err) => NanosleepRelativeResult::Err(err), + } + } + #[cfg(target_pointer_width = "64")] + unsafe { + let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); + match ret(syscall!( + __NR_clock_nanosleep, + id, + c_int(0), + by_ref(req), + &mut rem + )) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), + Err(err) => NanosleepRelativeResult::Err(err), + } + } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn clock_nanosleep_relative_old( + id: ClockId, + req: &__kernel_timespec, + rem: &mut MaybeUninit<__kernel_timespec>, +) -> io::Result<()> { + let old_req = __kernel_old_timespec { + tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, + tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }; + let mut old_rem = MaybeUninit::<__kernel_old_timespec>::uninit(); + ret(syscall!( + __NR_clock_nanosleep, + id, + c_int(0), + 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(), + }, + ); + Ok(()) +} + +#[inline] +pub(crate) fn clock_nanosleep_absolute(id: ClockId, req: &__kernel_timespec) -> io::Result<()> { + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall_readonly!( + __NR_clock_nanosleep_time64, + id, + c_uint(TIMER_ABSTIME), + by_ref(req), + zero() + )) + .or_else(|err| { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + if err == io::Errno::NOSYS { + clock_nanosleep_absolute_old(id, req) + } else { + Err(err) + } + }) + } + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall_readonly!( + __NR_clock_nanosleep, + id, + c_uint(TIMER_ABSTIME), + by_ref(req), + zero() + )) + } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn clock_nanosleep_absolute_old(id: ClockId, req: &__kernel_timespec) -> io::Result<()> { + let old_req = __kernel_old_timespec { + tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, + tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }; + ret(syscall_readonly!( + __NR_clock_nanosleep, + id, + c_int(0), + by_ref(&old_req), + zero() + )) +} + +#[inline] +pub(crate) fn nanosleep(req: &__kernel_timespec) -> NanosleepRelativeResult { + #[cfg(target_pointer_width = "32")] + unsafe { + let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); + match ret(syscall!( + __NR_clock_nanosleep_time64, + ClockId::Realtime, + c_int(0), + by_ref(req), + &mut rem + )) + .or_else(|err| { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + if err == io::Errno::NOSYS { + nanosleep_old(req, &mut rem) + } else { + Err(err) + } + }) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), + Err(err) => NanosleepRelativeResult::Err(err), + } + } + #[cfg(target_pointer_width = "64")] + unsafe { + let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); + match ret(syscall!(__NR_nanosleep, by_ref(req), &mut rem)) { + Ok(()) => NanosleepRelativeResult::Ok, + Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), + Err(err) => NanosleepRelativeResult::Err(err), + } + } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn nanosleep_old( + req: &__kernel_timespec, + rem: &mut MaybeUninit<__kernel_timespec>, +) -> io::Result<()> { + let old_req = __kernel_old_timespec { + tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, + tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }; + 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(), + }, + ); + 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)) + } +} + +// TODO: This could be de-multiplexed. +#[inline] +pub(crate) unsafe fn futex( + uaddr: *mut u32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + utime: *const Timespec, + uaddr2: *mut u32, + val3: u32, +) -> io::Result { + #[cfg(target_pointer_width = "32")] + { + ret_usize(syscall!( + __NR_futex_time64, + uaddr, + (op, flags), + c_uint(val), + utime, + uaddr2, + c_uint(val3) + )) + .or_else(|err| { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + if err == io::Errno::NOSYS { + futex_old(uaddr, op, flags, val, utime, uaddr2, val3) + } else { + Err(err) + } + }) + } + #[cfg(target_pointer_width = "64")] + ret_usize(syscall!( + __NR_futex, + uaddr, + (op, flags), + c_uint(val), + utime, + uaddr2, + c_uint(val3) + )) +} + +#[cfg(target_pointer_width = "32")] +unsafe fn futex_old( + uaddr: *mut u32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + utime: *const Timespec, + uaddr2: *mut u32, + val3: u32, +) -> io::Result { + let old_utime = __kernel_old_timespec { + tv_sec: (*utime).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, + tv_nsec: (*utime).tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }; + ret_usize(syscall!( + __NR_futex, + uaddr, + (op, flags), + c_uint(val), + by_ref(&old_utime), + uaddr2, + c_uint(val3) + )) +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result { + unsafe { ret_c_int(syscall_readonly!(__NR_setns, fd, c_int(nstype))) } +} diff --git a/vendor/rustix/src/backend/linux_raw/time/mod.rs b/vendor/rustix/src/backend/linux_raw/time/mod.rs new file mode 100644 index 000000000..c42592c4f --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/time/mod.rs @@ -0,0 +1,3 @@ +#[cfg(any(feature = "time", target_arch = "x86"))] +pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/vendor/rustix/src/backend/linux_raw/time/syscalls.rs b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs new file mode 100644 index 000000000..6e73a921b --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/time/syscalls.rs @@ -0,0 +1,229 @@ +//! linux_raw syscalls supporting `rustix::time`. +//! +//! # Safety +//! +//! See the `rustix::backend` module documentation for details. +#![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::io; +#[cfg(feature = "time")] +use crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; +use core::mem::MaybeUninit; +use linux_raw_sys::general::__kernel_timespec; +#[cfg(feature = "time")] +#[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}; + +// `clock_gettime` has special optimizations via the vDSO. +#[cfg(feature = "time")] +pub(crate) use super::super::vdso_wrappers::{clock_gettime, clock_gettime_dynamic}; + +#[inline] +pub(crate) fn clock_getres(which_clock: ClockId) -> __kernel_timespec { + #[cfg(target_pointer_width = "32")] + unsafe { + let mut result = MaybeUninit::<__kernel_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. + debug_assert_eq!(err, io::Errno::NOSYS); + clock_getres_old(which_clock, &mut result); + } + result.assume_init() + } + #[cfg(target_pointer_width = "64")] + unsafe { + let mut result = MaybeUninit::<__kernel_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>) { + 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(), + }, + ); +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result { + unsafe { ret_owned_fd(syscall!(__NR_timerfd_create, clockid, flags)) } +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn timerfd_settime( + fd: BorrowedFd<'_>, + flags: TimerfdTimerFlags, + new_value: &Itimerspec, +) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall!( + __NR_timerfd_settime, + fd, + flags, + by_ref(new_value), + &mut result + ))?; + Ok(result.assume_init()) + } + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall!( + __NR_timerfd_settime64, + fd, + flags, + by_ref(new_value), + &mut result + )) + .or_else(|err| { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + if err == io::Errno::NOSYS { + timerfd_settime_old(fd, flags, new_value, &mut result) + } else { + Err(err) + } + })?; + Ok(result.assume_init()) + } +} + +#[cfg(feature = "time")] +#[cfg(target_pointer_width = "32")] +unsafe fn timerfd_settime_old( + fd: BorrowedFd<'_>, + flags: TimerfdTimerFlags, + new_value: &Itimerspec, + result: &mut MaybeUninit, +) -> io::Result<()> { + let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); + + // Convert `new_value` to the old `__kernel_old_itimerspec` format. + let old_new_value = __kernel_old_itimerspec { + it_interval: __kernel_old_timespec { + tv_sec: new_value + .it_interval + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: new_value + .it_interval + .tv_nsec + .try_into() + .map_err(|_| io::Errno::INVAL)?, + }, + it_value: __kernel_old_timespec { + tv_sec: new_value + .it_value + .tv_sec + .try_into() + .map_err(|_| io::Errno::OVERFLOW)?, + tv_nsec: new_value + .it_value + .tv_nsec + .try_into() + .map_err(|_| io::Errno::INVAL)?, + }, + }; + ret(syscall!( + __NR_timerfd_settime, + fd, + flags, + by_ref(&old_new_value), + &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(), + }, + }, + ); + Ok(()) +} + +#[cfg(feature = "time")] +#[inline] +pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result { + let mut result = MaybeUninit::::uninit(); + + #[cfg(target_pointer_width = "64")] + unsafe { + ret(syscall!(__NR_timerfd_gettime, fd, &mut result))?; + Ok(result.assume_init()) + } + + #[cfg(target_pointer_width = "32")] + unsafe { + ret(syscall!(__NR_timerfd_gettime64, fd, &mut result)).or_else(|err| { + // See the comments in `rustix_clock_gettime_via_syscall` about + // emulation. + if err == io::Errno::NOSYS { + timerfd_gettime_old(fd, &mut result) + } else { + Err(err) + } + })?; + Ok(result.assume_init()) + } +} + +#[cfg(feature = "time")] +#[cfg(target_pointer_width = "32")] +unsafe fn timerfd_gettime_old( + fd: BorrowedFd<'_>, + result: &mut MaybeUninit, +) -> io::Result<()> { + 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(), + }, + }, + ); + Ok(()) +} diff --git a/vendor/rustix/src/backend/linux_raw/time/types.rs b/vendor/rustix/src/backend/linux_raw/time/types.rs new file mode 100644 index 000000000..5a0fcc6f5 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/time/types.rs @@ -0,0 +1,154 @@ +use super::super::c; +use crate::fd::BorrowedFd; +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`]. +/// +/// [`timerfd_gettime`]: crate::time::timerfd_gettime +/// [`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 + pub struct TimerfdFlags: c::c_uint { + /// `TFD_NONBLOCK` + const NONBLOCK = linux_raw_sys::general::TFD_NONBLOCK; + + /// `TFD_CLOEXEC` + const CLOEXEC = linux_raw_sys::general::TFD_CLOEXEC; + } +} + +bitflags! { + /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. + /// + /// [`timerfd_settime`]: crate::time::timerfd_settime + pub struct TimerfdTimerFlags: c::c_uint { + /// `TFD_TIMER_ABSTIME` + const ABSTIME = linux_raw_sys::general::TFD_TIMER_ABSTIME; + + /// `TFD_TIMER_CANCEL_ON_SET` + const CANCEL_ON_SET = linux_raw_sys::general::TFD_TIMER_CANCEL_ON_SET; + } +} + +/// `CLOCK_*` constants for use with [`timerfd_create`]. +/// +/// [`timerfd_create`]: crate::time::timerfd_create +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[repr(u32)] +#[non_exhaustive] +pub enum TimerfdClockId { + /// `CLOCK_REALTIME`—A clock that tells the "real" time. + /// + /// This is a clock that tells the amount of time elapsed since the + /// Unix epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so + /// it is not monotonic. Successive reads may see decreasing times, so it + /// isn't reliable for measuring durations. + Realtime = linux_raw_sys::general::CLOCK_REALTIME, + + /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. + /// + /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so + /// individual times aren't meaningful. However, since it isn't settable, + /// it is reliable for measuring durations. + /// + /// This clock does not advance while the system is suspended; see + /// `Boottime` for a clock that does. + Monotonic = linux_raw_sys::general::CLOCK_MONOTONIC, + + /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. + /// + /// This clock is similar to `Monotonic`, but does advance while the system + /// is suspended. + Boottime = linux_raw_sys::general::CLOCK_BOOTTIME, + + /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. + /// + /// This clock is like `Realtime`, but can wake up a suspended system. + /// + /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + RealtimeAlarm = linux_raw_sys::general::CLOCK_REALTIME_ALARM, + + /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. + /// + /// This clock is like `Boottime`, but can wake up a suspended system. + /// + /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. + BoottimeAlarm = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM, +} diff --git a/vendor/rustix/src/backend/linux_raw/vdso.rs b/vendor/rustix/src/backend/linux_raw/vdso.rs new file mode 100644 index 000000000..da7910b88 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/vdso.rs @@ -0,0 +1,310 @@ +//! Parse the Linux vDSO. +//! +//! The following code is transliterated from +//! tools/testing/selftests/vDSO/parse_vdso.c in Linux 5.11, which is licensed +//! with Creative Commons Zero License, version 1.0, +//! available at +//! +//! # Safety +//! +//! Parsing the vDSO involves a lot of raw pointer manipulation. This +//! implementation follows Linux's reference implementation, and adds several +//! additional safety checks. +#![allow(unsafe_code)] + +use super::c; +use super::elf::*; +use crate::ffi::CStr; +use crate::utils::check_raw_pointer; +use core::ffi::c_void; +use core::mem::size_of; +use core::ptr::{null, null_mut}; + +pub(super) struct Vdso { + // Load information + load_addr: *const Elf_Ehdr, + load_end: *const c_void, // the end of the `PT_LOAD` segment + pv_offset: usize, // recorded paddr - recorded vaddr + + // Symbol table + symtab: *const Elf_Sym, + symstrings: *const u8, + bucket: *const u32, + chain: *const u32, + nbucket: u32, + //nchain: u32, + + // Version table + versym: *const u16, + verdef: *const Elf_Verdef, +} + +// Straight from the ELF specification. +fn elf_hash(name: &CStr) -> u32 { + let mut h: u32 = 0; + for b in name.to_bytes() { + h = (h << 4).wrapping_add(u32::from(*b)); + let g = h & 0xf000_0000; + if g != 0 { + h ^= g >> 24; + } + h &= !g; + } + h +} + +/// Create a `Vdso` value by parsing the vDSO at the `sysinfo_ehdr` address. +fn init_from_sysinfo_ehdr() -> Option { + // Safety: the auxv initialization code does extensive checks to ensure + // that the value we get really is an `AT_SYSINFO_EHDR` value from the + // kernel. + unsafe { + let hdr = super::param::auxv::sysinfo_ehdr(); + + // If the platform doesn't provide a `AT_SYSINFO_EHDR`, we can't locate + // the vDSO. + if hdr.is_null() { + return None; + } + + let mut vdso = Vdso { + load_addr: hdr, + load_end: hdr.cast(), + pv_offset: 0, + symtab: null(), + symstrings: null(), + bucket: null(), + chain: null(), + nbucket: 0, + //nchain: 0, + versym: null(), + verdef: null(), + }; + + let hdr = &*hdr; + let pt = check_raw_pointer::(vdso.base_plus(hdr.e_phoff)? as *mut _)?.as_ptr(); + let mut dyn_: *const Elf_Dyn = null(); + let mut num_dyn = 0; + + // We need two things from the segment table: the load offset + // and the dynamic table. + let mut found_vaddr = false; + for i in 0..hdr.e_phnum { + let phdr = &*pt.add(i as usize); + if phdr.p_flags & PF_W != 0 { + // Don't trust any vDSO that claims to be loading writable + // segments into memory. + return None; + } + if phdr.p_type == PT_LOAD && !found_vaddr { + // The segment should be readable and executable, because it + // contains the symbol table and the function bodies. + if phdr.p_flags & (PF_R | PF_X) != (PF_R | PF_X) { + return None; + } + found_vaddr = true; + vdso.load_end = vdso.base_plus(phdr.p_offset.checked_add(phdr.p_memsz)?)?; + vdso.pv_offset = phdr.p_offset.wrapping_sub(phdr.p_vaddr); + } else if phdr.p_type == PT_DYNAMIC { + // If `p_offset` is zero, it's more likely that we're looking at memory + // that has been zeroed than that the kernel has somehow aliased the + // `Ehdr` and the `Elf_Dyn` array. + if phdr.p_offset < size_of::() { + return None; + } + + dyn_ = check_raw_pointer::(vdso.base_plus(phdr.p_offset)? as *mut _)? + .as_ptr(); + num_dyn = phdr.p_memsz / size_of::(); + } else if phdr.p_type == PT_INTERP || phdr.p_type == PT_GNU_RELRO { + // Don't trust any ELF image that has an "interpreter" or that uses + // RELRO, which is likely to be a user ELF image rather and not the + // kernel vDSO. + return None; + } + } + + if !found_vaddr || dyn_.is_null() { + return None; // Failed + } + + // Fish out the useful bits of the dynamic table. + let mut hash: *const u32 = null(); + vdso.symstrings = null(); + vdso.symtab = null(); + vdso.versym = null(); + vdso.verdef = null(); + let mut i = 0; + loop { + if i == num_dyn { + return None; + } + let d = &*dyn_.add(i); + match d.d_tag { + DT_STRTAB => { + vdso.symstrings = + check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)?.as_ptr(); + } + DT_SYMTAB => { + vdso.symtab = + check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)? + .as_ptr(); + } + DT_HASH => { + hash = + check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)?.as_ptr(); + } + DT_VERSYM => { + vdso.versym = + check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)?.as_ptr(); + } + DT_VERDEF => { + vdso.verdef = + check_raw_pointer::(vdso.addr_from_elf(d.d_val)? as *mut _)? + .as_ptr(); + } + DT_SYMENT => { + if d.d_val != size_of::() { + return None; // Failed + } + } + DT_NULL => break, + _ => {} + } + i = i.checked_add(1)?; + } + // The upstream code checks `symstrings`, `symtab`, and `hash` for null; + // here, `check_raw_pointer` has already done that. + + if vdso.verdef.is_null() { + vdso.versym = null(); + } + + // Parse the hash table header. + vdso.nbucket = *hash.add(0); + //vdso.nchain = *hash.add(1); + vdso.bucket = hash.add(2); + vdso.chain = hash.add(vdso.nbucket as usize + 2); + + // That's all we need. + Some(vdso) + } +} + +impl Vdso { + /// Parse the vDSO. + /// + /// Returns `None` if the vDSO can't be located or if it doesn't conform + /// to our expectations. + #[inline] + pub(super) fn new() -> Option { + init_from_sysinfo_ehdr() + } + + /// Check the version for a symbol. + /// + /// # Safety + /// + /// The raw pointers inside `self` must be valid. + unsafe fn match_version(&self, mut ver: u16, name: &CStr, hash: u32) -> bool { + // This is a helper function to check if the version indexed by + // ver matches name (which hashes to hash). + // + // The version definition table is a mess, and I don't know how + // to do this in better than linear time without allocating memory + // to build an index. I also don't know why the table has + // variable size entries in the first place. + // + // For added fun, I can't find a comprehensible specification of how + // to parse all the weird flags in the table. + // + // So I just parse the whole table every time. + + // First step: find the version definition + ver &= 0x7fff; // Apparently bit 15 means "hidden" + let mut def = self.verdef; + loop { + if (*def).vd_version != VER_DEF_CURRENT { + return false; // Failed + } + + if ((*def).vd_flags & VER_FLG_BASE) == 0 && ((*def).vd_ndx & 0x7fff) == ver { + break; + } + + if (*def).vd_next == 0 { + return false; // No definition. + } + + def = def + .cast::() + .add((*def).vd_next as usize) + .cast::(); + } + + // Now figure out whether it matches. + let aux = &*(def.cast::()) + .add((*def).vd_aux as usize) + .cast::(); + (*def).vd_hash == hash + && (name == CStr::from_ptr(self.symstrings.add(aux.vda_name as usize).cast())) + } + + /// Look up a symbol in the vDSO. + pub(super) fn sym(&self, version: &CStr, name: &CStr) -> *mut c::c_void { + let ver_hash = elf_hash(version); + let name_hash = elf_hash(name); + + // Safety: The pointers in `self` must be valid. + unsafe { + let mut chain = *self.bucket.add((name_hash % self.nbucket) as usize); + + while chain != STN_UNDEF { + let sym = &*self.symtab.add(chain as usize); + + // Check for a defined global or weak function w/ right name. + // + // The reference parser in Linux's parse_vdso.c requires + // symbols to have type `STT_FUNC`, but on powerpc64, the vDSO + // uses `STT_NOTYPE`, so allow that too. + if (ELF_ST_TYPE(sym.st_info) != STT_FUNC && + ELF_ST_TYPE(sym.st_info) != STT_NOTYPE) + || (ELF_ST_BIND(sym.st_info) != STB_GLOBAL + && ELF_ST_BIND(sym.st_info) != STB_WEAK) + || sym.st_shndx == SHN_UNDEF + || sym.st_shndx == SHN_ABS + || ELF_ST_VISIBILITY(sym.st_other) != STV_DEFAULT + || (name != CStr::from_ptr(self.symstrings.add(sym.st_name as usize).cast())) + // Check symbol version. + || (!self.versym.is_null() + && !self.match_version(*self.versym.add(chain as usize), version, ver_hash)) + { + chain = *self.chain.add(chain as usize); + continue; + } + + let sum = self.addr_from_elf(sym.st_value).unwrap(); + assert!( + sum as usize >= self.load_addr as usize + && sum as usize <= self.load_end as usize + ); + return sum as *mut c::c_void; + } + } + + null_mut() + } + + /// Add the given address to the vDSO base address. + unsafe fn base_plus(&self, offset: usize) -> Option<*const c_void> { + // Check for overflow. + let _ = (self.load_addr as usize).checked_add(offset)?; + // Add the offset to the base. + Some(self.load_addr.cast::().add(offset).cast()) + } + + /// Translate an ELF-address-space address into a usable virtual address. + unsafe fn addr_from_elf(&self, elf_addr: usize) -> Option<*const c_void> { + self.base_plus(elf_addr.wrapping_add(self.pv_offset)) + } +} diff --git a/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs new file mode 100644 index 000000000..487835314 --- /dev/null +++ b/vendor/rustix/src/backend/linux_raw/vdso_wrappers.rs @@ -0,0 +1,399 @@ +//! Implement syscalls using the vDSO. +//! +//! +//! +//! # Safety +//! +//! Similar to syscalls.rs, this file performs raw system calls, and sometimes +//! passes them uninitialized memory buffers. This file also calls vDSO +//! 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; +#[cfg(all(asm, target_arch = "x86"))] +use core::arch::asm; +use core::mem::{transmute, MaybeUninit}; +use core::ptr::null_mut; +use core::sync::atomic::AtomicPtr; +use core::sync::atomic::Ordering::Relaxed; +#[cfg(target_pointer_width = "32")] +use linux_raw_sys::general::timespec as __kernel_old_timespec; +use linux_raw_sys::general::{__kernel_clockid_t, __kernel_timespec}; + +#[inline] +pub(crate) fn clock_gettime(which_clock: ClockId) -> __kernel_timespec { + // Safety: `CLOCK_GETTIME` contains either null or the address of a + // function with an ABI like libc `clock_gettime`, and calling it has + // the side effect of writing to the result buffer, and no others. + unsafe { + let mut result = MaybeUninit::<__kernel_timespec>::uninit(); + let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { + Some(callee) => callee, + None => init_clock_gettime(), + }; + let r0 = callee(which_clock as c::c_int, result.as_mut_ptr()); + assert_eq!(r0, 0); + result.assume_init() + } +} + +#[inline] +pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Result { + let id = match which_clock { + DynamicClockId::Known(id) => id as __kernel_clockid_t, + + DynamicClockId::Dynamic(fd) => { + // See `FD_TO_CLOCKID` in Linux's `clock_gettime` documentation. + use crate::backend::fd::AsRawFd; + const CLOCKFD: i32 = 3; + ((!fd.as_raw_fd() << 3) | CLOCKFD) as __kernel_clockid_t + } + + DynamicClockId::RealtimeAlarm => { + linux_raw_sys::general::CLOCK_REALTIME_ALARM as __kernel_clockid_t + } + DynamicClockId::Tai => linux_raw_sys::general::CLOCK_TAI as __kernel_clockid_t, + DynamicClockId::Boottime => linux_raw_sys::general::CLOCK_BOOTTIME as __kernel_clockid_t, + DynamicClockId::BoottimeAlarm => { + linux_raw_sys::general::CLOCK_BOOTTIME_ALARM as __kernel_clockid_t + } + }; + + // Safety: `CLOCK_GETTIME` contains either null or the address of a + // function with an ABI like libc `clock_gettime`, and calling it has + // the side effect of writing to the result buffer, and no others. + unsafe { + const EINVAL: c::c_int = -(c::EINVAL as c::c_int); + let mut timespec = MaybeUninit::::uninit(); + let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { + Some(callee) => callee, + None => init_clock_gettime(), + }; + match callee(id, timespec.as_mut_ptr()) { + 0 => (), + EINVAL => return Err(io::Errno::INVAL), + _ => _rustix_clock_gettime_via_syscall(id, timespec.as_mut_ptr())?, + } + Ok(timespec.assume_init()) + } +} + +#[cfg(target_arch = "x86")] +pub(super) mod x86_via_vdso { + use super::{transmute, ArgReg, Relaxed, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; + use crate::backend::arch::asm; + + #[inline] + pub(in crate::backend) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall0(callee, nr) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall1<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + ) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall1(callee, nr, a0) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall1_noreturn<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + ) -> ! { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall1_noreturn(callee, nr, a0) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall2<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + a1: ArgReg<'a, A1>, + ) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall2(callee, nr, a0, a1) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall3<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + a1: ArgReg<'a, A1>, + a2: ArgReg<'a, A2>, + ) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall3(callee, nr, a0, a1, a2) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall4<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + a1: ArgReg<'a, A1>, + a2: ArgReg<'a, A2>, + a3: ArgReg<'a, A3>, + ) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall4(callee, nr, a0, a1, a2, a3) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall5<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + a1: ArgReg<'a, A1>, + a2: ArgReg<'a, A2>, + a3: ArgReg<'a, A3>, + a4: ArgReg<'a, A4>, + ) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall5(callee, nr, a0, a1, a2, a3, a4) + } + + #[inline] + pub(in crate::backend) unsafe fn syscall6<'a>( + nr: SyscallNumber<'a>, + a0: ArgReg<'a, A0>, + a1: ArgReg<'a, A1>, + a2: ArgReg<'a, A2>, + a3: ArgReg<'a, A3>, + a4: ArgReg<'a, A4>, + a5: ArgReg<'a, A5>, + ) -> RetReg { + let callee = match transmute(super::SYSCALL.load(Relaxed)) { + Some(callee) => callee, + None => super::init_syscall(), + }; + asm::indirect_syscall6(callee, nr, a0, a1, a2, a3, a4, a5) + } + + // With the indirect call, it isn't meaningful to do a separate + // `_readonly` optimization. + pub(in crate::backend) use { + syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, + syscall2 as syscall2_readonly, syscall3 as syscall3_readonly, + syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, + syscall6 as syscall6_readonly, + }; +} + +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 +/// special syscall calling convention to pass arguments and return values, +/// which the signature here doesn't reflect. +#[cfg(target_arch = "x86")] +pub(super) type SyscallType = unsafe extern "C" fn(); + +/// Initialize `CLOCK_GETTIME` and return its value. +fn init_clock_gettime() -> ClockGettimeType { + init(); + // Safety: Load the function address from static storage that we + // just initialized. + unsafe { transmute(CLOCK_GETTIME.load(Relaxed)) } +} + +/// Initialize `SYSCALL` and return its value. +#[cfg(target_arch = "x86")] +fn init_syscall() -> SyscallType { + init(); + // Safety: Load the function address from static storage that we + // just initialized. + unsafe { transmute(SYSCALL.load(Relaxed)) } +} + +/// `AtomicPtr` can't hold a `fn` pointer, so we use a `*` pointer to this +/// placeholder type, and cast it as needed. +struct Function; +static mut CLOCK_GETTIME: AtomicPtr = AtomicPtr::new(null_mut()); +#[cfg(target_arch = "x86")] +static mut SYSCALL: AtomicPtr = AtomicPtr::new(null_mut()); + +unsafe extern "C" fn rustix_clock_gettime_via_syscall( + clockid: c::c_int, + res: *mut Timespec, +) -> c::c_int { + match _rustix_clock_gettime_via_syscall(clockid, res) { + Ok(()) => 0, + Err(err) => err.raw_os_error().wrapping_neg(), + } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn _rustix_clock_gettime_via_syscall( + clockid: c::c_int, + res: *mut Timespec, +) -> io::Result<()> { + let r0 = syscall!(__NR_clock_gettime64, c_int(clockid), res); + match ret(r0) { + Err(io::Errno::NOSYS) => _rustix_clock_gettime_via_syscall_old(clockid, res), + otherwise => otherwise, + } +} + +#[cfg(target_pointer_width = "32")] +unsafe fn _rustix_clock_gettime_via_syscall_old( + clockid: c::c_int, + res: *mut Timespec, +) -> io::Result<()> { + // Ordinarily `rustix` doesn't like to emulate system calls, but in + // the case of time APIs, it's specific to Linux, specific to + // 32-bit architectures *and* specific to old kernel versions, and + // it's not that hard to fix up here, so that no other code needs + // to worry about this. + let mut old_result = MaybeUninit::<__kernel_old_timespec>::uninit(); + let r0 = syscall!(__NR_clock_gettime, c_int(clockid), &mut old_result); + match ret(r0) { + Ok(()) => { + let old_result = old_result.assume_init(); + *res = Timespec { + tv_sec: old_result.tv_sec.into(), + tv_nsec: old_result.tv_nsec.into(), + }; + Ok(()) + } + otherwise => otherwise, + } +} + +#[cfg(target_pointer_width = "64")] +unsafe fn _rustix_clock_gettime_via_syscall( + clockid: c::c_int, + res: *mut Timespec, +) -> io::Result<()> { + ret(syscall!(__NR_clock_gettime, c_int(clockid), res)) +} + +/// A symbol pointing to an `int 0x80` instruction. This "function" is only +/// called from assembly, and only with the x86 syscall calling convention, +/// so its signature here is not its true signature. +#[cfg(all(asm, target_arch = "x86"))] +#[naked] +unsafe extern "C" fn rustix_int_0x80() { + asm!("int $$0x80", "ret", options(noreturn)) +} + +// The outline version of the `rustix_int_0x80` above. +#[cfg(all(not(asm), target_arch = "x86"))] +extern "C" { + fn rustix_int_0x80(); +} + +fn minimal_init() { + // Safety: Store default function addresses in static storage so that if we + // end up making any system calls while we read the vDSO, they'll work. + // 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(target_arch = "x86")] + { + SYSCALL + .compare_exchange( + null_mut(), + rustix_int_0x80 as *mut Function, + Relaxed, + Relaxed, + ) + .ok(); + } + } +} + +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(any(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); + } + } + + // On x86, also look up the vsyscall entry point. + #[cfg(target_arch = "x86")] + { + let ptr = vdso.sym(cstr!("LINUX_2.5"), cstr!("__kernel_vsyscall")); + assert!(!ptr.is_null()); + + // Safety: As above, store the computed function addresses in + // static storage. + unsafe { + SYSCALL.store(ptr.cast(), Relaxed); + } + } + } +} diff --git a/vendor/rustix/src/const_assert.rs b/vendor/rustix/src/const_assert.rs index 8761a4a21..c1dd5498c 100644 --- a/vendor/rustix/src/const_assert.rs +++ b/vendor/rustix/src/const_assert.rs @@ -12,6 +12,7 @@ macro_rules! const_assert { } #[test] +#[allow(clippy::missing_const_for_fn)] fn test_const_assert() { const_assert!(true); } diff --git a/vendor/rustix/src/fs/abs.rs b/vendor/rustix/src/fs/abs.rs index 25556304b..a0d6cdecb 100644 --- a/vendor/rustix/src/fs/abs.rs +++ b/vendor/rustix/src/fs/abs.rs @@ -1,33 +1,69 @@ //! POSIX-style filesystem functions which operate on bare paths. #[cfg(not(any( + target_os = "haiku", target_os = "illumos", target_os = "netbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] use crate::fs::StatFs; #[cfg(not(any( + target_os = "haiku", target_os = "illumos", - target_os = "netbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] -use crate::{imp, io, path}; +use { + crate::fs::StatVfs, + crate::{backend, io, path}, +}; /// `statfs`—Queries filesystem metadata. /// +/// Compared to [`statvfs`], this function often provides more information, +/// though it's less portable. +/// /// # References /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/statfs.2.html #[cfg(not(any( + target_os = "haiku", target_os = "illumos", target_os = "netbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] #[inline] pub fn statfs(path: P) -> io::Result { - path.into_with_c_str(imp::fs::syscalls::statfs) + path.into_with_c_str(backend::fs::syscalls::statfs) +} + +/// `statvfs`—Queries filesystem metadata, POSIX version. +/// +/// Compared to [`statfs`], this function often provides less information, +/// but it is more portable. But even so, filesystems are very diverse and not +/// all the fields are meaningful for every filesystem. And `f_fsid` doesn't +/// seem to have a clear meaning anywhere. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/statvfs.html +/// [Linux]: https://man7.org/linux/man-pages/man2/statvfs.2.html +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[inline] +pub fn statvfs(path: P) -> io::Result { + path.into_with_c_str(backend::fs::syscalls::statvfs) } diff --git a/vendor/rustix/src/fs/at.rs b/vendor/rustix/src/fs/at.rs index 2ecd90324..463c247c0 100644 --- a/vendor/rustix/src/fs/at.rs +++ b/vendor/rustix/src/fs/at.rs @@ -5,8 +5,9 @@ //! //! [`cwd`]: crate::fs::cwd +use crate::fd::OwnedFd; use crate::ffi::{CStr, CString}; -#[cfg(not(target_os = "illumos"))] +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] use crate::fs::Access; #[cfg(any(target_os = "ios", target_os = "macos"))] use crate::fs::CloneFlags; @@ -15,28 +16,27 @@ use crate::fs::FileType; #[cfg(any(target_os = "android", target_os = "linux"))] use crate::fs::RenameFlags; use crate::fs::{AtFlags, Mode, OFlags, Stat, Timestamps}; -use crate::io::{self, OwnedFd}; use crate::path::SMALL_PATH_BUFFER_SIZE; #[cfg(not(target_os = "wasi"))] use crate::process::{Gid, Uid}; -use crate::{imp, path}; +use crate::{backend, io, path}; use alloc::vec::Vec; -use imp::fd::{AsFd, BorrowedFd}; -use imp::time::types::Nsecs; +use backend::fd::{AsFd, BorrowedFd}; +use backend::time::types::Nsecs; -pub use imp::fs::types::{Dev, RawMode}; +pub use backend::fs::types::{Dev, RawMode}; /// `UTIME_NOW` for use with [`utimensat`]. /// /// [`utimensat`]: crate::fs::utimensat #[cfg(not(target_os = "redox"))] -pub const UTIME_NOW: Nsecs = imp::fs::types::UTIME_NOW as Nsecs; +pub const UTIME_NOW: Nsecs = backend::fs::types::UTIME_NOW as Nsecs; /// `UTIME_OMIT` for use with [`utimensat`]. /// /// [`utimensat`]: crate::fs::utimensat #[cfg(not(target_os = "redox"))] -pub const UTIME_OMIT: Nsecs = imp::fs::types::UTIME_OMIT as Nsecs; +pub const UTIME_OMIT: Nsecs = backend::fs::types::UTIME_OMIT as Nsecs; /// `openat(dirfd, path, oflags, mode)`—Opens a file. /// @@ -59,7 +59,9 @@ pub fn openat( oflags: OFlags, create_mode: Mode, ) -> io::Result { - path.into_with_c_str(|path| imp::fs::syscalls::openat(dirfd.as_fd(), path, oflags, create_mode)) + path.into_with_c_str(|path| { + backend::fs::syscalls::openat(dirfd.as_fd(), path, oflags, create_mode) + }) } /// `readlinkat(fd, path)`—Reads the contents of a symlink. @@ -89,7 +91,7 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec) -> io::R buffer.resize(buffer.capacity(), 0_u8); loop { - let nread = imp::fs::syscalls::readlinkat(dirfd.as_fd(), path, &mut buffer)?; + let nread = backend::fs::syscalls::readlinkat(dirfd.as_fd(), path, &mut buffer)?; let nread = nread as usize; assert!(nread <= buffer.len()); @@ -112,7 +114,7 @@ fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec) -> io::R /// [Linux]: https://man7.org/linux/man-pages/man2/mkdirat.2.html #[inline] pub fn mkdirat(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> { - path.into_with_c_str(|path| imp::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode)) + path.into_with_c_str(|path| backend::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode)) } /// `linkat(old_dirfd, old_path, new_dirfd, new_path, flags)`—Creates a hard @@ -134,7 +136,7 @@ pub fn linkat( ) -> io::Result<()> { old_path.into_with_c_str(|old_path| { new_path.into_with_c_str(|new_path| { - imp::fs::syscalls::linkat( + backend::fs::syscalls::linkat( old_dirfd.as_fd(), old_path, new_dirfd.as_fd(), @@ -159,7 +161,7 @@ pub fn linkat( /// [Linux]: https://man7.org/linux/man-pages/man2/unlinkat.2.html #[inline] pub fn unlinkat(dirfd: Fd, path: P, flags: AtFlags) -> io::Result<()> { - path.into_with_c_str(|path| imp::fs::syscalls::unlinkat(dirfd.as_fd(), path, flags)) + path.into_with_c_str(|path| backend::fs::syscalls::unlinkat(dirfd.as_fd(), path, flags)) } /// `renameat(old_dirfd, old_path, new_dirfd, new_path)`—Renames a file or @@ -180,7 +182,12 @@ pub fn renameat( ) -> io::Result<()> { old_path.into_with_c_str(|old_path| { new_path.into_with_c_str(|new_path| { - imp::fs::syscalls::renameat(old_dirfd.as_fd(), old_path, new_dirfd.as_fd(), new_path) + backend::fs::syscalls::renameat( + old_dirfd.as_fd(), + old_path, + new_dirfd.as_fd(), + new_path, + ) }) }) } @@ -204,7 +211,7 @@ pub fn renameat_with( ) -> io::Result<()> { old_path.into_with_c_str(|old_path| { new_path.into_with_c_str(|new_path| { - imp::fs::syscalls::renameat2( + backend::fs::syscalls::renameat2( old_dirfd.as_fd(), old_path, new_dirfd.as_fd(), @@ -231,7 +238,7 @@ pub fn symlinkat( ) -> io::Result<()> { old_path.into_with_c_str(|old_path| { new_path.into_with_c_str(|new_path| { - imp::fs::syscalls::symlinkat(old_path, new_dirfd.as_fd(), new_path) + backend::fs::syscalls::symlinkat(old_path, new_dirfd.as_fd(), new_path) }) }) } @@ -252,7 +259,7 @@ pub fn symlinkat( #[inline] #[doc(alias = "fstatat")] pub fn statat(dirfd: Fd, path: P, flags: AtFlags) -> io::Result { - path.into_with_c_str(|path| imp::fs::syscalls::statat(dirfd.as_fd(), path, flags)) + path.into_with_c_str(|path| backend::fs::syscalls::statat(dirfd.as_fd(), path, flags)) } /// `faccessat(dirfd, path, access, flags)`—Tests permissions for a file or @@ -264,7 +271,7 @@ pub fn statat(dirfd: Fd, path: P, flags: AtFlags) -> io: /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html /// [Linux]: https://man7.org/linux/man-pages/man2/faccessat.2.html -#[cfg(not(target_os = "illumos"))] +#[cfg(not(any(target_os = "illumos", target_os = "solaris")))] #[inline] #[doc(alias = "faccessat")] pub fn accessat( @@ -273,7 +280,7 @@ pub fn accessat( access: Access, flags: AtFlags, ) -> io::Result<()> { - path.into_with_c_str(|path| imp::fs::syscalls::accessat(dirfd.as_fd(), path, access, flags)) + path.into_with_c_str(|path| backend::fs::syscalls::accessat(dirfd.as_fd(), path, access, flags)) } /// `utimensat(dirfd, path, times, flags)`—Sets file or directory timestamps. @@ -291,7 +298,7 @@ pub fn utimensat( times: &Timestamps, flags: AtFlags, ) -> io::Result<()> { - path.into_with_c_str(|path| imp::fs::syscalls::utimensat(dirfd.as_fd(), path, times, flags)) + path.into_with_c_str(|path| backend::fs::syscalls::utimensat(dirfd.as_fd(), path, times, flags)) } /// `fchmodat(dirfd, path, mode, 0)`—Sets file or directory permissions. @@ -312,7 +319,7 @@ pub fn utimensat( #[inline] #[doc(alias = "fchmodat")] pub fn chmodat(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> { - path.into_with_c_str(|path| imp::fs::syscalls::chmodat(dirfd.as_fd(), path, mode)) + path.into_with_c_str(|path| backend::fs::syscalls::chmodat(dirfd.as_fd(), path, mode)) } /// `fclonefileat(src, dst_dir, dst, flags)`—Efficiently copies between files. @@ -330,7 +337,7 @@ pub fn fclonefileat( flags: CloneFlags, ) -> io::Result<()> { dst.into_with_c_str(|dst| { - imp::fs::syscalls::fclonefileat(src.as_fd(), dst_dir.as_fd(), &dst, flags) + backend::fs::syscalls::fclonefileat(src.as_fd(), dst_dir.as_fd(), dst, flags) }) } @@ -352,7 +359,7 @@ pub fn mknodat( dev: Dev, ) -> io::Result<()> { path.into_with_c_str(|path| { - imp::fs::syscalls::mknodat(dirfd.as_fd(), path, file_type, mode, dev) + backend::fs::syscalls::mknodat(dirfd.as_fd(), path, file_type, mode, dev) }) } @@ -375,6 +382,6 @@ pub fn chownat( flags: AtFlags, ) -> io::Result<()> { path.into_with_c_str(|path| { - imp::fs::syscalls::chownat(dirfd.as_fd(), path, owner, group, flags) + backend::fs::syscalls::chownat(dirfd.as_fd(), path, owner, group, flags) }) } diff --git a/vendor/rustix/src/fs/constants.rs b/vendor/rustix/src/fs/constants.rs index b6893a92e..11b53fd2a 100644 --- a/vendor/rustix/src/fs/constants.rs +++ b/vendor/rustix/src/fs/constants.rs @@ -1,19 +1,20 @@ //! Filesystem API constants, translated into `bitflags` constants. -use crate::imp; +use crate::backend; -pub use imp::fs::types::{Access, FdFlags, Mode, OFlags}; +pub use crate::io::FdFlags; +pub use backend::fs::types::{Access, Mode, OFlags}; #[cfg(not(target_os = "redox"))] -pub use imp::fs::types::AtFlags; +pub use backend::fs::types::AtFlags; #[cfg(any(target_os = "ios", target_os = "macos"))] -pub use imp::fs::types::{CloneFlags, CopyfileFlags}; +pub use backend::fs::types::{CloneFlags, CopyfileFlags}; #[cfg(any(target_os = "android", target_os = "linux"))] -pub use imp::fs::types::{RenameFlags, ResolveFlags}; +pub use backend::fs::types::{RenameFlags, ResolveFlags}; #[cfg(not(target_os = "redox"))] -pub use imp::fs::types::Dev; +pub use backend::fs::types::Dev; -pub use imp::time::types::{Nsecs, Secs, Timespec}; +pub use backend::time::types::{Nsecs, Secs, Timespec}; diff --git a/vendor/rustix/src/fs/copy_file_range.rs b/vendor/rustix/src/fs/copy_file_range.rs index b12190472..4b118b30e 100644 --- a/vendor/rustix/src/fs/copy_file_range.rs +++ b/vendor/rustix/src/fs/copy_file_range.rs @@ -1,5 +1,5 @@ -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; /// `copy_file_range(fd_in, off_in, fd_out, off_out, len, 0)`—Copies data /// from one file to another. @@ -16,5 +16,5 @@ pub fn copy_file_range( off_out: Option<&mut u64>, len: u64, ) -> io::Result { - imp::fs::syscalls::copy_file_range(fd_in.as_fd(), off_in, fd_out.as_fd(), off_out, len) + backend::fs::syscalls::copy_file_range(fd_in.as_fd(), off_in, fd_out.as_fd(), off_out, len) } diff --git a/vendor/rustix/src/fs/cwd.rs b/vendor/rustix/src/fs/cwd.rs index 95f97f85d..d0455cd6c 100644 --- a/vendor/rustix/src/fs/cwd.rs +++ b/vendor/rustix/src/fs/cwd.rs @@ -7,8 +7,8 @@ #![allow(unsafe_code)] -use crate::imp; -use imp::fd::{BorrowedFd, RawFd}; +use crate::backend; +use backend::fd::{BorrowedFd, RawFd}; /// `AT_FDCWD`—Returns a handle representing the current working directory. /// @@ -24,7 +24,7 @@ use imp::fd::{BorrowedFd, RawFd}; #[inline] #[doc(alias = "AT_FDCWD")] pub const fn cwd() -> BorrowedFd<'static> { - let at_fdcwd = imp::io::types::AT_FDCWD as RawFd; + let at_fdcwd = backend::io::types::AT_FDCWD as RawFd; // Safety: `AT_FDCWD` is a reserved value that is never dynamically // allocated, so it'll remain valid for the duration of `'static`. diff --git a/vendor/rustix/src/fs/dir.rs b/vendor/rustix/src/fs/dir.rs index f9d7ff871..94bc0a3ee 100644 --- a/vendor/rustix/src/fs/dir.rs +++ b/vendor/rustix/src/fs/dir.rs @@ -1,5 +1,5 @@ //! `Dir` and `Entry`. -use crate::imp; +use crate::backend; -pub use imp::fs::dir::{Dir, DirEntry}; +pub use backend::fs::dir::{Dir, DirEntry}; diff --git a/vendor/rustix/src/fs/fadvise.rs b/vendor/rustix/src/fs/fadvise.rs index ead3ad9a3..5bc3a588a 100644 --- a/vendor/rustix/src/fs/fadvise.rs +++ b/vendor/rustix/src/fs/fadvise.rs @@ -1,7 +1,7 @@ -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; -pub use imp::fs::types::Advice; +pub use backend::fs::types::Advice; /// `posix_fadvise(fd, offset, len, advice)`—Declares an expected access /// pattern for a file. @@ -15,5 +15,5 @@ pub use imp::fs::types::Advice; #[inline] #[doc(alias = "posix_fadvise")] pub fn fadvise(fd: Fd, offset: u64, len: u64, advice: Advice) -> io::Result<()> { - imp::fs::syscalls::fadvise(fd.as_fd(), offset, len, advice) + backend::fs::syscalls::fadvise(fd.as_fd(), offset, len, advice) } diff --git a/vendor/rustix/src/fs/fcntl.rs b/vendor/rustix/src/fs/fcntl.rs index 7f89873b5..80ac858c0 100644 --- a/vendor/rustix/src/fs/fcntl.rs +++ b/vendor/rustix/src/fs/fcntl.rs @@ -3,38 +3,16 @@ //! a type-safe API, rustix makes them all separate functions so that they //! can have dedicated static type signatures. -use crate::imp; -use crate::io::{self, OwnedFd}; -use imp::fd::{AsFd, RawFd}; -use imp::fs::types::{FdFlags, OFlags}; +use crate::{backend, io}; +use backend::fd::AsFd; +use backend::fs::types::OFlags; -/// `fcntl(fd, F_GETFD)`—Returns a file descriptor's flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[inline] -#[doc(alias = "F_GETFD")] -pub fn fcntl_getfd(fd: Fd) -> io::Result { - imp::fs::syscalls::fcntl_getfd(fd.as_fd()) -} - -/// `fcntl(fd, F_SETFD, flags)`—Sets a file descriptor's flags. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[inline] -#[doc(alias = "F_SETFD")] -pub fn fcntl_setfd(fd: Fd, flags: FdFlags) -> io::Result<()> { - imp::fs::syscalls::fcntl_setfd(fd.as_fd(), flags) -} +// These `fcntl` functions like in the `io` module because they're not specific +// to files, directories, or memfd objects. We re-export them here in the `fs` +// module because the other the `fcntl` functions are here. +#[cfg(not(target_os = "wasi"))] +pub use crate::io::fcntl_dupfd_cloexec; +pub use crate::io::{fcntl_getfd, fcntl_setfd}; /// `fcntl(fd, F_GETFL)`—Returns a file descriptor's access mode and status. /// @@ -47,7 +25,7 @@ pub fn fcntl_setfd(fd: Fd, flags: FdFlags) -> io::Result<()> { #[inline] #[doc(alias = "F_GETFL")] pub fn fcntl_getfl(fd: Fd) -> io::Result { - imp::fs::syscalls::fcntl_getfl(fd.as_fd()) + backend::fs::syscalls::fcntl_getfl(fd.as_fd()) } /// `fcntl(fd, F_SETFL, flags)`—Sets a file descriptor's status. @@ -61,7 +39,7 @@ pub fn fcntl_getfl(fd: Fd) -> io::Result { #[inline] #[doc(alias = "F_SETFL")] pub fn fcntl_setfl(fd: Fd, flags: OFlags) -> io::Result<()> { - imp::fs::syscalls::fcntl_setfl(fd.as_fd(), flags) + backend::fs::syscalls::fcntl_setfl(fd.as_fd(), flags) } /// `fcntl(fd, F_GET_SEALS)` @@ -79,7 +57,7 @@ pub fn fcntl_setfl(fd: Fd, flags: OFlags) -> io::Result<()> { #[inline] #[doc(alias = "F_GET_SEALS")] pub fn fcntl_get_seals(fd: Fd) -> io::Result { - imp::fs::syscalls::fcntl_get_seals(fd.as_fd()) + backend::fs::syscalls::fcntl_get_seals(fd.as_fd()) } #[cfg(any( @@ -88,7 +66,7 @@ pub fn fcntl_get_seals(fd: Fd) -> io::Result { target_os = "fuchsia", target_os = "linux", ))] -pub use imp::fs::types::SealFlags; +pub use backend::fs::types::SealFlags; /// `fcntl(fd, F_ADD_SEALS)` /// @@ -105,27 +83,5 @@ pub use imp::fs::types::SealFlags; #[inline] #[doc(alias = "F_ADD_SEALS")] pub fn fcntl_add_seals(fd: Fd, seals: SealFlags) -> io::Result<()> { - imp::fs::syscalls::fcntl_add_seals(fd.as_fd(), seals) -} - -/// `fcntl(fd, F_DUPFD_CLOEXEC)`—Creates a new `OwnedFd` instance, with value -/// at least `min`, that has `O_CLOEXEC` set and that shares the same -/// underlying [file description] as `fd`. -/// -/// POSIX guarantees that `F_DUPFD_CLOEXEC` will use the lowest unused file -/// descriptor which is at least `min`, however it is not safe in general to -/// rely on this, as file descriptors may be unexpectedly allocated on other -/// threads or in libraries. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -#[doc(alias = "F_DUPFD_CLOEXEC")] -pub fn fcntl_dupfd_cloexec(fd: Fd, min: RawFd) -> io::Result { - imp::fs::syscalls::fcntl_dupfd_cloexec(fd.as_fd(), min) + backend::fs::syscalls::fcntl_add_seals(fd.as_fd(), seals) } diff --git a/vendor/rustix/src/fs/fcntl_darwin.rs b/vendor/rustix/src/fs/fcntl_darwin.rs index 17d8f844f..6d624ee47 100644 --- a/vendor/rustix/src/fs/fcntl_darwin.rs +++ b/vendor/rustix/src/fs/fcntl_darwin.rs @@ -1,5 +1,5 @@ -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; /// `fcntl(fd, F_RDADVISE, radvisory { offset, len })` /// @@ -9,7 +9,7 @@ use imp::fd::AsFd; /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html #[inline] pub fn fcntl_rdadvise(fd: Fd, offset: u64, len: u64) -> io::Result<()> { - imp::fs::syscalls::fcntl_rdadvise(fd.as_fd(), offset, len) + backend::fs::syscalls::fcntl_rdadvise(fd.as_fd(), offset, len) } /// `fcntl(fd, F_FULLFSYNC)` @@ -20,5 +20,5 @@ pub fn fcntl_rdadvise(fd: Fd, offset: u64, len: u64) -> io::Result<()> /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html #[inline] pub fn fcntl_fullfsync(fd: Fd) -> io::Result<()> { - imp::fs::syscalls::fcntl_fullfsync(fd.as_fd()) + backend::fs::syscalls::fcntl_fullfsync(fd.as_fd()) } diff --git a/vendor/rustix/src/fs/fcopyfile.rs b/vendor/rustix/src/fs/fcopyfile.rs index c5b00ce10..d8931733f 100644 --- a/vendor/rustix/src/fs/fcopyfile.rs +++ b/vendor/rustix/src/fs/fcopyfile.rs @@ -1,9 +1,9 @@ use crate::fs::CopyfileFlags; -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; /// `copyfile_state_t` -pub use imp::fs::types::copyfile_state_t; +pub use backend::fs::types::copyfile_state_t; /// `fcopyfile(from, to, state, flags)` /// @@ -23,7 +23,7 @@ pub unsafe fn fcopyfile( state: copyfile_state_t, flags: CopyfileFlags, ) -> io::Result<()> { - imp::fs::syscalls::fcopyfile(from.as_fd(), to.as_fd(), state, flags) + backend::fs::syscalls::fcopyfile(from.as_fd(), to.as_fd(), state, flags) } /// `copyfile_state_alloc()` @@ -34,7 +34,7 @@ pub unsafe fn fcopyfile( /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html #[inline] pub fn copyfile_state_alloc() -> io::Result { - imp::fs::syscalls::copyfile_state_alloc() + backend::fs::syscalls::copyfile_state_alloc() } /// `copyfile_state_free(state)` @@ -50,7 +50,7 @@ pub fn copyfile_state_alloc() -> io::Result { /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html #[inline] pub unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { - imp::fs::syscalls::copyfile_state_free(state) + backend::fs::syscalls::copyfile_state_free(state) } /// `copyfile_state_get(state, COPYFILE_STATE_COPIED)` @@ -66,7 +66,7 @@ pub unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/fcopyfile.3.html #[inline] pub unsafe fn copyfile_state_get_copied(state: copyfile_state_t) -> io::Result { - imp::fs::syscalls::copyfile_state_get_copied(state) + backend::fs::syscalls::copyfile_state_get_copied(state) } /// `copyfile_state_get(state, flags, dst)` @@ -86,5 +86,5 @@ pub unsafe fn copyfile_state_get( flag: u32, dst: *mut core::ffi::c_void, ) -> io::Result<()> { - imp::fs::syscalls::copyfile_state_get(state, flag, dst) + backend::fs::syscalls::copyfile_state_get(state, flag, dst) } diff --git a/vendor/rustix/src/fs/fd.rs b/vendor/rustix/src/fs/fd.rs index b41579fb8..6bea89547 100644 --- a/vendor/rustix/src/fs/fd.rs +++ b/vendor/rustix/src/fs/fd.rs @@ -5,33 +5,46 @@ use crate::fs::Mode; use crate::io::SeekFrom; #[cfg(not(target_os = "wasi"))] use crate::process::{Gid, Uid}; -use crate::{imp, io}; -use imp::fd::{AsFd, BorrowedFd}; +use crate::{backend, io}; +use backend::fd::{AsFd, BorrowedFd}; -#[cfg(not(target_os = "wasi"))] -pub use imp::fs::types::FlockOperation; +#[cfg(not(any(target_os = "solaris", target_os = "wasi")))] +pub use backend::fs::types::FlockOperation; #[cfg(not(any( + target_os = "aix", target_os = "dragonfly", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::fs::types::FallocateFlags; +pub use backend::fs::types::FallocateFlags; -pub use imp::fs::types::Stat; +pub use backend::fs::types::Stat; #[cfg(not(any( + target_os = "haiku", target_os = "illumos", target_os = "netbsd", target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub use backend::fs::types::StatFs; + +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] -pub use imp::fs::types::StatFs; +pub use backend::fs::types::{StatVfs, StatVfsMountFlags}; #[cfg(any(target_os = "android", target_os = "linux"))] -pub use imp::fs::types::FsWord; +pub use backend::fs::types::FsWord; /// Timestamps used by [`utimensat`] and [`futimens`]. /// @@ -55,7 +68,7 @@ pub struct Timestamps { /// /// [the `fstatfs` man page]: https://man7.org/linux/man-pages/man2/fstatfs.2.html#DESCRIPTION #[cfg(any(target_os = "android", target_os = "linux"))] -pub const PROC_SUPER_MAGIC: FsWord = imp::fs::types::PROC_SUPER_MAGIC; +pub const PROC_SUPER_MAGIC: FsWord = backend::fs::types::PROC_SUPER_MAGIC; /// The filesystem magic number for NFS. /// @@ -63,7 +76,7 @@ pub const PROC_SUPER_MAGIC: FsWord = imp::fs::types::PROC_SUPER_MAGIC; /// /// [the `fstatfs` man page]: https://man7.org/linux/man-pages/man2/fstatfs.2.html#DESCRIPTION #[cfg(any(target_os = "android", target_os = "linux"))] -pub const NFS_SUPER_MAGIC: FsWord = imp::fs::types::NFS_SUPER_MAGIC; +pub const NFS_SUPER_MAGIC: FsWord = backend::fs::types::NFS_SUPER_MAGIC; /// `lseek(fd, offset, whence)`—Repositions a file descriptor within a file. /// @@ -75,7 +88,7 @@ pub const NFS_SUPER_MAGIC: FsWord = imp::fs::types::NFS_SUPER_MAGIC; /// [Linux]: https://man7.org/linux/man-pages/man2/lseek.2.html #[inline] pub fn seek(fd: Fd, pos: SeekFrom) -> io::Result { - imp::fs::syscalls::seek(fd.as_fd(), pos) + backend::fs::syscalls::seek(fd.as_fd(), pos) } /// `lseek(fd, 0, SEEK_CUR)`—Returns the current position within a file. @@ -92,7 +105,7 @@ pub fn seek(fd: Fd, pos: SeekFrom) -> io::Result { /// [Linux]: https://man7.org/linux/man-pages/man2/lseek.2.html #[inline] pub fn tell(fd: Fd) -> io::Result { - imp::fs::syscalls::tell(fd.as_fd()) + backend::fs::syscalls::tell(fd.as_fd()) } /// `fchmod(fd)`—Sets open file or directory permissions. @@ -109,7 +122,7 @@ pub fn tell(fd: Fd) -> io::Result { #[cfg(not(target_os = "wasi"))] #[inline] pub fn fchmod(fd: Fd, mode: Mode) -> io::Result<()> { - imp::fs::syscalls::fchmod(fd.as_fd(), mode) + backend::fs::syscalls::fchmod(fd.as_fd(), mode) } /// `fchown(fd)`—Sets open file or directory ownership. @@ -123,7 +136,7 @@ pub fn fchmod(fd: Fd, mode: Mode) -> io::Result<()> { #[cfg(not(target_os = "wasi"))] #[inline] pub fn fchown(fd: Fd, owner: Option, group: Option) -> io::Result<()> { - imp::fs::syscalls::fchown(fd.as_fd(), owner, group) + backend::fs::syscalls::fchown(fd.as_fd(), owner, group) } /// `fstat(fd)`—Queries metadata for an open file or directory. @@ -141,24 +154,55 @@ pub fn fchown(fd: Fd, owner: Option, group: Option) -> io::R /// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode #[inline] pub fn fstat(fd: Fd) -> io::Result { - imp::fs::syscalls::fstat(fd.as_fd()) + backend::fs::syscalls::fstat(fd.as_fd()) } /// `fstatfs(fd)`—Queries filesystem statistics for an open file or directory. /// +/// Compared to [`fstatvfs`], this function often provides more information, +/// though it's less portable. +/// /// # References /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/fstatfs.2.html #[cfg(not(any( + target_os = "haiku", target_os = "illumos", target_os = "netbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", -)))] // not implemented in libc for netbsd yet +)))] #[inline] pub fn fstatfs(fd: Fd) -> io::Result { - imp::fs::syscalls::fstatfs(fd.as_fd()) + backend::fs::syscalls::fstatfs(fd.as_fd()) +} + +/// `fstatvfs(fd)`—Queries filesystem statistics for an open file or +/// directory, POSIX version. +/// +/// Compared to [`fstatfs`], this function often provides less information, +/// but it is more portable. But even so, filesystems are very diverse and not +/// all the fields are meaningful for every filesystem. And `f_fsid` doesn't +/// seem to have a clear meaning anywhere. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html +/// [Linux]: https://man7.org/linux/man-pages/man2/fstatvfs.2.html +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +#[inline] +pub fn fstatvfs(fd: Fd) -> io::Result { + backend::fs::syscalls::fstatvfs(fd.as_fd()) } /// `futimens(fd, times)`—Sets timestamps for an open file or directory. @@ -171,7 +215,7 @@ pub fn fstatfs(fd: Fd) -> io::Result { /// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html #[inline] pub fn futimens(fd: Fd, times: &Timestamps) -> io::Result<()> { - imp::fs::syscalls::futimens(fd.as_fd(), times) + backend::fs::syscalls::futimens(fd.as_fd(), times) } /// `fallocate(fd, mode, offset, len)`—Adjusts file allocation. @@ -190,16 +234,18 @@ pub fn futimens(fd: Fd, times: &Timestamps) -> io::Result<()> { /// [Linux `fallocate`]: https://man7.org/linux/man-pages/man2/fallocate.2.html /// [Linux `posix_fallocate`]: https://man7.org/linux/man-pages/man3/posix_fallocate.3.html #[cfg(not(any( + target_os = "aix", target_os = "dragonfly", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] // not implemented in libc for netbsd yet #[inline] #[doc(alias = "posix_fallocate")] pub fn fallocate(fd: Fd, mode: FallocateFlags, offset: u64, len: u64) -> io::Result<()> { - imp::fs::syscalls::fallocate(fd.as_fd(), mode, offset, len) + backend::fs::syscalls::fallocate(fd.as_fd(), mode, offset, len) } /// `fcntl(fd, F_GETFL) & O_ACCMODE` @@ -214,7 +260,7 @@ pub fn is_file_read_write(fd: Fd) -> io::Result<(bool, bool)> { } pub(crate) fn _is_file_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { - let mode = imp::fs::syscalls::fcntl_getfl(fd)?; + let mode = backend::fs::syscalls::fcntl_getfl(fd)?; // Check for `O_PATH`. #[cfg(any( @@ -252,7 +298,7 @@ pub(crate) fn _is_file_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool) /// [`fcntl_fullfsync`]: https://docs.rs/rustix/*/x86_64-apple-darwin/rustix/fs/fn.fcntl_fullfsync.html #[inline] pub fn fsync(fd: Fd) -> io::Result<()> { - imp::fs::syscalls::fsync(fd.as_fd()) + backend::fs::syscalls::fsync(fd.as_fd()) } /// `fdatasync(fd)`—Ensures that file data is written to the underlying @@ -266,13 +312,14 @@ pub fn fsync(fd: Fd) -> io::Result<()> { /// [Linux]: https://man7.org/linux/man-pages/man2/fdatasync.2.html #[cfg(not(any( target_os = "dragonfly", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "redox", )))] #[inline] pub fn fdatasync(fd: Fd) -> io::Result<()> { - imp::fs::syscalls::fdatasync(fd.as_fd()) + backend::fs::syscalls::fdatasync(fd.as_fd()) } /// `ftruncate(fd, length)`—Sets the length of a file. @@ -285,7 +332,7 @@ pub fn fdatasync(fd: Fd) -> io::Result<()> { /// [Linux]: https://man7.org/linux/man-pages/man2/ftruncate.2.html #[inline] pub fn ftruncate(fd: Fd, length: u64) -> io::Result<()> { - imp::fs::syscalls::ftruncate(fd.as_fd(), length) + backend::fs::syscalls::ftruncate(fd.as_fd(), length) } /// `flock(fd, operation)`—Acquire or release an advisory lock on an open file. @@ -294,8 +341,8 @@ pub fn ftruncate(fd: Fd, length: u64) -> io::Result<()> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/flock.2.html -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "solaris", target_os = "wasi")))] #[inline] pub fn flock(fd: Fd, operation: FlockOperation) -> io::Result<()> { - imp::fs::syscalls::flock(fd.as_fd(), operation) + backend::fs::syscalls::flock(fd.as_fd(), operation) } diff --git a/vendor/rustix/src/fs/file_type.rs b/vendor/rustix/src/fs/file_type.rs index 75935c794..cf8fc1d38 100644 --- a/vendor/rustix/src/fs/file_type.rs +++ b/vendor/rustix/src/fs/file_type.rs @@ -1,4 +1,4 @@ -use crate::imp; +use crate::backend; /// `S_IF*` constants. -pub use imp::fs::types::FileType; +pub use backend::fs::types::FileType; diff --git a/vendor/rustix/src/fs/getpath.rs b/vendor/rustix/src/fs/getpath.rs index bc40890d1..8e14ff2f2 100644 --- a/vendor/rustix/src/fs/getpath.rs +++ b/vendor/rustix/src/fs/getpath.rs @@ -1,6 +1,6 @@ use crate::ffi::CString; -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; /// `fcntl(fd, F_GETPATH)` /// @@ -10,5 +10,5 @@ use imp::fd::AsFd; /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html #[inline] pub fn getpath(fd: Fd) -> io::Result { - imp::fs::syscalls::getpath(fd.as_fd()) + backend::fs::syscalls::getpath(fd.as_fd()) } diff --git a/vendor/rustix/src/fs/makedev.rs b/vendor/rustix/src/fs/makedev.rs index 75cc42540..5793058ff 100644 --- a/vendor/rustix/src/fs/makedev.rs +++ b/vendor/rustix/src/fs/makedev.rs @@ -1,5 +1,5 @@ +use crate::backend; use crate::fs::Dev; -use crate::imp; /// `makedev(maj, min)` /// @@ -9,7 +9,7 @@ use crate::imp; /// [Linux]: https://man7.org/linux/man-pages/man3/makedev.3.html #[inline] pub fn makedev(maj: u32, min: u32) -> Dev { - imp::fs::makedev::makedev(maj, min) + backend::fs::makedev::makedev(maj, min) } /// `minor(dev)` @@ -20,7 +20,7 @@ pub fn makedev(maj: u32, min: u32) -> Dev { /// [Linux]: https://man7.org/linux/man-pages/man3/minor.3.html #[inline] pub fn minor(dev: Dev) -> u32 { - imp::fs::makedev::minor(dev) + backend::fs::makedev::minor(dev) } /// `major(dev)` @@ -31,5 +31,5 @@ pub fn minor(dev: Dev) -> u32 { /// [Linux]: https://man7.org/linux/man-pages/man3/major.3.html #[inline] pub fn major(dev: Dev) -> u32 { - imp::fs::makedev::major(dev) + backend::fs::makedev::major(dev) } diff --git a/vendor/rustix/src/fs/memfd_create.rs b/vendor/rustix/src/fs/memfd_create.rs index 74b432739..dad964777 100644 --- a/vendor/rustix/src/fs/memfd_create.rs +++ b/vendor/rustix/src/fs/memfd_create.rs @@ -1,7 +1,7 @@ -use crate::io::{self, OwnedFd}; -use crate::{imp, path}; +use crate::fd::OwnedFd; +use crate::{backend, io, path}; -pub use imp::fs::types::MemfdFlags; +pub use backend::fs::types::MemfdFlags; /// `memfd_create(path, flags)` /// @@ -11,5 +11,5 @@ pub use imp::fs::types::MemfdFlags; /// [Linux]: https://man7.org/linux/man-pages/man2/memfd_create.2.html #[inline] pub fn memfd_create(path: P, flags: MemfdFlags) -> io::Result { - path.into_with_c_str(|path| imp::fs::syscalls::memfd_create(path, flags)) + path.into_with_c_str(|path| backend::fs::syscalls::memfd_create(path, flags)) } diff --git a/vendor/rustix/src/fs/mod.rs b/vendor/rustix/src/fs/mod.rs index 49b9c3b51..fa7f93aec 100644 --- a/vendor/rustix/src/fs/mod.rs +++ b/vendor/rustix/src/fs/mod.rs @@ -1,9 +1,7 @@ //! Filesystem operations. -#[cfg(feature = "fs")] mod abs; #[cfg(not(target_os = "redox"))] -#[cfg(any(feature = "fs", feature = "procfs"))] mod at; mod constants; #[cfg(any(target_os = "android", target_os = "linux"))] @@ -11,16 +9,17 @@ mod copy_file_range; #[cfg(not(target_os = "redox"))] mod cwd; #[cfg(not(target_os = "redox"))] -#[cfg(any(feature = "fs", feature = "procfs"))] mod dir; #[cfg(not(any( target_os = "dragonfly", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] mod fadvise; pub(crate) mod fcntl; @@ -35,19 +34,20 @@ mod getpath; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] mod makedev; #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] mod memfd_create; #[cfg(any(target_os = "android", target_os = "linux"))] -#[cfg(feature = "fs")] mod openat2; #[cfg(target_os = "linux")] mod sendfile; @@ -55,18 +55,25 @@ mod sendfile; mod statx; #[cfg(not(any( + target_os = "haiku", target_os = "illumos", target_os = "netbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] -#[cfg(feature = "fs")] pub use abs::statfs; -#[cfg(not(any(target_os = "illumos", target_os = "redox")))] -#[cfg(feature = "fs")] +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub use abs::statvfs; +#[cfg(not(any(target_os = "illumos", target_os = "redox", target_os = "solaris")))] pub use at::accessat; #[cfg(any(target_os = "ios", target_os = "macos"))] -#[cfg(feature = "fs")] pub use at::fclonefileat; #[cfg(not(any( target_os = "ios", @@ -74,16 +81,12 @@ pub use at::fclonefileat; target_os = "redox", target_os = "wasi", )))] -#[cfg(feature = "fs")] pub use at::mknodat; #[cfg(any(target_os = "android", target_os = "linux"))] -#[cfg(feature = "fs")] pub use at::renameat_with; #[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[cfg(feature = "fs")] pub use at::{chmodat, chownat}; #[cfg(not(target_os = "redox"))] -#[cfg(any(feature = "fs", feature = "procfs"))] pub use at::{ linkat, mkdirat, openat, readlinkat, renameat, statat, symlinkat, unlinkat, utimensat, RawMode, UTIME_NOW, UTIME_OMIT, @@ -105,16 +108,17 @@ pub use copy_file_range::copy_file_range; #[cfg(not(target_os = "redox"))] pub use cwd::cwd; #[cfg(not(target_os = "redox"))] -#[cfg(any(feature = "fs", feature = "procfs"))] pub use dir::{Dir, DirEntry}; #[cfg(not(any( target_os = "dragonfly", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use fadvise::{fadvise, Advice}; #[cfg(not(target_os = "wasi"))] @@ -136,30 +140,44 @@ pub use fcopyfile::{ }; #[cfg(not(any( target_os = "dragonfly", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "redox", )))] pub use fd::fdatasync; #[cfg(not(any( + target_os = "aix", target_os = "dragonfly", target_os = "illumos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use fd::{fallocate, FallocateFlags}; #[cfg(not(target_os = "wasi"))] -pub use fd::{fchmod, fchown, flock, FlockOperation}; +pub use fd::{fchmod, fchown}; +#[cfg(not(any(target_os = "solaris", target_os = "wasi")))] +pub use fd::{flock, FlockOperation}; pub use fd::{fstat, fsync, ftruncate, futimens, is_file_read_write, seek, tell, Stat, Timestamps}; #[cfg(not(any( + target_os = "haiku", target_os = "illumos", target_os = "netbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] -// not implemented in libc for netbsd yet pub use fd::{fstatfs, StatFs}; +#[cfg(not(any( + target_os = "haiku", + target_os = "illumos", + target_os = "redox", + target_os = "solaris", + target_os = "wasi", +)))] +pub use fd::{fstatvfs, StatVfs, StatVfsMountFlags}; #[cfg(any(target_os = "android", target_os = "linux"))] pub use fd::{FsWord, NFS_SUPER_MAGIC, PROC_SUPER_MAGIC}; pub use file_type::FileType; @@ -168,19 +186,20 @@ pub use getpath::getpath; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] pub use makedev::{major, makedev, minor}; #[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] pub use memfd_create::{memfd_create, MemfdFlags}; #[cfg(any(target_os = "android", target_os = "linux"))] -#[cfg(feature = "fs")] pub use openat2::openat2; #[cfg(target_os = "linux")] pub use sendfile::sendfile; diff --git a/vendor/rustix/src/fs/openat2.rs b/vendor/rustix/src/fs/openat2.rs index d6f77357b..4918e0034 100644 --- a/vendor/rustix/src/fs/openat2.rs +++ b/vendor/rustix/src/fs/openat2.rs @@ -1,7 +1,7 @@ -use crate::io::{self, OwnedFd}; -use crate::{imp, path}; -use imp::fd::AsFd; -use imp::fs::types::{Mode, OFlags, ResolveFlags}; +use crate::fd::OwnedFd; +use crate::{backend, io, path}; +use backend::fd::AsFd; +use backend::fs::types::{Mode, OFlags, ResolveFlags}; /// `openat2(dirfd, path, OpenHow { oflags, mode, resolve }, sizeof(OpenHow))` /// @@ -18,6 +18,6 @@ pub fn openat2( resolve: ResolveFlags, ) -> io::Result { path.into_with_c_str(|path| { - imp::fs::syscalls::openat2(dirfd.as_fd(), path, oflags, mode, resolve) + backend::fs::syscalls::openat2(dirfd.as_fd(), path, oflags, mode, resolve) }) } diff --git a/vendor/rustix/src/fs/sendfile.rs b/vendor/rustix/src/fs/sendfile.rs index a4d8c24d4..472ad37b2 100644 --- a/vendor/rustix/src/fs/sendfile.rs +++ b/vendor/rustix/src/fs/sendfile.rs @@ -1,5 +1,5 @@ -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; /// `sendfile(out_fd, in_fd, offset, count)` /// @@ -15,5 +15,5 @@ pub fn sendfile( offset: Option<&mut u64>, count: usize, ) -> io::Result { - imp::fs::syscalls::sendfile(out_fd.as_fd(), in_fd.as_fd(), offset, count) + backend::fs::syscalls::sendfile(out_fd.as_fd(), in_fd.as_fd(), offset, count) } diff --git a/vendor/rustix/src/fs/statx.rs b/vendor/rustix/src/fs/statx.rs index fa1d36779..383f109ce 100644 --- a/vendor/rustix/src/fs/statx.rs +++ b/vendor/rustix/src/fs/statx.rs @@ -3,10 +3,10 @@ use crate::fd::{AsFd, BorrowedFd}; use crate::ffi::CStr; use crate::fs::AtFlags; -use crate::{imp, io, path}; +use crate::{backend, io, path}; use core::sync::atomic::{AtomicU8, Ordering}; -pub use imp::fs::types::{Statx, StatxFlags, StatxTimestamp}; +pub use backend::fs::types::{Statx, StatxFlags, StatxTimestamp}; /// `statx(dirfd, path, flags, mask, statxbuf)` /// @@ -47,7 +47,7 @@ fn _statx( match STATX_STATE.load(Ordering::Relaxed) { 0 => statx_init(dirfd, path, flags, mask), 1 => Err(io::Errno::NOSYS), - _ => imp::fs::syscalls::statx(dirfd, path, flags, mask), + _ => backend::fs::syscalls::statx(dirfd, path, flags, mask), } } @@ -58,7 +58,7 @@ fn statx_init( flags: AtFlags, mask: StatxFlags, ) -> io::Result { - match imp::fs::syscalls::statx(dirfd, path, flags, mask) { + match backend::fs::syscalls::statx(dirfd, path, flags, mask) { Err(io::Errno::NOSYS) => statx_error_nosys(), Err(io::Errno::PERM) => statx_error_perm(), result => { @@ -82,7 +82,7 @@ fn statx_error_perm() -> io::Result { // Some old versions of Docker have `statx` fail with `PERM` when it isn't // recognized. Check whether `statx` really is available, and if so, fail // with `PERM`, and if not, treat it like `NOSYS`. - if imp::fs::syscalls::is_statx_available() { + if backend::fs::syscalls::is_statx_available() { STATX_STATE.store(2, Ordering::Relaxed); Err(io::Errno::PERM) } else { diff --git a/vendor/rustix/src/imp/libc/conv.rs b/vendor/rustix/src/imp/libc/conv.rs deleted file mode 100644 index fed15fbd1..000000000 --- a/vendor/rustix/src/imp/libc/conv.rs +++ /dev/null @@ -1,220 +0,0 @@ -//! Libc call arguments and return values are often things like `c_int`, -//! `c_uint`, or libc-specific pointer types. This module provides functions -//! for converting between rustix's types and libc types. - -#![allow(dead_code)] - -use super::c; -use super::fd::{AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, LibcFd, RawFd}; -#[cfg(not(windows))] -use super::offset::libc_off_t; -#[cfg(not(windows))] -use crate::ffi::CStr; -use crate::io::{self, OwnedFd}; -#[cfg(windows)] -use core::convert::TryInto; - -#[cfg(not(windows))] -#[inline] -pub(super) fn c_str(c: &CStr) -> *const c::c_char { - c.as_ptr() -} - -#[cfg(not(windows))] -#[inline] -pub(super) fn no_fd() -> LibcFd { - -1 -} - -#[inline] -pub(super) fn borrowed_fd(fd: BorrowedFd<'_>) -> LibcFd { - fd.as_raw_fd() as LibcFd -} - -#[inline] -pub(super) fn owned_fd(fd: OwnedFd) -> LibcFd { - fd.into_raw_fd() as LibcFd -} - -#[inline] -pub(super) fn ret(raw: c::c_int) -> io::Result<()> { - if raw == 0 { - Ok(()) - } else { - Err(io::Errno::last_os_error()) - } -} - -#[inline] -pub(super) fn syscall_ret(raw: c::c_long) -> io::Result<()> { - if raw == 0 { - Ok(()) - } else { - Err(io::Errno::last_os_error()) - } -} - -#[inline] -pub(super) fn nonnegative_ret(raw: c::c_int) -> io::Result<()> { - if raw >= 0 { - Ok(()) - } else { - Err(io::Errno::last_os_error()) - } -} - -#[inline] -pub(super) unsafe fn ret_infallible(raw: c::c_int) { - debug_assert_eq!(raw, 0, "unexpected error: {:?}", io::Errno::last_os_error()); -} - -#[inline] -pub(super) fn ret_c_int(raw: c::c_int) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -#[inline] -pub(super) fn ret_u32(raw: c::c_int) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw as u32) - } -} - -#[inline] -pub(super) fn ret_ssize_t(raw: c::ssize_t) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -#[inline] -pub(super) fn syscall_ret_ssize_t(raw: c::c_long) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw as c::ssize_t) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(super) fn syscall_ret_u32(raw: c::c_long) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - let r32 = raw as u32; - - // Converting `raw` to `u32` should be lossless. - debug_assert_eq!(r32 as c::c_long, raw); - - Ok(r32) - } -} - -#[cfg(not(windows))] -#[inline] -pub(super) fn ret_off_t(raw: libc_off_t) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -#[cfg(not(windows))] -#[inline] -pub(super) fn ret_pid_t(raw: c::pid_t) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(raw) - } -} - -/// Convert a `c_int` returned from a libc function to an `OwnedFd`, if valid. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a libc function -/// which returns an owned file descriptor. -#[inline] -pub(super) unsafe fn ret_owned_fd(raw: LibcFd) -> io::Result { - if raw == !0 { - Err(io::Errno::last_os_error()) - } else { - Ok(OwnedFd::from_raw_fd(raw as RawFd)) - } -} - -#[inline] -pub(super) fn ret_discarded_fd(raw: LibcFd) -> io::Result<()> { - if raw == !0 { - Err(io::Errno::last_os_error()) - } else { - Ok(()) - } -} - -#[inline] -pub(super) fn ret_discarded_char_ptr(raw: *mut c::c_char) -> io::Result<()> { - if raw.is_null() { - Err(io::Errno::last_os_error()) - } else { - Ok(()) - } -} - -/// Convert a `c_long` returned from `syscall` to an `OwnedFd`, if valid. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a `syscall` call -/// which returns an owned file descriptor. -#[cfg(not(windows))] -#[inline] -pub(super) unsafe fn syscall_ret_owned_fd(raw: c::c_long) -> io::Result { - if raw == -1 { - Err(io::Errno::last_os_error()) - } else { - Ok(OwnedFd::from_raw_fd(raw as RawFd)) - } -} - -/// Convert the buffer-length argument value of a `send` or `recv` call. -#[cfg(not(windows))] -#[inline] -pub(super) fn send_recv_len(len: usize) -> usize { - len -} - -/// Convert the buffer-length argument value of a `send` or `recv` call. -#[cfg(windows)] -#[inline] -pub(super) fn send_recv_len(len: usize) -> i32 { - // On Windows, the length argument has type `i32`; saturate the length, - // since `send` and `recv` are allowed to send and recv less data than - // requested. - len.try_into().unwrap_or(i32::MAX) -} - -/// Convert the return value of a `send` or `recv` call. -#[cfg(not(windows))] -#[inline] -pub(super) fn ret_send_recv(len: isize) -> io::Result { - ret_ssize_t(len) -} - -/// Convert the return value of a `send` or `recv` call. -#[cfg(windows)] -#[inline] -pub(super) fn ret_send_recv(len: i32) -> io::Result { - ret_ssize_t(len as isize) -} diff --git a/vendor/rustix/src/imp/libc/fs/dir.rs b/vendor/rustix/src/imp/libc/fs/dir.rs deleted file mode 100644 index 1e6b6066f..000000000 --- a/vendor/rustix/src/imp/libc/fs/dir.rs +++ /dev/null @@ -1,402 +0,0 @@ -use super::super::c; -use super::super::conv::owned_fd; -#[cfg(not(target_os = "illumos"))] -use super::types::FileType; -use crate::fd::{AsFd, BorrowedFd}; -use crate::ffi::CStr; -#[cfg(target_os = "wasi")] -use crate::ffi::CString; -use crate::fs::{fcntl_getfl, fstat, openat, Mode, OFlags, Stat}; -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] // not implemented in libc for netbsd yet -use crate::fs::{fstatfs, StatFs}; -use crate::io; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::process::fchdir; -#[cfg(target_os = "wasi")] -use alloc::borrow::ToOwned; -#[cfg(not(any( - target_os = "android", - target_os = "emscripten", - target_os = "l4re", - target_os = "linux", - target_os = "openbsd", -)))] -use c::dirent as libc_dirent; -#[cfg(not(any( - target_os = "android", - target_os = "emscripten", - target_os = "l4re", - target_os = "linux", -)))] -use c::readdir as libc_readdir; -#[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "l4re", - target_os = "linux", -))] -use c::{dirent64 as libc_dirent, readdir64 as libc_readdir}; -use core::fmt; -use core::mem::zeroed; -use core::ptr::NonNull; -use libc_errno::{errno, set_errno, Errno}; - -/// `DIR*` -#[repr(transparent)] -pub struct Dir(NonNull); - -impl Dir { - /// Construct a `Dir` that reads entries from the given directory - /// file descriptor. - #[inline] - pub fn read_from(fd: Fd) -> io::Result { - Self::_read_from(fd.as_fd()) - } - - #[inline] - fn _read_from(fd: BorrowedFd<'_>) -> io::Result { - // Given an arbitrary `OwnedFd`, it's impossible to know whether the - // user holds a `dup`'d copy which could continue to modify the - // file description state, which would cause Undefined Behavior after - // our call to `fdopendir`. To prevent this, we obtain an independent - // `OwnedFd`. - let flags = fcntl_getfl(&fd)?; - let fd_for_dir = openat(&fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; - - let raw = owned_fd(fd_for_dir); - unsafe { - let libc_dir = c::fdopendir(raw); - - if let Some(libc_dir) = NonNull::new(libc_dir) { - Ok(Self(libc_dir)) - } else { - let e = io::Errno::last_os_error(); - let _ = c::close(raw); - Err(e) - } - } - } - - /// `rewinddir(self)` - #[inline] - pub fn rewind(&mut self) { - unsafe { c::rewinddir(self.0.as_ptr()) } - } - - /// `readdir(self)`, where `None` means the end of the directory. - pub fn read(&mut self) -> Option> { - set_errno(Errno(0)); - let dirent_ptr = unsafe { libc_readdir(self.0.as_ptr()) }; - if dirent_ptr.is_null() { - let curr_errno = errno().0; - if curr_errno == 0 { - // We successfully reached the end of the stream. - None - } else { - // `errno` is unknown or non-zero, so an error occurred. - Some(Err(io::Errno(curr_errno))) - } - } else { - // We successfully read an entry. - unsafe { - // We have our own copy of OpenBSD's dirent; check that the - // layout minimally matches libc's. - #[cfg(target_os = "openbsd")] - check_dirent_layout(&*dirent_ptr); - - let result = DirEntry { - dirent: read_dirent(&*dirent_ptr.cast()), - - #[cfg(target_os = "wasi")] - name: CStr::from_ptr((*dirent_ptr).d_name.as_ptr()).to_owned(), - }; - - Some(Ok(result)) - } - } - } - - /// `fstat(self)` - #[inline] - pub fn stat(&self) -> io::Result { - fstat(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) - } - - /// `fstatfs(self)` - #[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", - )))] // not implemented in libc for netbsd yet - #[inline] - pub fn statfs(&self) -> io::Result { - fstatfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) - } - - /// `fchdir(self)` - #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] - #[inline] - pub fn chdir(&self) -> io::Result<()> { - fchdir(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.0.as_ptr())) }) - } -} - -// A `dirent` pointer returned from `readdir` may not point to a full `dirent` -// struct, as the name is NUL-terminated and memory may not be allocated for -// the full extent of the struct. Copy the fields one at a time. -unsafe fn read_dirent(input: &libc_dirent) -> libc_dirent { - #[cfg(not(target_os = "illumos"))] - let d_type = input.d_type; - - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "wasi", - )))] - let d_off = input.d_off; - - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - )))] - let d_ino = input.d_ino; - - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] - let d_fileno = input.d_fileno; - - #[cfg(not(target_os = "wasi"))] - let d_reclen = input.d_reclen; - - #[cfg(any( - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - target_os = "ios", - target_os = "macos", - ))] - let d_namlen = input.d_namlen; - - #[cfg(any(target_os = "ios", target_os = "macos"))] - let d_seekoff = input.d_seekoff; - - // Construct the input. Rust will give us an error if any OS has a input - // with a field that we missed here. And we can avoid blindly copying the - // whole `d_name` field, which may not be entirely allocated. - #[cfg_attr(target_os = "wasi", allow(unused_mut))] - let mut dirent = libc_dirent { - #[cfg(not(target_os = "illumos"))] - d_type, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "wasi", - )))] - d_off, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - )))] - d_ino, - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))] - d_fileno, - #[cfg(not(target_os = "wasi"))] - d_reclen, - #[cfg(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - d_namlen, - #[cfg(any(target_os = "ios", target_os = "macos"))] - d_seekoff, - // The `d_name` field is NUL-terminated, and we need to be careful not - // to read bytes past the NUL, even though they're within the nominal - // extent of the `struct dirent`, because they may not be allocated. So - // don't read it from `dirent_ptr`. - // - // In theory this could use `MaybeUninit::uninit().assume_init()`, but - // that [invokes undefined behavior]. - // - // [invokes undefined behavior]: https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#initialization-invariant - d_name: zeroed(), - #[cfg(target_os = "openbsd")] - __d_padding: zeroed(), - }; - - // Copy from d_name, reading up to and including the first NUL. - #[cfg(not(target_os = "wasi"))] - { - let name_len = CStr::from_ptr(input.d_name.as_ptr()) - .to_bytes_with_nul() - .len(); - dirent.d_name[..name_len].copy_from_slice(&input.d_name[..name_len]); - } - - dirent -} - -/// `Dir` implements `Send` but not `Sync`, because we use `readdir` which is -/// not guaranteed to be thread-safe. Users can wrap this in a `Mutex` if they -/// need `Sync`, which is effectively what'd need to do to implement `Sync` -/// ourselves. -unsafe impl Send for Dir {} - -impl Drop for Dir { - #[inline] - fn drop(&mut self) { - unsafe { c::closedir(self.0.as_ptr()) }; - } -} - -impl Iterator for Dir { - type Item = io::Result; - - #[inline] - fn next(&mut self) -> Option { - Self::read(self) - } -} - -impl fmt::Debug for Dir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Dir") - .field("fd", unsafe { &c::dirfd(self.0.as_ptr()) }) - .finish() - } -} - -/// `struct dirent` -#[derive(Debug)] -pub struct DirEntry { - dirent: libc_dirent, - - #[cfg(target_os = "wasi")] - name: CString, -} - -impl DirEntry { - /// Returns the file name of this directory entry. - #[inline] - pub fn file_name(&self) -> &CStr { - #[cfg(not(target_os = "wasi"))] - unsafe { - CStr::from_ptr(self.dirent.d_name.as_ptr()) - } - - #[cfg(target_os = "wasi")] - &self.name - } - - /// Returns the type of this directory entry. - #[cfg(not(target_os = "illumos"))] - #[inline] - pub fn file_type(&self) -> FileType { - FileType::from_dirent_d_type(self.dirent.d_type) - } - - /// Return the inode number of this directory entry. - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - )))] - #[inline] - pub fn ino(&self) -> u64 { - self.dirent.d_ino - } - - /// Return the inode number of this directory entry. - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - ))] - #[inline] - pub fn ino(&self) -> u64 { - #[allow(clippy::useless_conversion)] - self.dirent.d_fileno.into() - } -} - -/// libc's OpenBSD `dirent` has a private field so we can't construct it -/// directly, so we declare it ourselves to make all fields accessible. -#[cfg(target_os = "openbsd")] -#[repr(C)] -#[derive(Debug)] -struct libc_dirent { - d_fileno: c::ino_t, - d_off: c::off_t, - d_reclen: u16, - d_type: u8, - d_namlen: u8, - __d_padding: [u8; 4], - d_name: [c::c_char; 256], -} - -/// We have our own copy of OpenBSD's dirent; check that the layout -/// minimally matches libc's. -#[cfg(target_os = "openbsd")] -fn check_dirent_layout(dirent: &c::dirent) { - use crate::utils::as_ptr; - use core::mem::{align_of, size_of}; - - // Check that the basic layouts match. - assert_eq!(size_of::(), size_of::()); - assert_eq!(align_of::(), align_of::()); - - // Check that the field offsets match. - assert_eq!( - { - let z = libc_dirent { - d_fileno: 0_u64, - d_off: 0_i64, - d_reclen: 0_u16, - d_type: 0_u8, - d_namlen: 0_u8, - __d_padding: [0_u8; 4], - d_name: [0 as c::c_char; 256], - }; - let base = as_ptr(&z) as usize; - ( - (as_ptr(&z.d_fileno) as usize) - base, - (as_ptr(&z.d_off) as usize) - base, - (as_ptr(&z.d_reclen) as usize) - base, - (as_ptr(&z.d_type) as usize) - base, - (as_ptr(&z.d_namlen) as usize) - base, - (as_ptr(&z.d_name) as usize) - base, - ) - }, - { - let z = dirent; - let base = as_ptr(z) as usize; - ( - (as_ptr(&z.d_fileno) as usize) - base, - (as_ptr(&z.d_off) as usize) - base, - (as_ptr(&z.d_reclen) as usize) - base, - (as_ptr(&z.d_type) as usize) - base, - (as_ptr(&z.d_namlen) as usize) - base, - (as_ptr(&z.d_name) as usize) - base, - ) - } - ); -} diff --git a/vendor/rustix/src/imp/libc/fs/makedev.rs b/vendor/rustix/src/imp/libc/fs/makedev.rs deleted file mode 100644 index d9089e7f4..000000000 --- a/vendor/rustix/src/imp/libc/fs/makedev.rs +++ /dev/null @@ -1,90 +0,0 @@ -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -use super::super::c; -use crate::fs::Dev; - -#[cfg(not(any(target_os = "android", target_os = "emscripten")))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - unsafe { c::makedev(maj, min) } -} - -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // Android's `makedev` oddly has signed argument types. - unsafe { c::makedev(maj as i32, min as i32) } -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, - // so we do it ourselves. - ((u64::from(maj) & 0xffff_f000_u64) << 32) - | ((u64::from(maj) & 0x0000_0fff_u64) << 8) - | ((u64::from(min) & 0xffff_ff00_u64) << 12) - | (u64::from(min) & 0x0000_00ff_u64) -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - // Emscripten's `makedev` has a 32-bit return value. - Dev::from(unsafe { c::makedev(maj, min) }) -} - -#[cfg(not(any(target_os = "android", target_os = "emscripten")))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - unsafe { c::major(dev) } -} - -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - // Android's `major` oddly has signed return types. - (unsafe { c::major(dev) }) as u32 -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, - // so we do it ourselves. - (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - // Emscripten's `major` has a 32-bit argument value. - unsafe { c::major(dev as u32) } -} - -#[cfg(not(any(target_os = "android", target_os = "emscripten")))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - unsafe { c::minor(dev) } -} - -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - // Android's `minor` oddly has signed return types. - (unsafe { c::minor(dev) }) as u32 -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, - // so we do it ourselves. - (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - // Emscripten's `minor` has a 32-bit argument value. - unsafe { c::minor(dev as u32) } -} diff --git a/vendor/rustix/src/imp/libc/fs/mod.rs b/vendor/rustix/src/imp/libc/fs/mod.rs deleted file mode 100644 index 02b7b2d6a..000000000 --- a/vendor/rustix/src/imp/libc/fs/mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[cfg(not(target_os = "redox"))] -#[cfg(any(feature = "fs", feature = "procfs"))] -pub(crate) mod dir; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) mod makedev; -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/libc/fs/syscalls.rs b/vendor/rustix/src/imp/libc/fs/syscalls.rs deleted file mode 100644 index 0317367ab..000000000 --- a/vendor/rustix/src/imp/libc/fs/syscalls.rs +++ /dev/null @@ -1,1670 +0,0 @@ -//! libc syscalls supporting `rustix::fs`. - -use super::super::c; -use super::super::conv::{ - borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd, ret_ssize_t, -}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::{syscall_ret, syscall_ret_owned_fd, syscall_ret_ssize_t}; -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -use super::super::offset::libc_fallocate; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -use super::super::offset::libc_posix_fadvise; -#[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -use super::super::offset::libc_posix_fallocate; -use super::super::offset::{libc_fstat, libc_fstatat, libc_ftruncate, libc_lseek, libc_off_t}; -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -use super::super::offset::{libc_fstatfs, libc_statfs}; -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -use super::super::time::types::LibcTimespec; -use crate::fd::BorrowedFd; -#[cfg(not(target_os = "wasi"))] -use crate::fd::RawFd; -use crate::ffi::CStr; -#[cfg(any(target_os = "ios", target_os = "macos"))] -use crate::ffi::CString; -#[cfg(not(target_os = "illumos"))] -use crate::fs::Access; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -use crate::fs::Advice; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -use crate::fs::FallocateFlags; -#[cfg(not(target_os = "wasi"))] -use crate::fs::FlockOperation; -#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] -use crate::fs::MemfdFlags; -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] -use crate::fs::SealFlags; -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -// not implemented in libc for netbsd yet -use crate::fs::StatFs; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::fs::{cwd, RenameFlags, ResolveFlags, Statx, StatxFlags}; -#[cfg(not(any( - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -use crate::fs::{Dev, FileType}; -use crate::fs::{FdFlags, Mode, OFlags, Stat, Timestamps}; -use crate::io::{self, OwnedFd, SeekFrom}; -#[cfg(not(target_os = "wasi"))] -use crate::process::{Gid, Uid}; -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -use crate::utils::as_ptr; -use core::convert::TryInto; -#[cfg(any( - target_os = "android", - target_os = "ios", - target_os = "linux", - target_os = "macos", -))] -use core::mem::size_of; -use core::mem::MaybeUninit; -#[cfg(any(target_os = "android", target_os = "linux"))] -use core::ptr::null; -#[cfg(any( - target_os = "android", - target_os = "ios", - target_os = "linux", - target_os = "macos", -))] -use core::ptr::null_mut; -#[cfg(any(target_os = "ios", target_os = "macos"))] -use { - super::super::conv::nonnegative_ret, - crate::fs::{copyfile_state_t, CloneFlags, CopyfileFlags}, -}; -#[cfg(not(target_os = "redox"))] -use {super::super::offset::libc_openat, crate::fs::AtFlags}; - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -weak!(fn __utimensat64(c::c_int, *const c::c_char, *const LibcTimespec, c::c_int) -> c::c_int); -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -weak!(fn __futimens64(c::c_int, *const LibcTimespec) -> c::c_int); - -/// Use a direct syscall (via libc) for `openat`. -/// -/// This is only currently necessary as a workaround for old glibc; see below. -#[cfg(all(unix, target_env = "gnu"))] -fn openat_via_syscall( - dirfd: BorrowedFd<'_>, - path: &CStr, - oflags: OFlags, - mode: Mode, -) -> io::Result { - unsafe { - let dirfd = borrowed_fd(dirfd); - let path = c_str(path); - let oflags = oflags.bits(); - let mode = c::c_uint::from(mode.bits()); - ret_owned_fd(c::syscall( - c::SYS_openat, - c::c_long::from(dirfd), - path, - c::c_long::from(oflags), - mode as c::c_long, - ) as c::c_int) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn openat( - dirfd: BorrowedFd<'_>, - path: &CStr, - oflags: OFlags, - mode: Mode, -) -> io::Result { - // Work around . - // Basically old glibc versions don't handle O_TMPFILE correctly. - #[cfg(all(unix, target_env = "gnu"))] - if oflags.contains(OFlags::TMPFILE) && crate::imp::if_glibc_is_less_than_2_25() { - return openat_via_syscall(dirfd, path, oflags, mode); - } - unsafe { - // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since - // `libc_openat` is declared as a variadic function and narrower - // arguments are promoted. - ret_owned_fd(libc_openat( - borrowed_fd(dirfd), - c_str(path), - oflags.bits(), - c::c_uint::from(mode.bits()), - )) - } -} - -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn statfs(filename: &CStr) -> io::Result { - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(libc_statfs(c_str(filename), result.as_mut_ptr()))?; - Ok(result.assume_init()) - } -} - -#[cfg(not(target_os = "redox"))] -#[inline] -pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result { - unsafe { - ret_ssize_t(c::readlinkat( - borrowed_fd(dirfd), - c_str(path), - buf.as_mut_ptr().cast::(), - buf.len(), - )) - .map(|nread| nread as usize) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { - ret(c::mkdirat( - borrowed_fd(dirfd), - c_str(path), - mode.bits() as c::mode_t, - )) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn linkat( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - ret(c::linkat( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - flags.bits(), - )) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { - unsafe { ret(c::unlinkat(borrowed_fd(dirfd), c_str(path), flags.bits())) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn renameat( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, -) -> io::Result<()> { - unsafe { - ret(c::renameat( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - )) - } -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - // `getrandom` wasn't supported in glibc until 2.28. - weak_or_syscall! { - fn renameat2( - olddirfd: c::c_int, - oldpath: *const c::c_char, - newdirfd: c::c_int, - newpath: *const c::c_char, - flags: c::c_uint - ) via SYS_renameat2 -> c::c_int - } - - unsafe { - ret(renameat2( - borrowed_fd(old_dirfd), - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - flags.bits(), - )) - } -} - -/// At present, `libc` only has `renameat2` defined for glibc. On other -/// ABIs, `RenameFlags` has no flags defined, and we use plain `renameat`. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - assert!(flags.is_empty()); - renameat(old_dirfd, old_path, new_dirfd, new_path) -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn symlinkat( - old_path: &CStr, - new_dirfd: BorrowedFd<'_>, - new_path: &CStr, -) -> io::Result<()> { - unsafe { - ret(c::symlinkat( - c_str(old_path), - borrowed_fd(new_dirfd), - c_str(new_path), - )) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result { - // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use - // `statx`. - #[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - ))] - { - match statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { - Ok(x) => return statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(dirfd, path, flags), - Err(e) => return Err(e), - } - } - - // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and - // there's nothing practical we can do. - #[cfg(not(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - )))] - unsafe { - let mut stat = MaybeUninit::::uninit(); - ret(libc_fstatat( - borrowed_fd(dirfd), - c_str(path), - stat.as_mut_ptr(), - flags.bits(), - ))?; - Ok(stat.assume_init()) - } -} - -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), -))] -fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result { - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(libc_fstatat( - borrowed_fd(dirfd), - c_str(path), - result.as_mut_ptr(), - flags.bits(), - ))?; - stat64_to_stat(result.assume_init()) - } -} - -#[cfg(not(any(target_os = "emscripten", target_os = "illumos", target_os = "redox")))] -pub(crate) fn accessat( - dirfd: BorrowedFd<'_>, - path: &CStr, - access: Access, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - ret(c::faccessat( - borrowed_fd(dirfd), - c_str(path), - access.bits(), - flags.bits(), - )) - } -} - -#[cfg(target_os = "emscripten")] -pub(crate) fn accessat( - _dirfd: BorrowedFd<'_>, - _path: &CStr, - _access: Access, - _flags: AtFlags, -) -> io::Result<()> { - Ok(()) -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn utimensat( - dirfd: BorrowedFd<'_>, - path: &CStr, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - // 32-bit gnu version: libc has `utimensat` but it is not y2038 safe by - // default. - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_utimensat) = __utimensat64.get() { - let libc_times: [LibcTimespec; 2] = [ - times.last_access.clone().into(), - times.last_modification.clone().into(), - ]; - - ret(libc_utimensat( - borrowed_fd(dirfd), - c_str(path), - libc_times.as_ptr(), - flags.bits(), - )) - } else { - utimensat_old(dirfd, path, times, flags) - } - } - - // Main version: libc is y2038 safe and has `utimensat`. Or, the platform - // is not y2038 safe and there's nothing practical we can do. - #[cfg(not(any( - target_os = "ios", - target_os = "macos", - all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ) - )))] - unsafe { - // Assert that `Timestamps` has the expected layout. - let _ = core::mem::transmute::(times.clone()); - - ret(c::utimensat( - borrowed_fd(dirfd), - c_str(path), - as_ptr(times).cast(), - flags.bits(), - )) - } - - // `utimensat` was introduced in macOS 10.13. - #[cfg(any(target_os = "ios", target_os = "macos"))] - unsafe { - // ABI details - weak! { - fn utimensat( - c::c_int, - *const c::c_char, - *const c::timespec, - c::c_int - ) -> c::c_int - } - extern "C" { - fn setattrlist( - path: *const c::c_char, - attr_list: *const Attrlist, - attr_buf: *const c::c_void, - attr_buf_size: c::size_t, - options: c::c_ulong, - ) -> c::c_int; - } - const FSOPT_NOFOLLOW: c::c_ulong = 0x0000_0001; - - // If we have `utimensat`, use it. - if let Some(have_utimensat) = utimensat.get() { - // Assert that `Timestamps` has the expected layout. - let _ = core::mem::transmute::(times.clone()); - - return ret(have_utimensat( - borrowed_fd(dirfd), - c_str(path), - as_ptr(times).cast(), - flags.bits(), - )); - } - - // `setattrlistat` was introduced in 10.13 along with `utimensat`, so if - // we don't have `utimensat`, we don't have `setattrlistat` either. - // Emulate it using `fork`, and `fchdir` and [`setattrlist`]. - // - // [`setattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setattrlist.2.html - match c::fork() { - -1 => Err(io::Errno::IO), - 0 => { - if c::fchdir(borrowed_fd(dirfd)) != 0 { - let code = match libc_errno::errno().0 { - c::EACCES => 2, - c::ENOTDIR => 3, - _ => 1, - }; - c::_exit(code); - } - - let mut flags_arg = 0; - if flags.contains(AtFlags::SYMLINK_NOFOLLOW) { - flags_arg |= FSOPT_NOFOLLOW; - } - - let (attrbuf_size, times, attrs) = times_to_attrlist(times); - - if setattrlist( - c_str(path), - &attrs, - as_ptr(×).cast(), - attrbuf_size, - flags_arg, - ) != 0 - { - // Translate expected errno codes into ad-hoc integer - // values suitable for exit statuses. - let code = match libc_errno::errno().0 { - c::EACCES => 2, - c::ENOTDIR => 3, - c::EPERM => 4, - c::EROFS => 5, - c::ELOOP => 6, - c::ENOENT => 7, - c::ENAMETOOLONG => 8, - c::EINVAL => 9, - c::ESRCH => 10, - c::ENOTSUP => 11, - _ => 1, - }; - c::_exit(code); - } - - c::_exit(0); - } - child_pid => { - let mut wstatus = 0; - let _ = ret_c_int(c::waitpid(child_pid, &mut wstatus, 0))?; - if c::WIFEXITED(wstatus) { - // Translate our ad-hoc exit statuses back to errno codes. - match c::WEXITSTATUS(wstatus) { - 0 => Ok(()), - 2 => Err(io::Errno::ACCESS), - 3 => Err(io::Errno::NOTDIR), - 4 => Err(io::Errno::PERM), - 5 => Err(io::Errno::ROFS), - 6 => Err(io::Errno::LOOP), - 7 => Err(io::Errno::NOENT), - 8 => Err(io::Errno::NAMETOOLONG), - 9 => Err(io::Errno::INVAL), - 10 => Err(io::Errno::SRCH), - 11 => Err(io::Errno::NOTSUP), - _ => Err(io::Errno::IO), - } - } else { - Err(io::Errno::IO) - } - } - } - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -unsafe fn utimensat_old( - dirfd: BorrowedFd<'_>, - path: &CStr, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - let old_times = [ - c::timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_access.tv_nsec, - }, - c::timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_modification.tv_nsec, - }, - ]; - ret(c::utimensat( - borrowed_fd(dirfd), - c_str(path), - old_times.as_ptr(), - flags.bits(), - )) -} - -#[cfg(not(any( - target_os = "android", - target_os = "linux", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(c::fchmodat(borrowed_fd(dirfd), c_str(path), mode.bits(), 0)) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { - // Linux's `fchmodat` does not have a flags argument. - unsafe { - // Pass `mode` as a `c_uint` even if `mode_t` is narrower, since - // `libc_openat` is declared as a variadic function and narrower - // arguments are promoted. - syscall_ret(c::syscall( - c::SYS_fchmodat, - borrowed_fd(dirfd), - c_str(path), - c::c_uint::from(mode.bits()), - )) - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn fclonefileat( - srcfd: BorrowedFd<'_>, - dst_dirfd: BorrowedFd<'_>, - dst: &CStr, - flags: CloneFlags, -) -> io::Result<()> { - syscall! { - fn fclonefileat( - srcfd: BorrowedFd<'_>, - dst_dirfd: BorrowedFd<'_>, - dst: *const c::c_char, - flags: c::c_int - ) via SYS_fclonefileat -> c::c_int - } - - unsafe { ret(fclonefileat(srcfd, dst_dirfd, c_str(dst), flags.bits())) } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn chownat( - dirfd: BorrowedFd<'_>, - path: &CStr, - owner: Option, - group: Option, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); - ret(c::fchownat( - borrowed_fd(dirfd), - c_str(path), - ow, - gr, - flags.bits(), - )) - } -} - -#[cfg(not(any( - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) fn mknodat( - dirfd: BorrowedFd<'_>, - path: &CStr, - file_type: FileType, - mode: Mode, - dev: Dev, -) -> io::Result<()> { - unsafe { - ret(c::mknodat( - borrowed_fd(dirfd), - c_str(path), - (mode.bits() | file_type.as_raw_mode()) as c::mode_t, - dev.try_into().map_err(|_e| io::Errno::PERM)?, - )) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn copy_file_range( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: u64, -) -> io::Result { - assert_eq!(size_of::(), size_of::()); - - let mut off_in_val: c::loff_t = 0; - let mut off_out_val: c::loff_t = 0; - // Silently cast; we'll get `EINVAL` if the value is negative. - let off_in_ptr = if let Some(off_in) = &off_in { - off_in_val = (**off_in) as i64; - &mut off_in_val - } else { - null_mut() - }; - let off_out_ptr = if let Some(off_out) = &off_out { - off_out_val = (**off_out) as i64; - &mut off_out_val - } else { - null_mut() - }; - let len: usize = len.try_into().unwrap_or(usize::MAX); - let copied = unsafe { - syscall_ret_ssize_t(c::syscall( - c::SYS_copy_file_range, - borrowed_fd(fd_in), - off_in_ptr, - borrowed_fd(fd_out), - off_out_ptr, - len, - 0, // no flags are defined yet - ))? - }; - if let Some(off_in) = off_in { - *off_in = off_in_val as u64; - } - if let Some(off_out) = off_out { - *off_out = off_out_val as u64; - } - Ok(copied as u64) -} - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub(crate) fn fadvise(fd: BorrowedFd<'_>, offset: u64, len: u64, advice: Advice) -> io::Result<()> { - let offset = offset as i64; - let len = len as i64; - - // FreeBSD returns `EINVAL` on invalid offsets; emulate the POSIX behavior. - #[cfg(target_os = "freebsd")] - let offset = if (offset as i64) < 0 { - i64::MAX - } else { - offset - }; - - // FreeBSD returns `EINVAL` on overflow; emulate the POSIX behavior. - #[cfg(target_os = "freebsd")] - let len = if len > 0 && offset.checked_add(len).is_none() { - i64::MAX - offset - } else { - len - }; - - let err = unsafe { libc_posix_fadvise(borrowed_fd(fd), offset, len, advice as c::c_int) }; - - // `posix_fadvise` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } -} - -pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result { - unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFD)).map(FdFlags::from_bits_truncate) } -} - -pub(crate) fn fcntl_setfd(fd: BorrowedFd<'_>, flags: FdFlags) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFD, flags.bits())) } -} - -pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result { - unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFL)).map(OFlags::from_bits_truncate) } -} - -pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFL, flags.bits())) } -} - -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] -pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GET_SEALS)) - .map(|flags| SealFlags::from_bits_unchecked(flags)) - } -} - -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] -pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_ADD_SEALS, seals.bits())) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result { - unsafe { ret_owned_fd(c::fcntl(borrowed_fd(fd), c::F_DUPFD_CLOEXEC, min)) } -} - -pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { - let (whence, offset): (c::c_int, libc_off_t) = match pos { - SeekFrom::Start(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (c::SEEK_SET, pos as i64) - } - SeekFrom::End(offset) => (c::SEEK_END, offset), - SeekFrom::Current(offset) => (c::SEEK_CUR, offset), - }; - let offset = unsafe { ret_off_t(libc_lseek(borrowed_fd(fd), offset, whence))? }; - Ok(offset as u64) -} - -pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result { - let offset = unsafe { ret_off_t(libc_lseek(borrowed_fd(fd), 0, c::SEEK_CUR))? }; - Ok(offset as u64) -} - -#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { - unsafe { ret(c::fchmod(borrowed_fd(fd), mode.bits())) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { - // Use `c::syscall` rather than `c::fchmod` because some libc - // implementations, such as musl, add extra logic to `fchmod` to emulate - // support for `O_PATH`, which uses `/proc` outside our control and - // interferes with our own use of `O_PATH`. - unsafe { - syscall_ret(c::syscall( - c::SYS_fchmod, - borrowed_fd(fd), - c::c_uint::from(mode.bits()), - )) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option, group: Option) -> io::Result<()> { - // Use `c::syscall` rather than `c::fchown` because some libc - // implementations, such as musl, add extra logic to `fchown` to emulate - // support for `O_PATH`, which uses `/proc` outside our control and - // interferes with our own use of `O_PATH`. - unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); - syscall_ret(c::syscall(c::SYS_fchown, borrowed_fd(fd), ow, gr)) - } -} - -#[cfg(not(any(target_os = "android", target_os = "linux", target_os = "wasi")))] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option, group: Option) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); - ret(c::fchown(borrowed_fd(fd), ow, gr)) - } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { - unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) } -} - -pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { - // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use - // `statx`. - #[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - ))] - { - match statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { - Ok(x) => return statx_to_stat(x), - Err(io::Errno::NOSYS) => fstat_old(fd), - Err(e) => return Err(e), - } - } - - // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and - // there's nothing practical we can do. - #[cfg(not(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), - )))] - unsafe { - let mut stat = MaybeUninit::::uninit(); - ret(libc_fstat(borrowed_fd(fd), stat.as_mut_ptr()))?; - Ok(stat.assume_init()) - } -} - -#[cfg(all( - any(target_os = "android", target_os = "linux"), - any(target_pointer_width = "32", target_arch = "mips64"), -))] -fn fstat_old(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(libc_fstat(borrowed_fd(fd), result.as_mut_ptr()))?; - stat64_to_stat(result.assume_init()) - } -} - -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] // not implemented in libc for netbsd yet -pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result { - let mut statfs = MaybeUninit::::uninit(); - unsafe { - ret(libc_fstatfs(borrowed_fd(fd), statfs.as_mut_ptr()))?; - Ok(statfs.assume_init()) - } -} - -pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { - // 32-bit gnu version: libc has `futimens` but it is not y2038 safe by default. - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_futimens) = __futimens64.get() { - let libc_times: [LibcTimespec; 2] = [ - times.last_access.clone().into(), - times.last_modification.clone().into(), - ]; - - ret(libc_futimens(borrowed_fd(fd), libc_times.as_ptr())) - } else { - futimens_old(fd, times) - } - } - - // Main version: libc is y2038 safe and has `futimens`. Or, the platform - // is not y2038 safe and there's nothing practical we can do. - #[cfg(not(any( - target_os = "ios", - target_os = "macos", - all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ) - )))] - unsafe { - // Assert that `Timestamps` has the expected layout. - let _ = core::mem::transmute::(times.clone()); - - ret(c::futimens(borrowed_fd(fd), as_ptr(times).cast())) - } - - // `futimens` was introduced in macOS 10.13. - #[cfg(any(target_os = "ios", target_os = "macos"))] - unsafe { - // ABI details. - weak! { - fn futimens(c::c_int, *const c::timespec) -> c::c_int - } - extern "C" { - fn fsetattrlist( - fd: c::c_int, - attr_list: *const Attrlist, - attr_buf: *const c::c_void, - attr_buf_size: c::size_t, - options: c::c_ulong, - ) -> c::c_int; - } - - // If we have `futimens`, use it. - if let Some(have_futimens) = futimens.get() { - // Assert that `Timestamps` has the expected layout. - let _ = core::mem::transmute::(times.clone()); - - return ret(have_futimens(borrowed_fd(fd), as_ptr(times).cast())); - } - - // Otherwise use `fsetattrlist`. - let (attrbuf_size, times, attrs) = times_to_attrlist(times); - - ret(fsetattrlist( - borrowed_fd(fd), - &attrs, - as_ptr(×).cast(), - attrbuf_size, - 0, - )) - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -unsafe fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { - let old_times = [ - c::timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_access.tv_nsec, - }, - c::timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times.last_modification.tv_nsec, - }, - ]; - - ret(c::futimens(borrowed_fd(fd), old_times.as_ptr())) -} - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub(crate) fn fallocate( - fd: BorrowedFd<'_>, - mode: FallocateFlags, - offset: u64, - len: u64, -) -> io::Result<()> { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - let len = len as i64; - - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] - unsafe { - ret(libc_fallocate(borrowed_fd(fd), mode.bits(), offset, len)) - } - - #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))] - { - assert!(mode.is_empty()); - let err = unsafe { libc_posix_fallocate(borrowed_fd(fd), offset, len) }; - - // `posix_fallocate` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn fallocate( - fd: BorrowedFd<'_>, - mode: FallocateFlags, - offset: u64, - len: u64, -) -> io::Result<()> { - let offset: i64 = offset.try_into().map_err(|_e| io::Errno::INVAL)?; - let len = len as i64; - - assert!(mode.is_empty()); - - let new_len = offset.checked_add(len).ok_or_else(|| io::Errno::FBIG)?; - let mut store = c::fstore_t { - fst_flags: c::F_ALLOCATECONTIG, - fst_posmode: c::F_PEOFPOSMODE, - fst_offset: 0, - fst_length: new_len, - fst_bytesalloc: 0, - }; - unsafe { - if c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store) == -1 { - store.fst_flags = c::F_ALLOCATEALL; - let _ = ret_c_int(c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store))?; - } - ret(c::ftruncate(borrowed_fd(fd), new_len)) - } -} - -pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fsync(borrowed_fd(fd))) } -} - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "ios", - target_os = "macos", - target_os = "redox", -)))] -pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fdatasync(borrowed_fd(fd))) } -} - -pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { - let length = length.try_into().map_err(|_overflow_err| io::Errno::FBIG)?; - unsafe { ret(libc_ftruncate(borrowed_fd(fd), length)) } -} - -#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] -pub(crate) fn memfd_create(path: &CStr, flags: MemfdFlags) -> io::Result { - #[cfg(target_os = "freebsd")] - weakcall! { - fn memfd_create( - name: *const c::c_char, - flags: c::c_uint - ) -> c::c_int - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - weak_or_syscall! { - fn memfd_create( - name: *const c::c_char, - flags: c::c_uint - ) via SYS_memfd_create -> c::c_int - } - - unsafe { ret_owned_fd(memfd_create(c_str(path), flags.bits())) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn openat2( - dirfd: BorrowedFd<'_>, - path: &CStr, - oflags: OFlags, - mode: Mode, - resolve: ResolveFlags, -) -> io::Result { - let oflags: i32 = oflags.bits(); - let open_how = OpenHow { - oflag: u64::from(oflags as u32), - mode: u64::from(mode.bits()), - resolve: resolve.bits(), - }; - - unsafe { - syscall_ret_owned_fd(c::syscall( - SYS_OPENAT2, - borrowed_fd(dirfd), - c_str(path), - &open_how, - SIZEOF_OPEN_HOW, - )) - } -} -#[cfg(all( - target_pointer_width = "32", - any(target_os = "android", target_os = "linux"), -))] -const SYS_OPENAT2: i32 = 437; -#[cfg(all( - target_pointer_width = "64", - any(target_os = "android", target_os = "linux"), -))] -const SYS_OPENAT2: i64 = 437; - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[repr(C)] -#[derive(Debug)] -struct OpenHow { - oflag: u64, - mode: u64, - resolve: u64, -} -#[cfg(any(target_os = "android", target_os = "linux"))] -const SIZEOF_OPEN_HOW: usize = size_of::(); - -#[cfg(target_os = "linux")] -pub(crate) fn sendfile( - out_fd: BorrowedFd<'_>, - in_fd: BorrowedFd<'_>, - offset: Option<&mut u64>, - count: usize, -) -> io::Result { - unsafe { - let nsent = ret_ssize_t(c::sendfile64( - borrowed_fd(out_fd), - borrowed_fd(in_fd), - offset.map_or(null_mut(), crate::utils::as_mut_ptr).cast(), - count, - ))?; - Ok(nsent as usize) - } -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "32", -))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result { - Ok(Stat { - st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor).into(), - st_mode: x.stx_mode.into(), - st_nlink: x.stx_nlink.into(), - st_uid: x.stx_uid.into(), - st_gid: x.stx_gid.into(), - st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor).into(), - st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: x.stx_blksize.into(), - st_blocks: x.stx_blocks.into(), - st_atime: x - .stx_atime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_atime_nsec: x.stx_atime.tv_nsec as _, - st_mtime: x - .stx_mtime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime_nsec: x.stx_mtime.tv_nsec as _, - st_ctime: x - .stx_ctime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime_nsec: x.stx_ctime.tv_nsec as _, - st_ino: x.stx_ino.into(), - }) -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -/// -/// mips64' `struct stat64` in libc has private fields, and `stx_blocks` -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_arch = "mips64", -))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result { - let mut result: Stat = unsafe { core::mem::zeroed() }; - - result.st_dev = crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor); - result.st_mode = x.stx_mode.into(); - result.st_nlink = x.stx_nlink.into(); - result.st_uid = x.stx_uid.into(); - result.st_gid = x.stx_gid.into(); - result.st_rdev = crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor); - result.st_size = x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_blksize = x.stx_blksize.into(); - result.st_blocks = x.stx_blocks.try_into().map_err(|_e| io::Errno::OVERFLOW)?; - result.st_atime = x - .stx_atime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_atime_nsec = x.stx_atime.tv_nsec as _; - result.st_mtime = x - .stx_mtime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_mtime_nsec = x.stx_mtime.tv_nsec as _; - result.st_ctime = x - .stx_ctime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_ctime_nsec = x.stx_ctime.tv_nsec as _; - result.st_ino = x.stx_ino.into(); - - Ok(result) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "32", -))] -fn stat64_to_stat(s64: c::stat64) -> io::Result { - Ok(Stat { - st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime: s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime_nsec: s64 - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime: s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mtime_nsec: s64 - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime: s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_ctime_nsec: s64 - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, - }) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -/// -/// mips64' `struct stat64` in libc has private fields, and `st_blocks` has -/// type `i64`. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_arch = "mips64", -))] -fn stat64_to_stat(s64: c::stat64) -> io::Result { - let mut result: Stat = unsafe { core::mem::zeroed() }; - - result.st_dev = s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_mode = s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_nlink = s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_uid = s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_gid = s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_rdev = s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_size = s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_blksize = s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_blocks = s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_atime = s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_atime_nsec = s64 - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_mtime = s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_mtime_nsec = s64 - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_ctime = s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?; - result.st_ctime_nsec = s64 - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?; - result.st_ino = s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?; - - Ok(result) -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[allow(non_upper_case_globals)] -mod sys { - use super::{c, BorrowedFd, Statx}; - - #[cfg(all(target_os = "android", target_arch = "arm"))] - const SYS_statx: c::c_long = 397; - #[cfg(all(target_os = "android", target_arch = "x86"))] - const SYS_statx: c::c_long = 383; - #[cfg(all(target_os = "android", target_arch = "aarch64"))] - const SYS_statx: c::c_long = 291; - #[cfg(all(target_os = "android", target_arch = "x86_64"))] - const SYS_statx: c::c_long = 332; - - weak_or_syscall! { - pub(super) fn statx( - pirfd: BorrowedFd<'_>, - path: *const c::c_char, - flags: c::c_int, - mask: c::c_uint, - buf: *mut Statx - ) via SYS_statx -> c::c_int - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[allow(non_upper_case_globals)] -pub(crate) fn statx( - dirfd: BorrowedFd<'_>, - path: &CStr, - flags: AtFlags, - mask: StatxFlags, -) -> io::Result { - let mut statx_buf = MaybeUninit::::uninit(); - unsafe { - ret(sys::statx( - dirfd, - c_str(path), - flags.bits(), - mask.bits(), - statx_buf.as_mut_ptr(), - ))?; - Ok(statx_buf.assume_init()) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn is_statx_available() -> bool { - unsafe { - // Call `statx` with null pointers so that if it fails for any reason - // other than `EFAULT`, we know it's not supported. - matches!( - ret(sys::statx(cwd(), null(), 0, 0, null_mut())), - Err(io::Errno::FAULT) - ) - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) unsafe fn fcopyfile( - from: BorrowedFd<'_>, - to: BorrowedFd<'_>, - state: copyfile_state_t, - flags: CopyfileFlags, -) -> io::Result<()> { - extern "C" { - fn fcopyfile( - from: c::c_int, - to: c::c_int, - state: copyfile_state_t, - flags: c::c_uint, - ) -> c::c_int; - } - - nonnegative_ret(fcopyfile( - borrowed_fd(from), - borrowed_fd(to), - state, - flags.bits(), - )) -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn copyfile_state_alloc() -> io::Result { - extern "C" { - fn copyfile_state_alloc() -> copyfile_state_t; - } - - let result = unsafe { copyfile_state_alloc() }; - if result.0.is_null() { - Err(io::Errno::last_os_error()) - } else { - Ok(result) - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { - extern "C" { - fn copyfile_state_free(state: copyfile_state_t) -> c::c_int; - } - - nonnegative_ret(copyfile_state_free(state)) -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -const COPYFILE_STATE_COPIED: u32 = 8; - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) unsafe fn copyfile_state_get_copied(state: copyfile_state_t) -> io::Result { - let mut copied = MaybeUninit::::uninit(); - copyfile_state_get(state, COPYFILE_STATE_COPIED, copied.as_mut_ptr().cast())?; - Ok(copied.assume_init()) -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) unsafe fn copyfile_state_get( - state: copyfile_state_t, - flag: u32, - dst: *mut c::c_void, -) -> io::Result<()> { - extern "C" { - fn copyfile_state_get(state: copyfile_state_t, flag: u32, dst: *mut c::c_void) -> c::c_int; - } - - nonnegative_ret(copyfile_state_get(state, flag, dst)) -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result { - // The use of PATH_MAX is generally not encouraged, but it - // is inevitable in this case because macOS defines `fcntl` with - // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no - // alternatives. If a better method is invented, it should be used - // instead. - let mut buf = vec![0; c::PATH_MAX as usize]; - - // From the [macOS `fcntl` man page]: - // `F_GETPATH` - Get the path of the file descriptor `Fildes`. The argument - // must be a buffer of size `MAXPATHLEN` or greater. - // - // [macOS `fcntl` man page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html - unsafe { - ret(c::fcntl(borrowed_fd(fd), c::F_GETPATH, buf.as_mut_ptr()))?; - } - - let l = buf.iter().position(|&c| c == 0).unwrap(); - buf.truncate(l); - - // TODO: On Rust 1.56, we can use `shrink_to` here. - //buf.shrink_to(l + 1); - buf.shrink_to_fit(); - - Ok(CString::new(buf).unwrap()) -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn fcntl_rdadvise(fd: BorrowedFd<'_>, offset: u64, len: u64) -> io::Result<()> { - // From the [macOS `fcntl` man page]: - // `F_RDADVISE` - Issue an advisory read async with no copy to user. - // - // The `F_RDADVISE` command operates on the following structure which holds - // information passed from the user to the system: - // - // ```c - // struct radvisory { - // off_t ra_offset; /* offset into the file */ - // int ra_count; /* size of the read */ - // }; - // ``` - // - // [macOS `fcntl` man page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html - let ra_offset = match offset.try_into() { - Ok(len) => len, - // If this conversion fails, the user is providing an offset outside - // any possible file extent, so just ignore it. - Err(_) => return Ok(()), - }; - let ra_count = match len.try_into() { - Ok(len) => len, - // If this conversion fails, the user is providing a dubiously large - // hint which is unlikely to improve performance. - Err(_) => return Ok(()), - }; - unsafe { - let radvisory = c::radvisory { - ra_offset, - ra_count, - }; - ret(c::fcntl(borrowed_fd(fd), c::F_RDADVISE, &radvisory)) - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn fcntl_fullfsync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_FULLFSYNC)) } -} - -/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist` -/// arguments. -#[cfg(any(target_os = "ios", target_os = "macos"))] -fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrlist) { - // ABI details. - const ATTR_CMN_MODTIME: u32 = 0x0000_0400; - const ATTR_CMN_ACCTIME: u32 = 0x0000_1000; - const ATTR_BIT_MAP_COUNT: u16 = 5; - - let mut times = times.clone(); - - // If we have any `UTIME_NOW` elements, replace them with the current time. - if times.last_access.tv_nsec == c::UTIME_NOW || times.last_modification.tv_nsec == c::UTIME_NOW - { - let now = { - let mut tv = c::timeval { - tv_sec: 0, - tv_usec: 0, - }; - unsafe { - let r = c::gettimeofday(&mut tv, null_mut()); - assert_eq!(r, 0); - } - c::timespec { - tv_sec: tv.tv_sec, - tv_nsec: (tv.tv_usec * 1000) as _, - } - }; - if times.last_access.tv_nsec == c::UTIME_NOW { - times.last_access = now; - } - if times.last_modification.tv_nsec == c::UTIME_NOW { - times.last_modification = now; - } - } - - // Pack the return values following the rules for [`getattrlist`]. - // - // [`getattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getattrlist.2.html - let mut times_size = 0; - let mut attrs = Attrlist { - bitmapcount: ATTR_BIT_MAP_COUNT, - reserved: 0, - commonattr: 0, - volattr: 0, - dirattr: 0, - fileattr: 0, - forkattr: 0, - }; - let mut return_times = [c::timespec { - tv_sec: 0, - tv_nsec: 0, - }; 2]; - let mut times_index = 0; - if times.last_modification.tv_nsec != c::UTIME_OMIT { - attrs.commonattr |= ATTR_CMN_MODTIME; - return_times[times_index] = times.last_modification; - times_index += 1; - times_size += size_of::(); - } - if times.last_access.tv_nsec != c::UTIME_OMIT { - attrs.commonattr |= ATTR_CMN_ACCTIME; - return_times[times_index] = times.last_access; - times_size += size_of::(); - } - - (times_size, return_times, attrs) -} - -/// Support type for `Attrlist`. -#[cfg(any(target_os = "ios", target_os = "macos"))] -type Attrgroup = u32; - -/// Attribute list for use with `setattrlist`. -#[cfg(any(target_os = "ios", target_os = "macos"))] -#[repr(C)] -struct Attrlist { - bitmapcount: u16, - reserved: u16, - commonattr: Attrgroup, - volattr: Attrgroup, - dirattr: Attrgroup, - fileattr: Attrgroup, - forkattr: Attrgroup, -} diff --git a/vendor/rustix/src/imp/libc/fs/types.rs b/vendor/rustix/src/imp/libc/fs/types.rs deleted file mode 100644 index 9d892daf0..000000000 --- a/vendor/rustix/src/imp/libc/fs/types.rs +++ /dev/null @@ -1,1028 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `FD_*` constants for use with [`fcntl_getfd`] and [`fcntl_setfd`]. - /// - /// [`fcntl_getfd`]: crate::fs::fcntl_getfd - /// [`fcntl_setfd`]: crate::fs::fcntl_setfd - pub struct FdFlags: c::c_int { - /// `FD_CLOEXEC` - const CLOEXEC = c::FD_CLOEXEC; - } -} - -bitflags! { - /// `*_OK` constants for use with [`accessat`]. - /// - /// [`accessat`]: fn.accessat.html - pub struct Access: c::c_int { - /// `R_OK` - const READ_OK = c::R_OK; - - /// `W_OK` - const WRITE_OK = c::W_OK; - - /// `X_OK` - const EXEC_OK = c::X_OK; - - /// `F_OK` - const EXISTS = c::F_OK; - } -} - -#[cfg(not(target_os = "redox"))] -bitflags! { - /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` - /// functions. - /// - /// [`openat`]: crate::fs::openat - /// [`statat`]: crate::fs::statat - pub struct AtFlags: c::c_int { - /// `AT_REMOVEDIR` - const REMOVEDIR = c::AT_REMOVEDIR; - - /// `AT_SYMLINK_FOLLOW` - const SYMLINK_FOLLOW = c::AT_SYMLINK_FOLLOW; - - /// `AT_SYMLINK_NOFOLLOW` - const SYMLINK_NOFOLLOW = c::AT_SYMLINK_NOFOLLOW; - - /// `AT_EMPTY_PATH` - #[cfg(any( - target_os = "android", - target_os = "fuchsia", - target_os = "linux", - ))] - const EMPTY_PATH = c::AT_EMPTY_PATH; - - /// `AT_EACCESS` - #[cfg(not(any(target_os = "emscripten", target_os = "android")))] - const EACCESS = c::AT_EACCESS; - - /// `AT_STATX_SYNC_AS_STAT` - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const STATX_SYNC_AS_STAT = c::AT_STATX_SYNC_AS_STAT; - - /// `AT_STATX_FORCE_SYNC` - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const STATX_FORCE_SYNC = c::AT_STATX_FORCE_SYNC; - - /// `AT_STATX_DONT_SYNC` - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const STATX_DONT_SYNC = c::AT_STATX_DONT_SYNC; - } -} - -bitflags! { - /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. - /// - /// [`openat`]: crate::fs::openat - /// [`chmodat`]: crate::fs::chmodat - /// [`fchmod`]: crate::fs::fchmod - pub struct Mode: RawMode { - /// `S_IRWXU` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const RWXU = c::S_IRWXU as RawMode; - - /// `S_IRUSR` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const RUSR = c::S_IRUSR as RawMode; - - /// `S_IWUSR` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const WUSR = c::S_IWUSR as RawMode; - - /// `S_IXUSR` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const XUSR = c::S_IXUSR as RawMode; - - /// `S_IRWXG` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const RWXG = c::S_IRWXG as RawMode; - - /// `S_IRGRP` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const RGRP = c::S_IRGRP as RawMode; - - /// `S_IWGRP` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const WGRP = c::S_IWGRP as RawMode; - - /// `S_IXGRP` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const XGRP = c::S_IXGRP as RawMode; - - /// `S_IRWXO` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const RWXO = c::S_IRWXO as RawMode; - - /// `S_IROTH` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const ROTH = c::S_IROTH as RawMode; - - /// `S_IWOTH` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const WOTH = c::S_IWOTH as RawMode; - - /// `S_IXOTH` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const XOTH = c::S_IXOTH as RawMode; - - /// `S_ISUID` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const SUID = c::S_ISUID as RawMode; - - /// `S_ISGID` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const SGID = c::S_ISGID as RawMode; - - /// `S_ISVTX` - #[cfg(not(target_os = "wasi"))] // WASI doesn't have Unix-style mode flags. - const SVTX = c::S_ISVTX as RawMode; - } -} - -impl Mode { - /// Construct a `Mode` from the mode bits of the `st_mode` field of - /// a `Stat`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - Self::from_bits_truncate(st_mode) - } - - /// Construct an `st_mode` value from `Stat`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - self.bits() - } -} - -bitflags! { - /// `O_*` constants for use with [`openat`]. - /// - /// [`openat`]: crate::fs::openat - pub struct OFlags: c::c_int { - /// `O_ACCMODE` - const ACCMODE = c::O_ACCMODE; - - /// Similar to `ACCMODE`, but just includes the read/write flags, and - /// no other flags. - /// - /// Some implementations include `O_PATH` in `O_ACCMODE`, when - /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `O_PATH` may mean that the read/write - /// bits don't have their usual meaning. - const RWMODE = c::O_RDONLY | c::O_WRONLY | c::O_RDWR; - - /// `O_APPEND` - const APPEND = c::O_APPEND; - - /// `O_CREAT` - #[doc(alias = "CREAT")] - const CREATE = c::O_CREAT; - - /// `O_DIRECTORY` - const DIRECTORY = c::O_DIRECTORY; - - /// `O_DSYNC` - #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "redox")))] - const DSYNC = c::O_DSYNC; - - /// `O_EXCL` - const EXCL = c::O_EXCL; - - /// `O_FSYNC` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - all(target_os = "linux", not(target_env = "musl")), - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - const FSYNC = c::O_FSYNC; - - /// `O_NOFOLLOW` - const NOFOLLOW = c::O_NOFOLLOW; - - /// `O_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - - /// `O_RDONLY` - const RDONLY = c::O_RDONLY; - - /// `O_WRONLY` - const WRONLY = c::O_WRONLY; - - /// `O_RDWR` - const RDWR = c::O_RDWR; - - /// `O_NOCTTY` - #[cfg(not(target_os = "redox"))] - const NOCTTY = c::O_NOCTTY; - - /// `O_RSYNC` - #[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - ))] - const RSYNC = c::O_RSYNC; - - /// `O_SYNC` - #[cfg(not(target_os = "redox"))] - const SYNC = c::O_SYNC; - - /// `O_TRUNC` - const TRUNC = c::O_TRUNC; - - /// `O_PATH` - #[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "linux", - target_os = "redox", - ))] - const PATH = c::O_PATH; - - /// `O_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - - /// `O_TMPFILE` - #[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "linux", - ))] - const TMPFILE = c::O_TMPFILE; - - /// `O_NOATIME` - #[cfg(any( - target_os = "android", - target_os = "fuchsia", - target_os = "linux", - ))] - const NOATIME = c::O_NOATIME; - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -bitflags! { - /// `CLONE_*` constants for use with [`fclonefileat`]. - /// - /// [`fclonefileat`]: crate::fs::fclonefileat - pub struct CloneFlags: c::c_int { - /// `CLONE_NOFOLLOW` - const NOFOLLOW = 1; - - /// `CLONE_NOOWNERCOPY` - const NOOWNERCOPY = 2; - } -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -mod copyfile { - pub(super) const ACL: u32 = 1 << 0; - pub(super) const STAT: u32 = 1 << 1; - pub(super) const XATTR: u32 = 1 << 2; - pub(super) const DATA: u32 = 1 << 3; - pub(super) const SECURITY: u32 = STAT | ACL; - pub(super) const METADATA: u32 = SECURITY | XATTR; - pub(super) const ALL: u32 = METADATA | DATA; -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -bitflags! { - /// `COPYFILE_*` constants. - pub struct CopyfileFlags: c::c_uint { - /// `COPYFILE_ACL` - const ACL = copyfile::ACL; - - /// `COPYFILE_STAT` - const STAT = copyfile::STAT; - - /// `COPYFILE_XATTR` - const XATTR = copyfile::XATTR; - - /// `COPYFILE_DATA` - const DATA = copyfile::DATA; - - /// `COPYFILE_SECURITY` - const SECURITY = copyfile::SECURITY; - - /// `COPYFILE_METADATA` - const METADATA = copyfile::METADATA; - - /// `COPYFILE_ALL` - const ALL = copyfile::ALL; - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `RESOLVE_*` constants for use with [`openat2`]. - /// - /// [`openat2`]: crate::fs::openat2 - #[derive(Default)] - pub struct ResolveFlags: u64 { - /// `RESOLVE_NO_XDEV` - const NO_XDEV = 0x01; - - /// `RESOLVE_NO_MAGICLINKS` - const NO_MAGICLINKS = 0x02; - - /// `RESOLVE_NO_SYMLINKS` - const NO_SYMLINKS = 0x04; - - /// `RESOLVE_BENEATH` - const BENEATH = 0x08; - - /// `RESOLVE_IN_ROOT` - const IN_ROOT = 0x10; - - /// `RESOLVE_CACHED` (since Linux 5.12) - const CACHED = 0x20; - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `RENAME_*` constants for use with [`renameat_with`]. - /// - /// [`renameat_with`]: crate::fs::renameat_with - pub struct RenameFlags: c::c_uint { - /// `RENAME_EXCHANGE` - const EXCHANGE = c::RENAME_EXCHANGE as _; - - /// `RENAME_NOREPLACE` - const NOREPLACE = c::RENAME_NOREPLACE as _; - - /// `RENAME_WHITEOUT` - const WHITEOUT = c::RENAME_WHITEOUT as _; - } -} - -/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. -/// -/// [`mknodat`]: crate::fs::mknodat -/// [`Stat`]: crate::fs::Stat -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum FileType { - /// `S_IFREG` - RegularFile = c::S_IFREG as isize, - - /// `S_IFDIR` - Directory = c::S_IFDIR as isize, - - /// `S_IFLNK` - Symlink = c::S_IFLNK as isize, - - /// `S_IFIFO` - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. - #[doc(alias = "IFO")] - Fifo = c::S_IFIFO as isize, - - /// `S_IFSOCK` - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. - Socket = c::S_IFSOCK as isize, - - /// `S_IFCHR` - CharacterDevice = c::S_IFCHR as isize, - - /// `S_IFBLK` - BlockDevice = c::S_IFBLK as isize, - - /// An unknown filesystem object. - Unknown, -} - -impl FileType { - /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of - /// a `Stat`. - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - match (st_mode as c::mode_t) & c::S_IFMT { - c::S_IFREG => Self::RegularFile, - c::S_IFDIR => Self::Directory, - c::S_IFLNK => Self::Symlink, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. - c::S_IFIFO => Self::Fifo, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. - c::S_IFSOCK => Self::Socket, - c::S_IFCHR => Self::CharacterDevice, - c::S_IFBLK => Self::BlockDevice, - _ => Self::Unknown, - } - } - - /// Construct an `st_mode` value from `Stat`. - pub const fn as_raw_mode(self) -> RawMode { - match self { - Self::RegularFile => c::S_IFREG as RawMode, - Self::Directory => c::S_IFDIR as RawMode, - Self::Symlink => c::S_IFLNK as RawMode, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. - Self::Fifo => c::S_IFIFO as RawMode, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. - Self::Socket => c::S_IFSOCK as RawMode, - Self::CharacterDevice => c::S_IFCHR as RawMode, - Self::BlockDevice => c::S_IFBLK as RawMode, - Self::Unknown => c::S_IFMT as RawMode, - } - } - - /// Construct a `FileType` from the `d_type` field of a `c::dirent`. - #[cfg(not(any(target_os = "illumos", target_os = "redox")))] - pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { - match d_type { - c::DT_REG => Self::RegularFile, - c::DT_DIR => Self::Directory, - c::DT_LNK => Self::Symlink, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_SOCK`. - c::DT_SOCK => Self::Socket, - #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_FIFO`. - c::DT_FIFO => Self::Fifo, - c::DT_CHR => Self::CharacterDevice, - c::DT_BLK => Self::BlockDevice, - // c::DT_UNKNOWN | - _ => Self::Unknown, - } - } -} - -/// `POSIX_FADV_*` constants for use with [`fadvise`]. -/// -/// [`fadvise`]: crate::fs::fadvise -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum Advice { - /// `POSIX_FADV_NORMAL` - Normal = c::POSIX_FADV_NORMAL as c::c_uint, - - /// `POSIX_FADV_SEQUENTIAL` - Sequential = c::POSIX_FADV_SEQUENTIAL as c::c_uint, - - /// `POSIX_FADV_RANDOM` - Random = c::POSIX_FADV_RANDOM as c::c_uint, - - /// `POSIX_FADV_NOREUSE` - NoReuse = c::POSIX_FADV_NOREUSE as c::c_uint, - - /// `POSIX_FADV_WILLNEED` - WillNeed = c::POSIX_FADV_WILLNEED as c::c_uint, - - /// `POSIX_FADV_DONTNEED` - DontNeed = c::POSIX_FADV_DONTNEED as c::c_uint, -} - -#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))] -bitflags! { - /// `MFD_*` constants for use with [`memfd_create`]. - /// - /// [`memfd_create`]: crate::fs::memfd_create - pub struct MemfdFlags: c::c_uint { - /// `MFD_CLOEXEC` - const CLOEXEC = c::MFD_CLOEXEC; - - /// `MFD_ALLOW_SEALING` - const ALLOW_SEALING = c::MFD_ALLOW_SEALING; - - /// `MFD_HUGETLB` (since Linux 4.14) - const HUGETLB = c::MFD_HUGETLB; - - /// `MFD_HUGE_64KB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_64KB = c::MFD_HUGE_64KB; - /// `MFD_HUGE_512JB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_512KB = c::MFD_HUGE_512KB; - /// `MFD_HUGE_1MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_1MB = c::MFD_HUGE_1MB; - /// `MFD_HUGE_2MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_2MB = c::MFD_HUGE_2MB; - /// `MFD_HUGE_8MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_8MB = c::MFD_HUGE_8MB; - /// `MFD_HUGE_16MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_16MB = c::MFD_HUGE_16MB; - /// `MFD_HUGE_32MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_32MB = c::MFD_HUGE_32MB; - /// `MFD_HUGE_256MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_256MB = c::MFD_HUGE_256MB; - /// `MFD_HUGE_512MB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_512MB = c::MFD_HUGE_512MB; - /// `MFD_HUGE_1GB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_1GB = c::MFD_HUGE_1GB; - /// `MFD_HUGE_2GB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_2GB = c::MFD_HUGE_2GB; - /// `MFD_HUGE_16GB` - #[cfg(any(target_os = "android", target_os = "linux"))] - const HUGE_16GB = c::MFD_HUGE_16GB; - } -} - -#[cfg(any( - target_os = "android", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "linux", -))] -bitflags! { - /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and - /// [`fcntl_get_seals`]. - /// - /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals - /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals - pub struct SealFlags: i32 { - /// `F_SEAL_SEAL`. - const SEAL = c::F_SEAL_SEAL; - /// `F_SEAL_SHRINK`. - const SHRINK = c::F_SEAL_SHRINK; - /// `F_SEAL_GROW`. - const GROW = c::F_SEAL_GROW; - /// `F_SEAL_WRITE`. - const WRITE = c::F_SEAL_WRITE; - /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) - #[cfg(any(target_os = "android", target_os = "linux"))] - const FUTURE_WRITE = c::F_SEAL_FUTURE_WRITE; - } -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -bitflags! { - /// `STATX_*` constants for use with [`statx`]. - /// - /// [`statx`]: crate::fs::statx - pub struct StatxFlags: u32 { - /// `STATX_TYPE` - const TYPE = c::STATX_TYPE; - - /// `STATX_MODE` - const MODE = c::STATX_MODE; - - /// `STATX_NLINK` - const NLINK = c::STATX_NLINK; - - /// `STATX_UID` - const UID = c::STATX_UID; - - /// `STATX_GID` - const GID = c::STATX_GID; - - /// `STATX_ATIME` - const ATIME = c::STATX_ATIME; - - /// `STATX_MTIME` - const MTIME = c::STATX_MTIME; - - /// `STATX_CTIME` - const CTIME = c::STATX_CTIME; - - /// `STATX_INO` - const INO = c::STATX_INO; - - /// `STATX_SIZE` - const SIZE = c::STATX_SIZE; - - /// `STATX_BLOCKS` - const BLOCKS = c::STATX_BLOCKS; - - /// `STATX_BASIC_STATS` - const BASIC_STATS = c::STATX_BASIC_STATS; - - /// `STATX_BTIME` - const BTIME = c::STATX_BTIME; - - /// `STATX_MNT_ID` (since Linux 5.8) - const MNT_ID = c::STATX_MNT_ID; - - /// `STATX_ALL` - const ALL = c::STATX_ALL; - } -} - -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -bitflags! { - /// `STATX_*` constants for use with [`statx`]. - /// - /// [`statx`]: crate::fs::statx - pub struct StatxFlags: u32 { - /// `STATX_TYPE` - const TYPE = 0x0001; - - /// `STATX_MODE` - const MODE = 0x0002; - - /// `STATX_NLINK` - const NLINK = 0x0004; - - /// `STATX_UID` - const UID = 0x0008; - - /// `STATX_GID` - const GID = 0x0010; - - /// `STATX_ATIME` - const ATIME = 0x0020; - - /// `STATX_MTIME` - const MTIME = 0x0040; - - /// `STATX_CTIME` - const CTIME = 0x0080; - - /// `STATX_INO` - const INO = 0x0100; - - /// `STATX_SIZE` - const SIZE = 0x0200; - - /// `STATX_BLOCKS` - const BLOCKS = 0x0400; - - /// `STATX_BASIC_STATS` - const BASIC_STATS = 0x07ff; - - /// `STATX_BTIME` - const BTIME = 0x800; - - /// `STATX_MNT_ID` (since Linux 5.8) - const MNT_ID = 0x1000; - - /// `STATX_ALL` - const ALL = 0xfff; - } -} - -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -bitflags! { - /// `FALLOC_FL_*` constants for use with [`fallocate`]. - /// - /// [`fallocate`]: crate::fs::fallocate - pub struct FallocateFlags: i32 { - /// `FALLOC_FL_KEEP_SIZE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - const KEEP_SIZE = c::FALLOC_FL_KEEP_SIZE; - /// `FALLOC_FL_PUNCH_HOLE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - const PUNCH_HOLE = c::FALLOC_FL_PUNCH_HOLE; - /// `FALLOC_FL_NO_HIDE_STALE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "wasi", - )))] - const NO_HIDE_STALE = c::FALLOC_FL_NO_HIDE_STALE; - /// `FALLOC_FL_COLLAPSE_RANGE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "emscripten", - target_os = "wasi", - )))] - const COLLAPSE_RANGE = c::FALLOC_FL_COLLAPSE_RANGE; - /// `FALLOC_FL_ZERO_RANGE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "emscripten", - target_os = "wasi", - )))] - const ZERO_RANGE = c::FALLOC_FL_ZERO_RANGE; - /// `FALLOC_FL_INSERT_RANGE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "emscripten", - target_os = "wasi", - )))] - const INSERT_RANGE = c::FALLOC_FL_INSERT_RANGE; - /// `FALLOC_FL_UNSHARE_RANGE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "emscripten", - target_os = "wasi", - )))] - const UNSHARE_RANGE = c::FALLOC_FL_UNSHARE_RANGE; - } -} - -/// `LOCK_*` constants for use with [`flock`] -/// -/// [`flock`]: crate::fs::flock -#[cfg(not(target_os = "wasi"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(i32)] -pub enum FlockOperation { - /// `LOCK_SH` - LockShared = c::LOCK_SH, - /// `LOCK_EX` - LockExclusive = c::LOCK_EX, - /// `LOCK_UN` - Unlock = c::LOCK_UN, - /// `LOCK_SH | LOCK_NB` - NonBlockingLockShared = c::LOCK_SH | c::LOCK_NB, - /// `LOCK_EX | LOCK_NB` - NonBlockingLockExclusive = c::LOCK_EX | c::LOCK_NB, - /// `LOCK_UN | LOCK_NB` - NonBlockingUnlock = c::LOCK_UN | c::LOCK_NB, -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(not(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -)))] -pub type Stat = c::stat; - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(any( - all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "64", - ), - target_os = "emscripten", - target_os = "l4re", -))] -pub type Stat = c::stat64; - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -// On 32-bit, Linux's `struct stat64` has a 32-bit `st_mtime` and friends, so -// we use our own struct, populated from `statx` where possible, to avoid the -// y2038 bug. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - target_pointer_width = "32", -))] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -pub struct Stat { - pub st_dev: u64, - pub st_mode: u32, - pub st_nlink: u32, - pub st_uid: u32, - pub st_gid: u32, - pub st_rdev: u64, - pub st_size: i64, - pub st_blksize: u32, - pub st_blocks: u64, - pub st_atime: u64, - pub st_atime_nsec: u32, - pub st_mtime: u64, - pub st_mtime_nsec: u32, - pub st_ctime: u64, - pub st_ctime_nsec: u32, - pub st_ino: u64, -} - -/// `struct statfs` for use with [`fstatfs`]. -/// -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(not(any( - target_os = "android", - target_os = "emscripten", - target_os = "illumos", - target_os = "linux", - target_os = "l4re", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[allow(clippy::module_name_repetitions)] -pub type StatFs = c::statfs; - -/// `struct statfs` for use with [`fstatfs`]. -/// -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -pub type StatFs = c::statfs64; - -/// `struct statx` for use with [`statx`]. -/// -/// [`statx`]: crate::fs::statx -#[cfg(all(target_os = "linux", target_env = "gnu"))] -// Use the glibc `struct statx`. -pub type Statx = c::statx; - -/// `struct statx_timestamp` for use with [`Statx`]. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -// Use the glibc `struct statx_timestamp`. -pub type StatxTimestamp = c::statx; - -/// `struct statx` for use with [`statx`]. -/// -/// [`statx`]: crate::fs::statx -// Non-glibc ABIs don't currently declare a `struct statx`, so we declare it -// ourselves. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[repr(C)] -#[allow(missing_docs)] -pub struct Statx { - pub stx_mask: u32, - pub stx_blksize: u32, - pub stx_attributes: u64, - pub stx_nlink: u32, - pub stx_uid: u32, - pub stx_gid: u32, - pub stx_mode: u16, - __statx_pad1: [u16; 1], - pub stx_ino: u64, - pub stx_size: u64, - pub stx_blocks: u64, - pub stx_attributes_mask: u64, - pub stx_atime: StatxTimestamp, - pub stx_btime: StatxTimestamp, - pub stx_ctime: StatxTimestamp, - pub stx_mtime: StatxTimestamp, - pub stx_rdev_major: u32, - pub stx_rdev_minor: u32, - pub stx_dev_major: u32, - pub stx_dev_minor: u32, - pub stx_mnt_id: u64, - __statx_pad2: u64, - __statx_pad3: [u64; 12], -} - -/// `struct statx_timestamp` for use with [`Statx`]. -// Non-glibc ABIs don't currently declare a `struct statx_timestamp`, so we -// declare it ourselves. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[repr(C)] -#[allow(missing_docs)] -pub struct StatxTimestamp { - pub tv_sec: i64, - pub tv_nsec: u32, - pub __statx_timestamp_pad1: [i32; 1], -} - -/// `mode_t` -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -pub type RawMode = c::mode_t; - -/// `mode_t` -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -pub type RawMode = c::c_uint; - -/// `dev_t` -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -pub type Dev = c::dev_t; - -/// `dev_t` -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -pub type Dev = c::c_ulonglong; - -/// `__fsword_t` -#[cfg(all( - target_os = "linux", - not(target_env = "musl"), - not(target_arch = "s390x"), -))] -pub type FsWord = c::__fsword_t; - -/// `__fsword_t` -#[cfg(all( - any(target_os = "android", all(target_os = "linux", target_env = "musl")), - target_pointer_width = "32", -))] -pub type FsWord = u32; - -/// `__fsword_t` -#[cfg(all( - any(target_os = "android", all(target_os = "linux", target_env = "musl")), - not(target_arch = "s390x"), - target_pointer_width = "64", -))] -pub type FsWord = u64; - -/// `__fsword_t` -// s390x uses `u32` for `statfs` entries, even though `__fsword_t` is `u64`. -#[cfg(all(target_os = "linux", target_arch = "s390x"))] -pub type FsWord = u32; - -#[cfg(not(target_os = "redox"))] -pub use c::{UTIME_NOW, UTIME_OMIT}; - -/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - not(target_env = "musl"), -))] -pub const PROC_SUPER_MAGIC: FsWord = c::PROC_SUPER_MAGIC as FsWord; - -/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. -#[cfg(all( - any(target_os = "android", target_os = "linux"), - not(target_env = "musl"), -))] -pub const NFS_SUPER_MAGIC: FsWord = c::NFS_SUPER_MAGIC as FsWord; - -/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. -#[cfg(all(any(target_os = "android", target_os = "linux"), target_env = "musl"))] -pub const PROC_SUPER_MAGIC: FsWord = 0x0000_9fa0; - -/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. -#[cfg(all(any(target_os = "android", target_os = "linux"), target_env = "musl"))] -pub const NFS_SUPER_MAGIC: FsWord = 0x0000_6969; - -/// `copyfile_state_t`—State for use with [`fcopyfile`]. -/// -/// [`fcopyfile`]: crate::fs::fcopyfile -#[cfg(any(target_os = "ios", target_os = "macos"))] -#[allow(non_camel_case_types)] -#[repr(transparent)] -#[derive(Copy, Clone)] -pub struct copyfile_state_t(pub(crate) *mut c::c_void); diff --git a/vendor/rustix/src/imp/libc/io/epoll.rs b/vendor/rustix/src/imp/libc/io/epoll.rs deleted file mode 100644 index a95e6b5cd..000000000 --- a/vendor/rustix/src/imp/libc/io/epoll.rs +++ /dev/null @@ -1,568 +0,0 @@ -//! epoll support. -//! -//! This is an experiment, and it isn't yet clear whether epoll is the right -//! level of abstraction at which to introduce safety. But it works fairly well -//! in simple examples 🙂. -//! -//! # Examples -//! -//! ```rust,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::{self, Epoll}; -//! use rustix::io::{ioctl_fionbio, read, write}; -//! use rustix::net::{ -//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4, -//! SocketType, -//! }; -//! use std::os::unix::io::AsRawFd; -//! -//! // Create a socket and listen on it. -//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; -//! 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::new(epoll::CreateFlags::CLOEXEC, epoll::Owning::new())?; -//! -//! // Remember the socket raw fd, which we use for comparisons only. -//! let raw_listen_sock = listen_sock.as_fd().as_raw_fd(); -//! -//! // Register the socket with the epoll object. -//! epoll.add(listen_sock, epoll::EventFlags::IN)?; -//! -//! // Process events. -//! let mut event_list = epoll::EventVec::with_capacity(4); -//! loop { -//! epoll.wait(&mut event_list, -1)?; -//! for (_event_flags, target) in &event_list { -//! if target.as_raw_fd() == raw_listen_sock { -//! // 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(&*target)?; -//! ioctl_fionbio(&conn_sock, true)?; -//! epoll.add(conn_sock, epoll::EventFlags::OUT | epoll::EventFlags::ET)?; -//! } else { -//! // Write a message to the stream and then unregister it. -//! write(&*target, b"hello\n")?; -//! let _ = epoll.del(target)?; -//! } -//! } -//! } -//! # } -//! # #[cfg(not(feature = "net"))] -//! # fn main() {} -//! ``` - -use super::super::c; -use super::super::conv::{ret, ret_owned_fd, ret_u32}; -use crate::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}; -#[cfg(not(feature = "rustc-dep-of-std"))] -use crate::fd::{FromFd, FromRawFd, IntoFd, IntoRawFd}; -use crate::io::{self, OwnedFd}; -use alloc::vec::Vec; -use bitflags::bitflags; -use core::convert::TryInto; -use core::fmt; -use core::marker::PhantomData; -use core::ops::Deref; -use core::ptr::{null, null_mut}; - -bitflags! { - /// `EPOLL_*` for use with [`Epoll::new`]. - pub struct CreateFlags: c::c_int { - /// `EPOLL_CLOEXEC` - const CLOEXEC = c::EPOLL_CLOEXEC; - } -} - -bitflags! { - /// `EPOLL*` for use with [`Epoll::add`]. - #[derive(Default)] - pub struct EventFlags: u32 { - /// `EPOLLIN` - const IN = c::EPOLLIN as u32; - - /// `EPOLLOUT` - const OUT = c::EPOLLOUT as u32; - - /// `EPOLLPRI` - const PRI = c::EPOLLPRI as u32; - - /// `EPOLLERR` - const ERR = c::EPOLLERR as u32; - - /// `EPOLLHUP` - const HUP = c::EPOLLHUP as u32; - - /// `EPOLLET` - const ET = c::EPOLLET as u32; - - /// `EPOLLONESHOT` - const ONESHOT = c::EPOLLONESHOT as u32; - - /// `EPOLLWAKEUP` - const WAKEUP = c::EPOLLWAKEUP as u32; - - /// `EPOLLEXCLUSIVE` - #[cfg(not(target_os = "android"))] - const EXCLUSIVE = c::EPOLLEXCLUSIVE as u32; - } -} - -/// A reference to a `T`. -pub struct Ref<'a, T> { - t: T, - _phantom: PhantomData<&'a T>, -} - -impl<'a, T> Ref<'a, T> { - #[inline] - fn new(t: T) -> Self { - Self { - t, - _phantom: PhantomData, - } - } - - #[inline] - fn consume(self) -> T { - self.t - } -} - -impl<'a, T> Deref for Ref<'a, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - &self.t - } -} - -impl<'a, T: fmt::Debug> fmt::Debug for Ref<'a, T> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - self.t.fmt(fmt) - } -} - -/// A trait for data stored within an [`Epoll`] instance. -pub trait Context { - /// The type of an element owned by this context. - type Data; - - /// The type of a value used to refer to an element owned by this context. - type Target: AsFd; - - /// Assume ownership of `data`, and returning a `Target`. - fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target>; - - /// Encode `target` as a `u64`. The only requirement on this value is that - /// it be decodable by `decode`. - fn encode(&self, target: Ref<'_, Self::Target>) -> u64; - - /// Decode `raw`, which is a value encoded by `encode`, into a `Target`. - /// - /// # Safety - /// - /// `raw` must be a `u64` value returned from `encode`, from the same - /// context, and within the context's lifetime. - unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target>; - - /// Release ownership of the value referred to by `target` and return it. - fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data; -} - -/// A type implementing [`Context`] where the `Data` type is `BorrowedFd<'a>`. -pub struct Borrowing<'a> { - _phantom: PhantomData>, -} - -impl<'a> Context for Borrowing<'a> { - type Data = BorrowedFd<'a>; - type Target = BorrowedFd<'a>; - - #[inline] - fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { - Ref::new(data) - } - - #[inline] - fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { - target.as_raw_fd() as u64 - } - - #[inline] - unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { - Ref::new(BorrowedFd::<'a>::borrow_raw(raw as RawFd)) - } - - #[inline] - fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { - target.consume() - } -} - -/// A type implementing [`Context`] where the `Data` type is `T`, a type -/// implementing `IntoFd` and `FromFd`. -/// -/// This may be used with [`OwnedFd`], or higher-level types like -/// [`std::fs::File`] or [`std::net::TcpStream`]. -#[cfg(not(feature = "rustc-dep-of-std"))] -pub struct Owning<'context, T: IntoFd + FromFd> { - _phantom: PhantomData<&'context T>, -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: IntoFd + FromFd> Owning<'context, T> { - /// Creates a new empty `Owning`. - #[allow(clippy::new_without_default)] // This is a specialized type that doesn't need to be generically constructible. - #[inline] - pub fn new() -> Self { - Self { - _phantom: PhantomData, - } - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> Context for Owning<'context, T> { - type Data = T; - type Target = BorrowedFd<'context>; - - #[inline] - fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { - let raw_fd = data.into_fd().into_raw_fd(); - // Safety: `epoll` will assign ownership of the file descriptor to the - // kernel epoll object. We use `IntoFd`+`IntoRawFd` to consume the - // `Data` and extract the raw file descriptor and then "borrow" it - // with `borrow_raw` knowing that the borrow won't outlive the - // kernel epoll object. - unsafe { Ref::new(BorrowedFd::<'context>::borrow_raw(raw_fd)) } - } - - #[inline] - fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { - target.as_fd().as_raw_fd() as u64 - } - - #[inline] - unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { - Ref::new(BorrowedFd::<'context>::borrow_raw(raw as RawFd)) - } - - #[inline] - fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { - // The file descriptor was held by the kernel epoll object and is now - // being released, so we can create a new `OwnedFd` that assumes - // ownership. - let raw_fd = target.consume().as_raw_fd(); - unsafe { T::from_fd(io_lifetimes::OwnedFd::from_raw_fd(raw_fd)) } - } -} - -/// An "epoll", an interface to an OS object allowing one to repeatedly wait -/// for events from a set of file descriptors efficiently. -pub struct Epoll { - epoll_fd: OwnedFd, - context: Context, -} - -impl Epoll { - /// `epoll_create1(flags)`—Creates a new `Epoll`. - /// - /// 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 new(flags: CreateFlags, context: Context) -> io::Result { - // Safety: We're calling `epoll_create1` via FFI and we know how it - // behaves. - unsafe { - Ok(Self { - epoll_fd: ret_owned_fd(c::epoll_create1(flags.bits()))?, - context, - }) - } - } - - /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an - /// `Epoll`. - /// - /// This registers interest in any of the events set in `events` occurring - /// on the file descriptor associated with `data`. - #[doc(alias = "epoll_ctl")] - pub fn add( - &self, - data: Context::Data, - event_flags: EventFlags, - ) -> io::Result> { - // Safety: We're calling `epoll_ctl` via FFI and we know how it - // behaves. - unsafe { - let target = self.context.acquire(data); - let raw_fd = target.as_fd().as_raw_fd(); - let encoded = self.context.encode(target); - ret(c::epoll_ctl( - self.epoll_fd.as_fd().as_raw_fd(), - c::EPOLL_CTL_ADD, - raw_fd, - &mut c::epoll_event { - events: event_flags.bits(), - r#u64: encoded, - }, - ))?; - Ok(self.context.decode(encoded)) - } - } - - /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in - /// this `Epoll`. - /// - /// This sets the events of interest with `target` to `events`. - #[doc(alias = "epoll_ctl")] - pub fn mod_( - &self, - target: Ref<'_, Context::Target>, - event_flags: EventFlags, - ) -> io::Result<()> { - let raw_fd = target.as_fd().as_raw_fd(); - let encoded = self.context.encode(target); - // Safety: We're calling `epoll_ctl` via FFI and we know how it - // behaves. - unsafe { - ret(c::epoll_ctl( - self.epoll_fd.as_fd().as_raw_fd(), - c::EPOLL_CTL_MOD, - raw_fd, - &mut c::epoll_event { - events: event_flags.bits(), - r#u64: encoded, - }, - )) - } - } - - /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in - /// this `Epoll`. - /// - /// This also returns the owning `Data`. - #[doc(alias = "epoll_ctl")] - pub fn del(&self, target: Ref<'_, Context::Target>) -> io::Result { - // Safety: We're calling `epoll_ctl` via FFI and we know how it - // behaves. - unsafe { - let raw_fd = target.as_fd().as_raw_fd(); - ret(c::epoll_ctl( - self.epoll_fd.as_fd().as_raw_fd(), - c::EPOLL_CTL_DEL, - raw_fd, - null_mut(), - ))?; - } - Ok(self.context.release(target)) - } - - /// `epoll_wait(self, events, timeout)`—Waits for registered events of - /// interest. - /// - /// For each event of interest, an element is written to `events`. On - /// success, this returns the number of written elements. - #[doc(alias = "epoll_wait")] - pub fn wait<'context>( - &'context self, - event_list: &mut EventVec<'context, Context>, - timeout: c::c_int, - ) -> io::Result<()> { - // Safety: We're calling `epoll_wait` via FFI and we know how it - // behaves. - unsafe { - event_list.events.set_len(0); - let nfds = ret_u32(c::epoll_wait( - self.epoll_fd.as_fd().as_raw_fd(), - event_list.events.as_mut_ptr().cast::(), - event_list.events.capacity().try_into().unwrap_or(i32::MAX), - timeout, - ))?; - event_list.events.set_len(nfds as usize); - event_list.context = &self.context; - } - - Ok(()) - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> AsRawFd for Epoll> { - fn as_raw_fd(&self) -> RawFd { - self.epoll_fd.as_raw_fd() - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> IntoRawFd for Epoll> { - fn into_raw_fd(self) -> RawFd { - self.epoll_fd.into_raw_fd() - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> FromRawFd for Epoll> { - unsafe fn from_raw_fd(fd: RawFd) -> Self { - Self { - epoll_fd: OwnedFd::from_raw_fd(fd), - context: Owning::new(), - } - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> AsFd for Epoll> { - fn as_fd(&self) -> BorrowedFd<'_> { - self.epoll_fd.as_fd() - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> From>> for OwnedFd { - fn from(epoll: Epoll>) -> Self { - epoll.epoll_fd - } -} - -#[cfg(not(feature = "rustc-dep-of-std"))] -impl<'context, T: AsFd + IntoFd + FromFd> From for Epoll> { - fn from(fd: OwnedFd) -> Self { - Self { - epoll_fd: fd, - context: Owning::new(), - } - } -} - -/// An iterator over the `Event`s in an `EventVec`. -pub struct Iter<'context, Context: self::Context> { - iter: core::slice::Iter<'context, Event>, - context: *const Context, - _phantom: PhantomData<&'context Context>, -} - -impl<'context, Context: self::Context> Iterator for Iter<'context, Context> { - type Item = (EventFlags, Ref<'context, Context::Target>); - - fn next(&mut self) -> Option { - // Safety: `self.context` is guaranteed to be valid because we hold - // `'context` for it. And we know this event is associated with this - // context because `wait` sets both. - self.iter.next().map(|event| { - (event.event_flags, unsafe { - (*self.context).decode(event.encoded) - }) - }) - } -} - -/// A record of an event that occurred. -#[repr(C)] -#[cfg_attr( - any( - all( - target_arch = "x86", - not(target_env = "musl"), - not(target_os = "android"), - ), - target_arch = "x86_64", - ), - repr(packed) -)] -struct Event { - // Match the layout of `c::epoll_event`. We just use a `u64` instead of - // the full union; `Context` implementations will simply need to deal with - // casting the value into and out of the `u64` themselves. - event_flags: EventFlags, - encoded: u64, -} - -/// A vector of `Event`s, plus context for interpreting them. -pub struct EventVec<'context, Context: self::Context> { - events: Vec, - context: *const Context, - _phantom: PhantomData<&'context Context>, -} - -impl<'context, Context: self::Context> EventVec<'context, Context> { - /// Constructs an `EventVec` with memory for `capacity` `Event`s. - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - Self { - events: Vec::with_capacity(capacity), - context: null(), - _phantom: PhantomData, - } - } - - /// Returns the current `Event` capacity of this `EventVec`. - #[inline] - pub fn capacity(&self) -> usize { - self.events.capacity() - } - - /// Reserves enough memory for at least `additional` more `Event`s. - #[inline] - pub fn reserve(&mut self, additional: usize) { - self.events.reserve(additional); - } - - /// Reserves enough memory for exactly `additional` more `Event`s. - #[inline] - pub fn reserve_exact(&mut self, additional: usize) { - self.events.reserve_exact(additional); - } - - /// Clears all the `Events` out of this `EventVec`. - #[inline] - pub fn clear(&mut self) { - self.events.clear(); - } - - /// Shrinks the capacity of this `EventVec` as much as possible. - #[inline] - pub fn shrink_to_fit(&mut self) { - self.events.shrink_to_fit(); - } - - /// Returns an iterator over the `Event`s in this `EventVec`. - #[inline] - pub fn iter(&self) -> Iter<'_, Context> { - Iter { - iter: self.events.iter(), - context: self.context, - _phantom: PhantomData, - } - } - - /// Returns the number of `Event`s logically contained in this `EventVec`. - #[inline] - pub fn len(&mut self) -> usize { - self.events.len() - } - - /// Tests whether this `EventVec` is logically empty. - #[inline] - pub fn is_empty(&mut self) -> bool { - self.events.is_empty() - } -} - -impl<'context, Context: self::Context> IntoIterator for &'context EventVec<'context, Context> { - type IntoIter = Iter<'context, Context>; - type Item = (EventFlags, Ref<'context, Context::Target>); - - #[inline] - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} diff --git a/vendor/rustix/src/imp/libc/io/errno.rs b/vendor/rustix/src/imp/libc/io/errno.rs deleted file mode 100644 index 470cf205c..000000000 --- a/vendor/rustix/src/imp/libc/io/errno.rs +++ /dev/null @@ -1,997 +0,0 @@ -//! The `rustix` `Errno` type. -//! -//! This type holds an OS error code, which conceptually corresponds to an -//! `errno` value. - -use super::super::c; -use libc_errno::errno; - -/// The error type for `rustix` APIs. -/// -/// This is similar to `std::io::Error`, but only holds an OS error code, -/// and no extra error value. -#[repr(transparent)] -#[doc(alias = "errno")] -#[derive(Eq, PartialEq, Hash, Copy, Clone)] -pub struct Errno(pub(crate) c::c_int); - -impl Errno { - /// `EACCES` - #[doc(alias = "ACCES")] - pub const ACCESS: Self = Self(c::EACCES); - /// `EADDRINUSE` - pub const ADDRINUSE: Self = Self(c::EADDRINUSE); - /// `EADDRNOTAVAIL` - pub const ADDRNOTAVAIL: Self = Self(c::EADDRNOTAVAIL); - /// `EADV` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const ADV: Self = Self(c::EADV); - /// `EAFNOSUPPORT` - pub const AFNOSUPPORT: Self = Self(c::EAFNOSUPPORT); - /// `EAGAIN` - pub const AGAIN: Self = Self(c::EAGAIN); - /// `EALREADY` - pub const ALREADY: Self = Self(c::EALREADY); - /// `EAUTH` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const AUTH: Self = Self(c::EAUTH); - /// `EBADE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const BADE: Self = Self(c::EBADE); - /// `EBADF` - pub const BADF: Self = Self(c::EBADF); - /// `EBADFD` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const BADFD: Self = Self(c::EBADFD); - /// `EBADMSG` - #[cfg(not(windows))] - pub const BADMSG: Self = Self(c::EBADMSG); - /// `EBADR` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const BADR: Self = Self(c::EBADR); - /// `EBADRPC` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const BADRPC: Self = Self(c::EBADRPC); - /// `EBADRQC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const BADRQC: Self = Self(c::EBADRQC); - /// `EBADSLT` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const BADSLT: Self = Self(c::EBADSLT); - /// `EBFONT` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const BFONT: Self = Self(c::EBFONT); - /// `EBUSY` - #[cfg(not(windows))] - pub const BUSY: Self = Self(c::EBUSY); - /// `ECANCELED` - pub const CANCELED: Self = Self(c::ECANCELED); - /// `ECAPMODE` - #[cfg(any(target_os = "freebsd"))] - pub const CAPMODE: Self = Self(c::ECAPMODE); - /// `ECHILD` - #[cfg(not(windows))] - pub const CHILD: Self = Self(c::ECHILD); - /// `ECHRNG` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const CHRNG: Self = Self(c::ECHRNG); - /// `ECOMM` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const COMM: Self = Self(c::ECOMM); - /// `ECONNABORTED` - pub const CONNABORTED: Self = Self(c::ECONNABORTED); - /// `ECONNREFUSED` - pub const CONNREFUSED: Self = Self(c::ECONNREFUSED); - /// `ECONNRESET` - pub const CONNRESET: Self = Self(c::ECONNRESET); - /// `EDEADLK` - #[cfg(not(windows))] - pub const DEADLK: Self = Self(c::EDEADLK); - /// `EDEADLOCK` - #[cfg(not(any( - windows, - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const DEADLOCK: Self = Self(c::EDEADLOCK); - /// `EDESTADDRREQ` - pub const DESTADDRREQ: Self = Self(c::EDESTADDRREQ); - /// `EDISCON` - #[cfg(windows)] - pub const DISCON: Self = Self(c::EDISCON); - /// `EDOM` - #[cfg(not(windows))] - pub const DOM: Self = Self(c::EDOM); - /// `EDOOFUS` - #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] - pub const DOOFUS: Self = Self(c::EDOOFUS); - /// `EDOTDOT` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const DOTDOT: Self = Self(c::EDOTDOT); - /// `EDQUOT` - pub const DQUOT: Self = Self(c::EDQUOT); - /// `EEXIST` - #[cfg(not(windows))] - pub const EXIST: Self = Self(c::EEXIST); - /// `EFAULT` - pub const FAULT: Self = Self(c::EFAULT); - /// `EFBIG` - #[cfg(not(windows))] - pub const FBIG: Self = Self(c::EFBIG); - /// `EFTYPE` - #[cfg(any( - target_env = "newlib", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const FTYPE: Self = Self(c::EFTYPE); - /// `EHOSTDOWN` - #[cfg(not(target_os = "wasi"))] - pub const HOSTDOWN: Self = Self(c::EHOSTDOWN); - /// `EHOSTUNREACH` - pub const HOSTUNREACH: Self = Self(c::EHOSTUNREACH); - /// `EHWPOISON` - #[cfg(not(any( - windows, - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", - )))] - pub const HWPOISON: Self = Self(c::EHWPOISON); - /// `EIDRM` - #[cfg(not(windows))] - pub const IDRM: Self = Self(c::EIDRM); - /// `EILSEQ` - #[cfg(not(windows))] - pub const ILSEQ: Self = Self(c::EILSEQ); - /// `EINPROGRESS` - pub const INPROGRESS: Self = Self(c::EINPROGRESS); - /// `EINTR` - /// - /// For a convenient way to retry system calls that exit with `INTR`, use - /// [`retry_on_intr`]. - /// - /// [`retry_on_intr`]: crate::io::retry_on_intr - pub const INTR: Self = Self(c::EINTR); - /// `EINVAL` - pub const INVAL: Self = Self(c::EINVAL); - /// `EINVALIDPROCTABLE` - #[cfg(windows)] - pub const INVALIDPROCTABLE: Self = Self(c::EINVALIDPROCTABLE); - /// `EINVALIDPROVIDER` - #[cfg(windows)] - pub const INVALIDPROVIDER: Self = Self(c::EINVALIDPROVIDER); - /// `EIO` - #[cfg(not(windows))] - pub const IO: Self = Self(c::EIO); - /// `EISCONN` - pub const ISCONN: Self = Self(c::EISCONN); - /// `EISDIR` - #[cfg(not(windows))] - pub const ISDIR: Self = Self(c::EISDIR); - /// `EISNAM` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const ISNAM: Self = Self(c::EISNAM); - /// `EKEYEXPIRED` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const KEYEXPIRED: Self = Self(c::EKEYEXPIRED); - /// `EKEYREJECTED` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const KEYREJECTED: Self = Self(c::EKEYREJECTED); - /// `EKEYREVOKED` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const KEYREVOKED: Self = Self(c::EKEYREVOKED); - /// `EL2HLT` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const L2HLT: Self = Self(c::EL2HLT); - /// `EL2NSYNC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const L2NSYNC: Self = Self(c::EL2NSYNC); - /// `EL3HLT` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const L3HLT: Self = Self(c::EL3HLT); - /// `EL3RST` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const L3RST: Self = Self(c::EL3RST); - /// `ELIBACC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const LIBACC: Self = Self(c::ELIBACC); - /// `ELIBBAD` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const LIBBAD: Self = Self(c::ELIBBAD); - /// `ELIBEXEC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const LIBEXEC: Self = Self(c::ELIBEXEC); - /// `ELIBMAX` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const LIBMAX: Self = Self(c::ELIBMAX); - /// `ELIBSCN` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const LIBSCN: Self = Self(c::ELIBSCN); - /// `ELNRNG` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const LNRNG: Self = Self(c::ELNRNG); - /// `ELOOP` - pub const LOOP: Self = Self(c::ELOOP); - /// `EMEDIUMTYPE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const MEDIUMTYPE: Self = Self(c::EMEDIUMTYPE); - /// `EMFILE` - pub const MFILE: Self = Self(c::EMFILE); - /// `EMLINK` - #[cfg(not(windows))] - pub const MLINK: Self = Self(c::EMLINK); - /// `EMSGSIZE` - pub const MSGSIZE: Self = Self(c::EMSGSIZE); - /// `EMULTIHOP` - #[cfg(not(any(windows, target_os = "openbsd")))] - pub const MULTIHOP: Self = Self(c::EMULTIHOP); - /// `ENAMETOOLONG` - pub const NAMETOOLONG: Self = Self(c::ENAMETOOLONG); - /// `ENAVAIL` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NAVAIL: Self = Self(c::ENAVAIL); - /// `ENEEDAUTH` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const NEEDAUTH: Self = Self(c::ENEEDAUTH); - /// `ENETDOWN` - pub const NETDOWN: Self = Self(c::ENETDOWN); - /// `ENETRESET` - pub const NETRESET: Self = Self(c::ENETRESET); - /// `ENETUNREACH` - pub const NETUNREACH: Self = Self(c::ENETUNREACH); - /// `ENFILE` - #[cfg(not(windows))] - pub const NFILE: Self = Self(c::ENFILE); - /// `ENOANO` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOANO: Self = Self(c::ENOANO); - /// `ENOATTR` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const NOATTR: Self = Self(c::ENOATTR); - /// `ENOBUFS` - pub const NOBUFS: Self = Self(c::ENOBUFS); - /// `ENOCSI` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOCSI: Self = Self(c::ENOCSI); - /// `ENODATA` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NODATA: Self = Self(c::ENODATA); - /// `ENODEV` - #[cfg(not(windows))] - pub const NODEV: Self = Self(c::ENODEV); - /// `ENOENT` - #[cfg(not(windows))] - pub const NOENT: Self = Self(c::ENOENT); - /// `ENOEXEC` - #[cfg(not(windows))] - pub const NOEXEC: Self = Self(c::ENOEXEC); - /// `ENOKEY` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOKEY: Self = Self(c::ENOKEY); - /// `ENOLCK` - #[cfg(not(windows))] - pub const NOLCK: Self = Self(c::ENOLCK); - /// `ENOLINK` - #[cfg(not(any(windows, target_os = "openbsd")))] - pub const NOLINK: Self = Self(c::ENOLINK); - /// `ENOMEDIUM` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOMEDIUM: Self = Self(c::ENOMEDIUM); - /// `ENOMEM` - #[cfg(not(windows))] - pub const NOMEM: Self = Self(c::ENOMEM); - /// `ENOMORE` - #[cfg(windows)] - pub const NOMORE: Self = Self(c::ENOMORE); - /// `ENOMSG` - #[cfg(not(windows))] - pub const NOMSG: Self = Self(c::ENOMSG); - /// `ENONET` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NONET: Self = Self(c::ENONET); - /// `ENOPKG` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOPKG: Self = Self(c::ENOPKG); - /// `ENOPROTOOPT` - pub const NOPROTOOPT: Self = Self(c::ENOPROTOOPT); - /// `ENOSPC` - #[cfg(not(windows))] - pub const NOSPC: Self = Self(c::ENOSPC); - /// `ENOSR` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOSR: Self = Self(c::ENOSR); - /// `ENOSTR` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOSTR: Self = Self(c::ENOSTR); - /// `ENOSYS` - #[cfg(not(windows))] - pub const NOSYS: Self = Self(c::ENOSYS); - /// `ENOTBLK` - #[cfg(not(any(windows, target_os = "wasi")))] - pub const NOTBLK: Self = Self(c::ENOTBLK); - /// `ENOTCAPABLE` - #[cfg(any(target_os = "freebsd", target_os = "wasi"))] - pub const NOTCAPABLE: Self = Self(c::ENOTCAPABLE); - /// `ENOTCONN` - pub const NOTCONN: Self = Self(c::ENOTCONN); - /// `ENOTDIR` - #[cfg(not(windows))] - pub const NOTDIR: Self = Self(c::ENOTDIR); - /// `ENOTEMPTY` - pub const NOTEMPTY: Self = Self(c::ENOTEMPTY); - /// `ENOTNAM` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOTNAM: Self = Self(c::ENOTNAM); - /// `ENOTRECOVERABLE` - #[cfg(not(any(windows, target_os = "dragonfly", target_os = "netbsd")))] - pub const NOTRECOVERABLE: Self = Self(c::ENOTRECOVERABLE); - /// `ENOTSOCK` - pub const NOTSOCK: Self = Self(c::ENOTSOCK); - /// `ENOTSUP` - #[cfg(not(any(windows, target_os = "redox")))] - pub const NOTSUP: Self = Self(c::ENOTSUP); - /// `ENOTTY` - #[cfg(not(windows))] - pub const NOTTY: Self = Self(c::ENOTTY); - /// `ENOTUNIQ` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const NOTUNIQ: Self = Self(c::ENOTUNIQ); - /// `ENXIO` - #[cfg(not(windows))] - pub const NXIO: Self = Self(c::ENXIO); - /// `EOPNOTSUPP` - pub const OPNOTSUPP: Self = Self(c::EOPNOTSUPP); - /// `EOVERFLOW` - #[cfg(not(windows))] - pub const OVERFLOW: Self = Self(c::EOVERFLOW); - /// `EOWNERDEAD` - #[cfg(not(any(windows, target_os = "dragonfly", target_os = "netbsd")))] - pub const OWNERDEAD: Self = Self(c::EOWNERDEAD); - /// `EPERM` - #[cfg(not(windows))] - pub const PERM: Self = Self(c::EPERM); - /// `EPFNOSUPPORT` - #[cfg(not(target_os = "wasi"))] - pub const PFNOSUPPORT: Self = Self(c::EPFNOSUPPORT); - /// `EPIPE` - #[cfg(not(windows))] - pub const PIPE: Self = Self(c::EPIPE); - /// `EPROCLIM` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const PROCLIM: Self = Self(c::EPROCLIM); - /// `EPROCUNAVAIL` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const PROCUNAVAIL: Self = Self(c::EPROCUNAVAIL); - /// `EPROGMISMATCH` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const PROGMISMATCH: Self = Self(c::EPROGMISMATCH); - /// `EPROGUNAVAIL` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const PROGUNAVAIL: Self = Self(c::EPROGUNAVAIL); - /// `EPROTO` - #[cfg(not(windows))] - pub const PROTO: Self = Self(c::EPROTO); - /// `EPROTONOSUPPORT` - pub const PROTONOSUPPORT: Self = Self(c::EPROTONOSUPPORT); - /// `EPROTOTYPE` - pub const PROTOTYPE: Self = Self(c::EPROTOTYPE); - /// `EPROVIDERFAILEDINIT` - #[cfg(windows)] - pub const PROVIDERFAILEDINIT: Self = Self(c::EPROVIDERFAILEDINIT); - /// `ERANGE` - #[cfg(not(windows))] - pub const RANGE: Self = Self(c::ERANGE); - /// `EREFUSED` - #[cfg(windows)] - pub const REFUSED: Self = Self(c::EREFUSED); - /// `EREMCHG` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const REMCHG: Self = Self(c::EREMCHG); - /// `EREMOTE` - #[cfg(not(target_os = "wasi"))] - pub const REMOTE: Self = Self(c::EREMOTE); - /// `EREMOTEIO` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const REMOTEIO: Self = Self(c::EREMOTEIO); - /// `ERESTART` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const RESTART: Self = Self(c::ERESTART); - /// `ERFKILL` - #[cfg(not(any( - windows, - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", - )))] - pub const RFKILL: Self = Self(c::ERFKILL); - /// `EROFS` - #[cfg(not(windows))] - pub const ROFS: Self = Self(c::EROFS); - /// `ERPCMISMATCH` - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - pub const RPCMISMATCH: Self = Self(c::ERPCMISMATCH); - /// `ESHUTDOWN` - #[cfg(not(target_os = "wasi"))] - pub const SHUTDOWN: Self = Self(c::ESHUTDOWN); - /// `ESOCKTNOSUPPORT` - #[cfg(not(target_os = "wasi"))] - pub const SOCKTNOSUPPORT: Self = Self(c::ESOCKTNOSUPPORT); - /// `ESPIPE` - #[cfg(not(windows))] - pub const SPIPE: Self = Self(c::ESPIPE); - /// `ESRCH` - #[cfg(not(windows))] - pub const SRCH: Self = Self(c::ESRCH); - /// `ESRMNT` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const SRMNT: Self = Self(c::ESRMNT); - /// `ESTALE` - pub const STALE: Self = Self(c::ESTALE); - /// `ESTRPIPE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const STRPIPE: Self = Self(c::ESTRPIPE); - /// `ETIME` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const TIME: Self = Self(c::ETIME); - /// `ETIMEDOUT` - pub const TIMEDOUT: Self = Self(c::ETIMEDOUT); - /// `E2BIG` - #[cfg(not(windows))] - #[doc(alias = "2BIG")] - pub const TOOBIG: Self = Self(c::E2BIG); - /// `ETOOMANYREFS` - #[cfg(not(target_os = "wasi"))] - pub const TOOMANYREFS: Self = Self(c::ETOOMANYREFS); - /// `ETXTBSY` - #[cfg(not(windows))] - pub const TXTBSY: Self = Self(c::ETXTBSY); - /// `EUCLEAN` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const UCLEAN: Self = Self(c::EUCLEAN); - /// `EUNATCH` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const UNATCH: Self = Self(c::EUNATCH); - /// `EUSERS` - #[cfg(not(target_os = "wasi"))] - pub const USERS: Self = Self(c::EUSERS); - /// `EWOULDBLOCK` - pub const WOULDBLOCK: Self = Self(c::EWOULDBLOCK); - /// `EXDEV` - #[cfg(not(windows))] - pub const XDEV: Self = Self(c::EXDEV); - /// `EXFULL` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "wasi", - )))] - pub const XFULL: Self = Self(c::EXFULL); -} - -impl Errno { - /// Extract an `Errno` value from a `std::io::Error`. - /// - /// This isn't a `From` conversion because it's expected to be relatively - /// uncommon. - #[cfg(feature = "std")] - #[inline] - pub fn from_io_error(io_err: &std::io::Error) -> Option { - io_err - .raw_os_error() - .and_then(|raw| if raw != 0 { Some(Self(raw)) } else { None }) - } - - /// Extract the raw OS error number from this error. - #[inline] - pub const fn raw_os_error(self) -> i32 { - self.0 - } - - /// Construct an `Errno` from a raw OS error number. - #[inline] - pub const fn from_raw_os_error(raw: i32) -> Self { - Self(raw) - } - - pub(crate) fn last_os_error() -> Self { - Self(errno().0) - } -} diff --git a/vendor/rustix/src/imp/libc/io/io_slice.rs b/vendor/rustix/src/imp/libc/io/io_slice.rs deleted file mode 100644 index 81c504d25..000000000 --- a/vendor/rustix/src/imp/libc/io/io_slice.rs +++ /dev/null @@ -1,85 +0,0 @@ -//! The following is derived from Rust's -//! library/std/src/sys/unix/io.rs -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. - -use super::super::c; -use core::marker::PhantomData; -use core::slice; - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: c::iovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - #[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(), - }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.iov_len -= n; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } -} - -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: c::iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - #[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(), - }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if self.vec.iov_len < n { - panic!("advancing IoSliceMut beyond its length"); - } - - unsafe { - self.vec.iov_len -= n; - self.vec.iov_base = self.vec.iov_base.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } - } - - #[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) } - } -} diff --git a/vendor/rustix/src/imp/libc/io/mod.rs b/vendor/rustix/src/imp/libc/io/mod.rs deleted file mode 100644 index 1378adf3d..000000000 --- a/vendor/rustix/src/imp/libc/io/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub(crate) mod errno; -#[cfg(not(windows))] -#[cfg(not(feature = "std"))] -pub(crate) mod io_slice; -pub(crate) mod poll_fd; -#[cfg(not(windows))] -pub(crate) mod types; - -#[cfg_attr(windows, path = "windows_syscalls.rs")] -pub(crate) mod syscalls; - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub mod epoll; diff --git a/vendor/rustix/src/imp/libc/io/poll_fd.rs b/vendor/rustix/src/imp/libc/io/poll_fd.rs deleted file mode 100644 index c516a9309..000000000 --- a/vendor/rustix/src/imp/libc/io/poll_fd.rs +++ /dev/null @@ -1,136 +0,0 @@ -use super::super::c; -use super::super::conv::borrowed_fd; -#[cfg(windows)] -use super::super::fd::RawFd; -use super::super::fd::{AsFd, AsRawFd, BorrowedFd, LibcFd}; -use bitflags::bitflags; -use core::marker::PhantomData; -#[cfg(windows)] -use std::fmt; - -bitflags! { - /// `POLL*` flags for use with [`poll`]. - /// - /// [`poll`]: crate::io::poll - pub struct PollFlags: c::c_short { - /// `POLLIN` - const IN = c::POLLIN; - /// `POLLPRI` - #[cfg(not(target_os = "wasi"))] - const PRI = c::POLLPRI; - /// `POLLOUT` - const OUT = c::POLLOUT; - /// `POLLRDNORM` - #[cfg(not(target_os = "redox"))] - const RDNORM = c::POLLRDNORM; - /// `POLLWRNORM` - #[cfg(not(target_os = "redox"))] - const WRNORM = c::POLLWRNORM; - /// `POLLRDBAND` - #[cfg(not(any(target_os = "redox", target_os = "wasi")))] - const RDBAND = c::POLLRDBAND; - /// `POLLWRBAND` - #[cfg(not(any(target_os = "redox", target_os = "wasi")))] - const WRBAND = c::POLLWRBAND; - /// `POLLERR` - const ERR = c::POLLERR; - /// `POLLHUP` - const HUP = c::POLLHUP; - /// `POLLNVAL` - const NVAL = c::POLLNVAL; - /// `POLLRDHUP` - #[cfg(all( - any(target_os = "android", target_os = "linux"), - not(any(target_arch = "sparc", target_arch = "sparc64"))), - )] - const RDHUP = c::POLLRDHUP; - } -} - -/// `struct pollfd`—File descriptor and flags for use with [`poll`]. -/// -/// [`poll`]: crate::io::poll -#[doc(alias = "pollfd")] -#[derive(Clone)] -#[cfg_attr(not(windows), derive(Debug))] -#[repr(transparent)] -pub struct PollFd<'fd> { - pollfd: c::pollfd, - _phantom: PhantomData>, -} - -#[cfg(windows)] -impl<'fd> fmt::Debug for PollFd<'fd> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("pollfd") - .field("fd", &self.pollfd.fd) - .field("events", &self.pollfd.events) - .field("revents", &self.pollfd.revents) - .finish() - } -} - -impl<'fd> PollFd<'fd> { - /// Constructs a new `PollFd` holding `fd` and `events`. - #[inline] - pub fn new(fd: &'fd Fd, events: PollFlags) -> Self { - Self::from_borrowed_fd(fd.as_fd(), events) - } - - /// Sets the contained file descriptor to `fd`. - #[inline] - pub fn set_fd(&mut self, fd: &'fd Fd) { - self.pollfd.fd = fd.as_fd().as_raw_fd() as LibcFd; - } - - /// Clears the ready events. - #[inline] - pub fn clear_revents(&mut self) { - self.pollfd.revents = 0; - } - - /// Constructs a new `PollFd` holding `fd` and `events`. - /// - /// This is the same as `new`, but can be used to avoid borrowing the - /// `BorrowedFd`, which can be tricky in situations where the `BorrowedFd` - /// is a temporary. - #[inline] - pub fn from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self { - Self { - pollfd: c::pollfd { - fd: borrowed_fd(fd), - events: events.bits(), - revents: 0, - }, - _phantom: PhantomData, - } - } - - /// Returns the ready events. - #[inline] - pub fn revents(&self) -> PollFlags { - // Use `unwrap()` here because in theory we know we know all the bits - // the OS might set here, but OS's have added extensions in the past. - PollFlags::from_bits(self.pollfd.revents).unwrap() - } -} - -#[cfg(not(windows))] -impl<'fd> AsFd for PollFd<'fd> { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - // Safety: Our constructors and `set_fd` require `pollfd.fd` to be - // valid for the `fd lifetime. - unsafe { BorrowedFd::borrow_raw(self.pollfd.fd) } - } -} - -#[cfg(windows)] -impl<'fd> io_lifetimes::AsSocket for PollFd<'fd> { - #[inline] - fn as_socket(&self) -> BorrowedFd<'_> { - // Safety: Our constructors and `set_fd` require `pollfd.fd` to be - // valid for the `fd lifetime. - unsafe { BorrowedFd::borrow_raw(self.pollfd.fd as RawFd) } - } -} diff --git a/vendor/rustix/src/imp/libc/io/syscalls.rs b/vendor/rustix/src/imp/libc/io/syscalls.rs deleted file mode 100644 index 4fafbfd66..000000000 --- a/vendor/rustix/src/imp/libc/io/syscalls.rs +++ /dev/null @@ -1,456 +0,0 @@ -//! libc syscalls supporting `rustix::io`. - -use super::super::c; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::syscall_ret_owned_fd; -use super::super::conv::{ - borrowed_fd, ret, ret_c_int, ret_discarded_fd, ret_owned_fd, ret_ssize_t, -}; -use super::super::offset::{libc_pread, libc_pwrite}; -#[cfg(not(target_os = "redox"))] -use super::super::offset::{libc_preadv, libc_pwritev}; -#[cfg(all(target_os = "linux", target_env = "gnu"))] -use super::super::offset::{libc_preadv2, libc_pwritev2}; -use crate::fd::{AsFd, BorrowedFd, RawFd}; -#[cfg(not(target_os = "wasi"))] -use crate::io::DupFlags; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))] -use crate::io::PipeFlags; -use crate::io::{self, IoSlice, IoSliceMut, OwnedFd, PollFd}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::io::{EventfdFlags, ReadWriteFlags}; -use core::cmp::min; -use core::convert::TryInto; -use core::mem::MaybeUninit; -#[cfg(feature = "net")] -use libc_errno::errno; - -pub(crate) fn read(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { - let nread = unsafe { - ret_ssize_t(c::read( - borrowed_fd(fd), - buf.as_mut_ptr().cast(), - min(buf.len(), READ_LIMIT), - ))? - }; - Ok(nread as usize) -} - -pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result { - let nwritten = unsafe { - ret_ssize_t(c::write( - borrowed_fd(fd), - buf.as_ptr().cast(), - min(buf.len(), READ_LIMIT), - ))? - }; - Ok(nwritten as usize) -} - -pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], offset: u64) -> io::Result { - let len = min(buf.len(), READ_LIMIT); - - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - - let nread = unsafe { - ret_ssize_t(libc_pread( - borrowed_fd(fd), - buf.as_mut_ptr().cast(), - len, - offset, - ))? - }; - Ok(nread as usize) -} - -pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result { - let len = min(buf.len(), READ_LIMIT); - - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - - let nwritten = unsafe { - ret_ssize_t(libc_pwrite( - borrowed_fd(fd), - buf.as_ptr().cast(), - len, - offset, - ))? - }; - Ok(nwritten as usize) -} - -pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut]) -> io::Result { - let nread = unsafe { - ret_ssize_t(c::readv( - borrowed_fd(fd), - bufs.as_ptr().cast::(), - min(bufs.len(), max_iov()) as c::c_int, - ))? - }; - Ok(nread as usize) -} - -pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice]) -> io::Result { - let nwritten = unsafe { - ret_ssize_t(c::writev( - borrowed_fd(fd), - bufs.as_ptr().cast::(), - min(bufs.len(), max_iov()) as c::c_int, - ))? - }; - Ok(nwritten as usize) -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn preadv( - fd: BorrowedFd<'_>, - bufs: &mut [IoSliceMut], - offset: u64, -) -> io::Result { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - let nread = unsafe { - ret_ssize_t(libc_preadv( - borrowed_fd(fd), - bufs.as_ptr().cast::(), - min(bufs.len(), max_iov()) as c::c_int, - offset, - ))? - }; - Ok(nread as usize) -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn pwritev(fd: BorrowedFd<'_>, bufs: &[IoSlice], offset: u64) -> io::Result { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - let nwritten = unsafe { - ret_ssize_t(libc_pwritev( - borrowed_fd(fd), - bufs.as_ptr().cast::(), - min(bufs.len(), max_iov()) as c::c_int, - offset, - ))? - }; - Ok(nwritten as usize) -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(crate) fn preadv2( - fd: BorrowedFd<'_>, - bufs: &mut [IoSliceMut], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - let nread = unsafe { - ret_ssize_t(libc_preadv2( - borrowed_fd(fd), - bufs.as_ptr().cast::(), - min(bufs.len(), max_iov()) as c::c_int, - offset, - flags.bits(), - ))? - }; - Ok(nread as usize) -} - -/// At present, `libc` only has `preadv2` defined for glibc. On other -/// ABIs, `ReadWriteFlags` has no flags defined, and we use plain `preadv`. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] -pub(crate) fn preadv2( - fd: BorrowedFd<'_>, - bufs: &mut [IoSliceMut], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result { - assert!(flags.is_empty()); - preadv(fd, bufs, offset) -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(crate) fn pwritev2( - fd: BorrowedFd<'_>, - bufs: &[IoSlice], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result { - // Silently cast; we'll get `EINVAL` if the value is negative. - let offset = offset as i64; - let nwritten = unsafe { - ret_ssize_t(libc_pwritev2( - borrowed_fd(fd), - bufs.as_ptr().cast::(), - min(bufs.len(), max_iov()) as c::c_int, - offset, - flags.bits(), - ))? - }; - Ok(nwritten as usize) -} - -/// At present, `libc` only has `pwritev2` defined for glibc. On other -/// ABIs, `ReadWriteFlags` has no flags defined, and we use plain `pwritev`. -#[cfg(any( - target_os = "android", - all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] -pub(crate) fn pwritev2( - fd: BorrowedFd<'_>, - bufs: &[IoSlice], - offset: u64, - flags: ReadWriteFlags, -) -> io::Result { - assert!(flags.is_empty()); - pwritev(fd, bufs, offset) -} - -// These functions are derived from Rust's library/std/src/sys/unix/fd.rs at -// revision a77da2d454e6caa227a85b16410b95f93495e7e0. - -// The maximum read limit on most POSIX-like systems is `SSIZE_MAX`, with the -// man page quoting that if the count of bytes to read is greater than -// `SSIZE_MAX` the result is "unspecified". -// -// On macOS, however, apparently the 64-bit libc is either buggy or -// intentionally showing odd behavior by rejecting any read with a size larger -// than or equal to `INT_MAX`. To handle both of these the read size is capped -// on both platforms. -#[cfg(target_os = "macos")] -const READ_LIMIT: usize = c::c_int::MAX as usize - 1; -#[cfg(not(target_os = "macos"))] -const READ_LIMIT: usize = c::ssize_t::MAX as usize; - -#[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -))] -const fn max_iov() -> usize { - c::IOV_MAX as usize -} - -#[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))] -const fn max_iov() -> usize { - c::UIO_MAXIOV as usize -} - -#[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -const fn max_iov() -> usize { - 16 // The minimum value required by POSIX. -} - -pub(crate) unsafe fn close(raw_fd: RawFd) { - let _ = c::close(raw_fd as c::c_int); -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result { - unsafe { syscall_ret_owned_fd(c::syscall(c::SYS_eventfd2, initval, flags.bits())) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn ioctl_blksszget(fd: BorrowedFd) -> io::Result { - let mut result = MaybeUninit::::uninit(); - unsafe { - ret(c::ioctl(borrowed_fd(fd), c::BLKSSZGET, result.as_mut_ptr()))?; - Ok(result.assume_init() as u32) - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result { - let mut result = MaybeUninit::::uninit(); - unsafe { - ret(c::ioctl( - borrowed_fd(fd), - c::BLKPBSZGET, - result.as_mut_ptr(), - ))?; - Ok(result.assume_init() as u32) - } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result { - let mut nread = MaybeUninit::::uninit(); - unsafe { - ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?; - // `FIONREAD` returns the number of bytes silently casted to a `c_int`, - // even when this is lossy. The best we can do is convert it back to a - // `u64` without sign-extending it back first. - Ok(u64::from(nread.assume_init() as c::c_uint)) - } -} - -pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - unsafe { - let data = value as c::c_int; - ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &data)) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[cfg(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)?; - let mut not_socket = false; - if read { - // Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates - // the read side is shut down; an `EWOULDBLOCK` indicates the read - // side is still open. - match unsafe { - c::recv( - borrowed_fd(fd), - MaybeUninit::<[u8; 1]>::uninit() - .as_mut_ptr() - .cast::(), - 1, - c::MSG_PEEK | c::MSG_DONTWAIT, - ) - } { - 0 => read = false, - -1 => { - #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` - match errno().0 { - c::EAGAIN | c::EWOULDBLOCK => (), - c::ENOTSOCK => not_socket = true, - err => return Err(io::Errno(err)), - } - } - _ => (), - } - } - if write && !not_socket { - // Do a `send` with `DONTWAIT` for 0 bytes. An `EPIPE` indicates - // the write side is shut down. - if unsafe { c::send(borrowed_fd(fd), [].as_ptr(), 0, c::MSG_DONTWAIT) } == -1 { - #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` - match errno().0 { - c::EAGAIN | c::EWOULDBLOCK => (), - c::ENOTSOCK => (), - c::EPIPE => write = false, - err => return Err(io::Errno(err)), - } - } - } - Ok((read, write)) -} - -#[cfg(target_os = "wasi")] -#[cfg(feature = "net")] -pub(crate) fn is_read_write(_fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { - todo!("Implement is_read_write for WASI in terms of fd_fdstat_get"); -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result { - unsafe { ret_owned_fd(c::dup(borrowed_fd(fd))) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { - unsafe { ret_discarded_fd(c::dup2(borrowed_fd(fd), borrowed_fd(new.as_fd()))) } -} - -#[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { - unsafe { - ret_discarded_fd(c::dup3( - borrowed_fd(fd), - borrowed_fd(new.as_fd()), - flags.bits(), - )) - } -} - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "ios", - target_os = "macos", - target_os = "redox", -))] -pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, _flags: DupFlags) -> io::Result<()> { - // Android 5.0 has `dup3`, but libc doesn't have bindings. Emulate it - // using `dup2`. We don't need to worry about the difference between - // `dup2` and `dup3` when the file descriptors are equal because we - // have an `&mut OwnedFd` which means `fd` doesn't alias it. - dup2(fd, new) -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(crate) fn ioctl_fioclex(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::FIOCLEX)) } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn ioctl_tiocexcl(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCEXCL as _)) } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn ioctl_tiocnxcl(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCNXCL as _)) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(c::pipe(result.as_mut_ptr().cast::()))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))] -pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(c::pipe2(result.as_mut_ptr().cast::(), flags.bits()))?; - let [p0, p1] = result.assume_init(); - Ok((p0, p1)) - } -} - -#[inline] -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result { - let nfds = fds - .len() - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - - ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) - .map(|nready| nready as usize) -} diff --git a/vendor/rustix/src/imp/libc/io/types.rs b/vendor/rustix/src/imp/libc/io/types.rs deleted file mode 100644 index 483f3a6af..000000000 --- a/vendor/rustix/src/imp/libc/io/types.rs +++ /dev/null @@ -1,89 +0,0 @@ -use super::super::c; -#[cfg(not(target_os = "wasi"))] -use bitflags::bitflags; - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`]. - /// - /// [`preadv2`]: crate::io::preadv2 - /// [`pwritev2`]: crate::io::pwritev - pub struct ReadWriteFlags: c::c_int { - /// `RWF_DSYNC` (since Linux 4.7) - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const DSYNC = c::RWF_DSYNC; - /// `RWF_HIPRI` (since Linux 4.6) - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const HIPRI = c::RWF_HIPRI; - /// `RWF_SYNC` (since Linux 4.7) - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const SYNC = c::RWF_SYNC; - /// `RWF_NOWAIT` (since Linux 4.14) - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const NOWAIT = c::RWF_NOWAIT; - /// `RWF_APPEND` (since Linux 4.16) - #[cfg(all(target_os = "linux", target_env = "gnu"))] - const APPEND = c::RWF_APPEND; - } -} - -#[cfg(not(target_os = "wasi"))] -bitflags! { - /// `O_*` constants for use with [`dup2`]. - /// - /// [`dup2`]: crate::io::dup2 - pub struct DupFlags: c::c_int { - /// `O_CLOEXEC` - #[cfg(not(any( - target_os = "android", - target_os = "ios", - target_os = "macos", - target_os = "redox", - )))] // Android 5.0 has dup3, but libc doesn't have bindings - const CLOEXEC = c::O_CLOEXEC; - } -} - -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))] -bitflags! { - /// `O_*` constants for use with [`pipe_with`]. - /// - /// [`pipe_with`]: crate::io::pipe_with - pub struct PipeFlags: c::c_int { - /// `O_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - /// `O_DIRECT` - #[cfg(not(any(target_os = "illumos", target_os = "openbsd", target_os = "redox")))] - const DIRECT = c::O_DIRECT; - /// `O_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `EFD_*` flags for use with [`eventfd`]. - /// - /// [`eventfd`]: crate::io::eventfd - pub struct EventfdFlags: c::c_int { - /// `EFD_CLOEXEC` - const CLOEXEC = c::EFD_CLOEXEC; - /// `EFD_NONBLOCK` - const NONBLOCK = c::EFD_NONBLOCK; - /// `EFD_SEMAPHORE` - const SEMAPHORE = c::EFD_SEMAPHORE; - } -} - -/// `PIPE_BUF`—The maximum size of a write to a pipe guaranteed to be atomic. -#[cfg(not(any(target_os = "illumos", target_os = "redox", target_os = "wasi")))] -pub const PIPE_BUF: usize = c::PIPE_BUF; - -#[cfg(not(any(windows, target_os = "redox")))] -pub(crate) const AT_FDCWD: c::c_int = c::AT_FDCWD; -#[cfg(not(windows))] -pub(crate) const STDIN_FILENO: c::c_int = c::STDIN_FILENO; -#[cfg(not(windows))] -pub(crate) const STDOUT_FILENO: c::c_int = c::STDOUT_FILENO; -#[cfg(not(windows))] -pub(crate) const STDERR_FILENO: c::c_int = c::STDERR_FILENO; diff --git a/vendor/rustix/src/imp/libc/io/windows_syscalls.rs b/vendor/rustix/src/imp/libc/io/windows_syscalls.rs deleted file mode 100644 index 4c6e86f94..000000000 --- a/vendor/rustix/src/imp/libc/io/windows_syscalls.rs +++ /dev/null @@ -1,39 +0,0 @@ -//! Windows system calls in the `io` module. - -use super::super::c; -use super::super::conv::{borrowed_fd, ret, ret_c_int}; -use super::super::fd::LibcFd; -use crate::fd::{BorrowedFd, RawFd}; -use crate::io; -use crate::io::PollFd; -use core::convert::TryInto; -use core::mem::MaybeUninit; - -pub(crate) unsafe fn close(raw_fd: RawFd) { - let _ = c::close(raw_fd as LibcFd); -} - -pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result { - let mut nread = MaybeUninit::::uninit(); - unsafe { - ret(c::ioctl(borrowed_fd(fd), c::FIONREAD, nread.as_mut_ptr()))?; - Ok(u64::from(nread.assume_init())) - } -} - -pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - unsafe { - let mut data = value as c::c_uint; - ret(c::ioctl(borrowed_fd(fd), c::FIONBIO, &mut data)) - } -} - -pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result { - let nfds = fds - .len() - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - - ret_c_int(unsafe { c::poll(fds.as_mut_ptr().cast(), nfds, timeout) }) - .map(|nready| nready as usize) -} diff --git a/vendor/rustix/src/imp/libc/io_lifetimes.rs b/vendor/rustix/src/imp/libc/io_lifetimes.rs deleted file mode 100644 index b0b14b7c8..000000000 --- a/vendor/rustix/src/imp/libc/io_lifetimes.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! `io_lifetimes` types for Windows assuming that Fd is Socket. -//! -//! We can make this assumption since `rustix` supports only `rustix::net` on -//! Windows. - -pub use io_lifetimes::{BorrowedSocket as BorrowedFd, OwnedSocket as OwnedFd}; -#[cfg(feature = "std")] -pub use std::os::windows::io::RawSocket as RawFd; -pub(crate) use windows_sys::Win32::Networking::WinSock::SOCKET as LibcFd; - -// Re-export the `Socket` traits so that users can implement them. -pub use io_lifetimes::{AsSocket, FromSocket, IntoSocket}; - -/// A version of [`AsRawFd`] for use with Winsock2 API. -/// -/// [`AsRawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsRawFd.html -pub trait AsRawFd { - /// A version of [`as_raw_fd`] for use with Winsock2 API. - /// - /// [`as_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.as_raw_fd - fn as_raw_fd(&self) -> RawFd; -} -#[cfg(feature = "std")] -impl AsRawFd for T { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.as_raw_socket() - } -} - -/// A version of [`IntoRawFd`] for use with Winsock2 API. -/// -/// [`IntoRawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.IntoRawFd.html -pub trait IntoRawFd { - /// A version of [`into_raw_fd`] for use with Winsock2 API. - /// - /// [`into_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.into_raw_fd - fn into_raw_fd(self) -> RawFd; -} -#[cfg(feature = "std")] -impl IntoRawFd for T { - #[inline] - fn into_raw_fd(self) -> RawFd { - self.into_raw_socket() - } -} - -/// A version of [`FromRawFd`] for use with Winsock2 API. -/// -/// [`FromRawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html -pub trait FromRawFd { - /// A version of [`from_raw_fd`] for use with Winsock2 API. - /// - /// [`from_raw_fd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.FromRawFd.html#tymethod.from_raw_fd - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self; -} -#[cfg(feature = "std")] -impl FromRawFd for T { - #[inline] - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self::from_raw_socket(raw_fd) - } -} - -/// A version of [`AsFd`] for use with Winsock2 API. -/// -/// [`AsFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/trait.AsFd.html -pub trait AsFd { - /// An `as_fd` function for Winsock2, where a `Fd` is a `Socket`. - fn as_fd(&self) -> BorrowedFd; -} -impl AsFd for T { - #[inline] - fn as_fd(&self) -> BorrowedFd { - self.as_socket() - } -} - -/// A version of [`IntoFd`] for use with Winsock2 API. -/// -/// [`IntoFd`]: https://docs.rs/io-lifetimes/latest/io_lifetimes/trait.IntoFd.html -pub trait IntoFd { - /// A version of [`into_fd`] for use with Winsock2 API. - /// - /// [`into_fd`]: https://docs.rs/io-lifetimes/latest/io_lifetimes/trait.IntoFd.html#tymethod.into_fd - fn into_fd(self) -> OwnedFd; -} -impl IntoFd for T { - #[inline] - fn into_fd(self) -> OwnedFd { - self.into_socket() - } -} - -/// A version of [`FromFd`] for use with Winsock2 API. -/// -/// [`FromFd`]: https://docs.rs/io-lifetimes/latest/io_lifetimes/trait.FromFd.html -pub trait FromFd { - /// A version of [`from_fd`] for use with Winsock2 API. - /// - /// [`from_fd`]: https://docs.rs/io-lifetimes/latest/io_lifetimes/trait.FromFd.html#tymethod.from_fd - fn from_fd(fd: OwnedFd) -> Self; -} -impl FromFd for T { - #[inline] - fn from_fd(fd: OwnedFd) -> Self { - Self::from_socket(fd) - } -} diff --git a/vendor/rustix/src/imp/libc/io_uring/mod.rs b/vendor/rustix/src/imp/libc/io_uring/mod.rs deleted file mode 100644 index ef944f04d..000000000 --- a/vendor/rustix/src/imp/libc/io_uring/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/imp/libc/io_uring/syscalls.rs b/vendor/rustix/src/imp/libc/io_uring/syscalls.rs deleted file mode 100644 index d1e68363c..000000000 --- a/vendor/rustix/src/imp/libc/io_uring/syscalls.rs +++ /dev/null @@ -1,55 +0,0 @@ -//! libc syscalls supporting `rustix::io_uring`. - -use super::super::c; -use super::super::conv::{borrowed_fd, syscall_ret, syscall_ret_owned_fd, syscall_ret_u32}; -use crate::fd::BorrowedFd; -use crate::io::{self, OwnedFd}; -use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterOp}; -use linux_raw_sys::general::{__NR_io_uring_enter, __NR_io_uring_register, __NR_io_uring_setup}; - -#[inline] -pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result { - unsafe { - syscall_ret_owned_fd(c::syscall( - __NR_io_uring_setup as _, - entries as usize, - params, - )) - } -} - -#[inline] -pub(crate) unsafe fn io_uring_register( - fd: BorrowedFd<'_>, - opcode: IoringRegisterOp, - arg: *const c::c_void, - nr_args: u32, -) -> io::Result<()> { - syscall_ret(c::syscall( - __NR_io_uring_register as _, - borrowed_fd(fd), - opcode as u32 as usize, - arg, - nr_args as usize, - )) -} - -#[inline] -pub(crate) unsafe fn io_uring_enter( - fd: BorrowedFd<'_>, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - arg: *const c::c_void, - size: usize, -) -> io::Result { - syscall_ret_u32(c::syscall( - __NR_io_uring_enter as _, - borrowed_fd(fd), - to_submit as usize, - min_complete as usize, - flags.bits() as usize, - arg, - size, - )) -} diff --git a/vendor/rustix/src/imp/libc/mm/mod.rs b/vendor/rustix/src/imp/libc/mm/mod.rs deleted file mode 100644 index 1e0181a99..000000000 --- a/vendor/rustix/src/imp/libc/mm/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/libc/mm/syscalls.rs b/vendor/rustix/src/imp/libc/mm/syscalls.rs deleted file mode 100644 index ee670b5bf..000000000 --- a/vendor/rustix/src/imp/libc/mm/syscalls.rs +++ /dev/null @@ -1,218 +0,0 @@ -//! libc syscalls supporting `rustix::mm`. - -use super::super::c; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::syscall_ret_owned_fd; -use super::super::conv::{borrowed_fd, no_fd, ret}; -use super::super::offset::libc_mmap; -#[cfg(not(target_os = "redox"))] -use super::types::Advice; -#[cfg(target_os = "linux")] -use super::types::MremapFlags; -use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::types::{MlockFlags, UserfaultfdFlags}; -use crate::fd::BorrowedFd; -use crate::io; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::io::OwnedFd; - -#[cfg(not(target_os = "redox"))] -pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { - // On Linux platforms, `MADV_DONTNEED` has the same value as - // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different - // value, and check for it here. - #[cfg(target_os = "linux")] - if let Advice::LinuxDontNeed = advice { - return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) }; - } - - #[cfg(not(target_os = "android"))] - { - let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) }; - - // `posix_madvise` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } - } - - #[cfg(target_os = "android")] - { - if let Advice::DontNeed = advice { - // Do nothing. Linux's `MADV_DONTNEED` isn't the same as - // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`. - Ok(()) - } else { - unsafe { ret(c::madvise(addr, len, advice as c::c_int)) } - } - } -} - -pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - let err = c::msync(addr, len, flags.bits()); - - // `msync` returns its error status rather than using `errno`. - if err == 0 { - Ok(()) - } else { - Err(io::Errno(err)) - } -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -pub(crate) unsafe fn mmap( - ptr: *mut c::c_void, - len: usize, - prot: ProtFlags, - flags: MapFlags, - fd: BorrowedFd<'_>, - offset: u64, -) -> io::Result<*mut c::c_void> { - let res = libc_mmap( - ptr, - len, - prot.bits(), - flags.bits(), - borrowed_fd(fd), - offset as i64, - ); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -pub(crate) unsafe fn mmap_anonymous( - ptr: *mut c::c_void, - len: usize, - prot: ProtFlags, - flags: MapFlags, -) -> io::Result<*mut c::c_void> { - let res = libc_mmap( - ptr, - len, - prot.bits(), - flags.bits() | c::MAP_ANONYMOUS, - no_fd(), - 0, - ); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -pub(crate) unsafe fn mprotect( - ptr: *mut c::c_void, - len: usize, - flags: MprotectFlags, -) -> io::Result<()> { - ret(c::mprotect(ptr, len, flags.bits())) -} - -pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> { - ret(c::munmap(ptr, len)) -} - -/// # Safety -/// -/// `mremap` is primarily unsafe due to the `old_address` parameter, as -/// anything working with memory pointed to by raw pointers is unsafe. -#[cfg(target_os = "linux")] -pub(crate) unsafe fn mremap( - old_address: *mut c::c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, -) -> io::Result<*mut c::c_void> { - let res = c::mremap(old_address, old_size, new_size, flags.bits()); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -/// # Safety -/// -/// `mremap_fixed` is primarily unsafe due to the `old_address` and -/// `new_address` parameters, as anything working with memory pointed to by raw -/// pointers is unsafe. -#[cfg(target_os = "linux")] -pub(crate) unsafe fn mremap_fixed( - old_address: *mut c::c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, - new_address: *mut c::c_void, -) -> io::Result<*mut c::c_void> { - let res = c::mremap( - old_address, - old_size, - new_size, - flags.bits() | c::MAP_FIXED, - new_address, - ); - if res == c::MAP_FAILED { - Err(io::Errno::last_os_error()) - } else { - Ok(res) - } -} - -/// # Safety -/// -/// `mlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(c::mlock(addr, length)) -} - -/// # Safety -/// -/// `mlock_with` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) unsafe fn mlock_with( - addr: *mut c::c_void, - length: usize, - flags: MlockFlags, -) -> io::Result<()> { - weak_or_syscall! { - fn mlock2( - addr: *const c::c_void, - len: c::size_t, - flags: c::c_int - ) via SYS_mlock2 -> c::c_int - } - - ret(mlock2(addr, length, flags.bits())) -} - -/// # Safety -/// -/// `munlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(c::munlock(addr, length)) -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result { - syscall_ret_owned_fd(c::syscall(c::SYS_userfaultfd, flags.bits())) -} diff --git a/vendor/rustix/src/imp/libc/mm/types.rs b/vendor/rustix/src/imp/libc/mm/types.rs deleted file mode 100644 index 385b6c0e6..000000000 --- a/vendor/rustix/src/imp/libc/mm/types.rs +++ /dev/null @@ -1,397 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `PROT_*` flags for use with [`mmap`]. - /// - /// For `PROT_NONE`, use `ProtFlags::empty()`. - /// - /// [`mmap`]: crate::io::mmap - pub struct ProtFlags: c::c_int { - /// `PROT_READ` - const READ = c::PROT_READ; - /// `PROT_WRITE` - const WRITE = c::PROT_WRITE; - /// `PROT_EXEC` - const EXEC = c::PROT_EXEC; - } -} - -bitflags! { - /// `PROT_*` flags for use with [`mprotect`]. - /// - /// For `PROT_NONE`, use `MprotectFlags::empty()`. - /// - /// [`mprotect`]: crate::io::mprotect - pub struct MprotectFlags: c::c_int { - /// `PROT_READ` - const READ = c::PROT_READ; - /// `PROT_WRITE` - const WRITE = c::PROT_WRITE; - /// `PROT_EXEC` - const EXEC = c::PROT_EXEC; - /// `PROT_GROWSUP` - #[cfg(any(target_os = "android", target_os = "linux"))] - const GROWSUP = c::PROT_GROWSUP; - /// `PROT_GROWSDOWN` - #[cfg(any(target_os = "android", target_os = "linux"))] - const GROWSDOWN = c::PROT_GROWSDOWN; - } -} - -bitflags! { - /// `MAP_*` flags for use with [`mmap`]. - /// - /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. - /// - /// [`mmap`]: crate::io::mmap - /// [`mmap_anonymous`]: crates::io::mmap_anonymous - pub struct MapFlags: c::c_int { - /// `MAP_SHARED` - const SHARED = c::MAP_SHARED; - /// `MAP_SHARED_VALIDATE` - #[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const SHARED_VALIDATE = c::MAP_SHARED_VALIDATE; - /// `MAP_PRIVATE` - const PRIVATE = c::MAP_PRIVATE; - /// `MAP_DENYWRITE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const DENYWRITE = c::MAP_DENYWRITE; - /// `MAP_FIXED` - const FIXED = c::MAP_FIXED; - /// `MAP_FIXED_NOREPLACE` - #[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const FIXED_NOREPLACE = c::MAP_FIXED_NOREPLACE; - /// `MAP_GROWSDOWN` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const GROWSDOWN = c::MAP_GROWSDOWN; - /// `MAP_HUGETLB` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const HUGETLB = c::MAP_HUGETLB; - /// `MAP_HUGE_2MB` - #[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const HUGE_2MB = c::MAP_HUGE_2MB; - /// `MAP_HUGE_1GB` - #[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const HUGE_1GB = c::MAP_HUGE_1GB; - /// `MAP_LOCKED` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const LOCKED = c::MAP_LOCKED; - /// `MAP_NORESERVE` - #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "redox")))] - const NORESERVE = c::MAP_NORESERVE; - /// `MAP_POPULATE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - const POPULATE = c::MAP_POPULATE; - /// `MAP_STACK` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "redox", - )))] - const STACK = c::MAP_STACK; - /// `MAP_SYNC` - #[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - all( - any(target_os = "android", target_os = "linux"), - any(target_arch = "mips", target_arch = "mips64"), - ) - )))] - const SYNC = c::MAP_SYNC; - /// `MAP_UNINITIALIZED` - #[cfg(any())] - const UNINITIALIZED = c::MAP_UNINITIALIZED; - } -} - -#[cfg(target_os = "linux")] -bitflags! { - /// `MREMAP_*` flags for use with [`mremap`]. - /// - /// For `MREMAP_FIXED`, see [`mremap_fixed`]. - /// - /// [`mremap`]: crate::io::mremap - /// [`mremap_fixed`]: crate::io::mremap_fixed - pub struct MremapFlags: i32 { - /// `MREMAP_MAYMOVE` - const MAYMOVE = c::MREMAP_MAYMOVE; - } -} - -bitflags! { - /// `MS_*` flags for use with [`msync`]. - /// - /// [`msync`]: crate::io::msync - pub struct MsyncFlags: i32 { - /// `MS_SYNC`—Requests an update and waits for it to complete. - const SYNC = c::MS_SYNC; - /// `MS_ASYNC`—Specifies that an update be scheduled, but the call - /// returns immediately. - const ASYNC = c::MS_ASYNC; - /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same - /// file (so that they can be updated with the fresh values just - /// written). - const INVALIDATE = c::MS_INVALIDATE; - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `MLOCK_*` flags for use with [`mlock_with`]. - /// - /// [`mlock_with`]: crate::io::mlock_with - pub struct MlockFlags: i32 { - /// `MLOCK_ONFAULT` - const ONFAULT = c::MLOCK_ONFAULT as _; - } -} - -/// `POSIX_MADV_*` constants for use with [`madvise`]. -/// -/// [`madvise`]: crate::mm::madvise -#[cfg(not(target_os = "redox"))] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(i32)] -#[non_exhaustive] -pub enum Advice { - /// `POSIX_MADV_NORMAL` - #[cfg(not(target_os = "android"))] - Normal = c::POSIX_MADV_NORMAL, - - /// `POSIX_MADV_NORMAL` - #[cfg(target_os = "android")] - Normal = c::MADV_NORMAL, - - /// `POSIX_MADV_SEQUENTIAL` - #[cfg(not(target_os = "android"))] - Sequential = c::POSIX_MADV_SEQUENTIAL, - - /// `POSIX_MADV_SEQUENTIAL` - #[cfg(target_os = "android")] - Sequential = c::MADV_SEQUENTIAL, - - /// `POSIX_MADV_RANDOM` - #[cfg(not(target_os = "android"))] - Random = c::POSIX_MADV_RANDOM, - - /// `POSIX_MADV_RANDOM` - #[cfg(target_os = "android")] - Random = c::MADV_RANDOM, - - /// `POSIX_MADV_WILLNEED` - #[cfg(not(target_os = "android"))] - WillNeed = c::POSIX_MADV_WILLNEED, - - /// `POSIX_MADV_WILLNEED` - #[cfg(target_os = "android")] - WillNeed = c::MADV_WILLNEED, - - /// `POSIX_MADV_DONTNEED` - #[cfg(not(any(target_os = "android", target_os = "emscripten")))] - DontNeed = c::POSIX_MADV_DONTNEED, - - /// `POSIX_MADV_DONTNEED` - #[cfg(target_os = "android")] - DontNeed = i32::MAX - 1, - - /// `MADV_DONTNEED` - // `MADV_DONTNEED` has the same value as `POSIX_MADV_DONTNEED`. We don't - // have a separate `posix_madvise` from `madvise`, so we expose a special - // value which we special-case. - #[cfg(target_os = "linux")] - LinuxDontNeed = i32::MAX, - - /// `MADV_DONTNEED` - #[cfg(target_os = "android")] - LinuxDontNeed = c::MADV_DONTNEED, - /// `MADV_FREE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxFree = c::MADV_FREE, - /// `MADV_REMOVE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxRemove = c::MADV_REMOVE, - /// `MADV_DONTFORK` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDontFork = c::MADV_DONTFORK, - /// `MADV_DOFORK` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDoFork = c::MADV_DOFORK, - /// `MADV_HWPOISON` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxHwPoison = c::MADV_HWPOISON, - /// `MADV_SOFT_OFFLINE` - #[cfg(all( - any(target_os = "android", target_os = "linux"), - not(any(target_arch = "mips", target_arch = "mips64")), - ))] - LinuxSoftOffline = c::MADV_SOFT_OFFLINE, - /// `MADV_MERGEABLE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxMergeable = c::MADV_MERGEABLE, - /// `MADV_UNMERGEABLE` - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxUnmergeable = c::MADV_UNMERGEABLE, - /// `MADV_HUGEPAGE` (since Linux 2.6.38) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxHugepage = c::MADV_HUGEPAGE, - /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxNoHugepage = c::MADV_NOHUGEPAGE, - /// `MADV_DONTDUMP` (since Linux 3.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDontDump = c::MADV_DONTDUMP, - /// `MADV_DODUMP` (since Linux 3.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - LinuxDoDump = c::MADV_DODUMP, - /// `MADV_WIPEONFORK` (since Linux 4.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK as i32, - /// `MADV_KEEPONFORK` (since Linux 4.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK as i32, - /// `MADV_COLD` (since Linux 5.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxCold = linux_raw_sys::general::MADV_COLD as i32, - /// `MADV_PAGEOUT` (since Linux 5.4) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT as i32, - /// `MADV_POPULATE_READ` (since Linux 5.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ as i32, - /// `MADV_POPULATE_WRITE` (since Linux 5.14) - #[cfg(any(target_os = "android", target_os = "linux"))] - #[cfg(feature = "mm")] - LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE as i32, -} - -#[cfg(target_os = "emscripten")] -impl Advice { - /// `POSIX_MADV_DONTNEED` - #[allow(non_upper_case_globals)] - pub const DontNeed: Self = Self::Normal; -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -bitflags! { - /// `O_*` flags for use with [`userfaultfd`]. - /// - /// [`userfaultfd`]: crate::io::userfaultfd - pub struct UserfaultfdFlags: c::c_int { - /// `O_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - /// `O_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - } -} diff --git a/vendor/rustix/src/imp/libc/mod.rs b/vendor/rustix/src/imp/libc/mod.rs deleted file mode 100644 index e99a323ce..000000000 --- a/vendor/rustix/src/imp/libc/mod.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! The libc backend. -//! -//! On most platforms, this uses the `libc` crate to make system calls. On -//! Windows, this uses the Winsock2 API in `windows-sys`, which can be adapted -//! to have a very `libc`-like interface. - -// Every FFI call requires an unsafe block, and there are a lot of FFI -// calls. For now, set this to allow for the libc backend. -#![allow(clippy::undocumented_unsafe_blocks)] -// Lots of libc types vary between platforms, so we often need a `.into()` on -// one platform where it's redundant on another. -#![allow(clippy::useless_conversion)] - -#[cfg(not(any(windows, target_os = "wasi")))] -#[macro_use] -mod weak; - -mod conv; -mod offset; - -#[cfg(windows)] -mod io_lifetimes; -#[cfg(not(windows))] -#[cfg(not(feature = "std"))] -pub(crate) mod fd { - pub(crate) use super::c::c_int as LibcFd; - pub use crate::io::fd::*; -} -#[cfg(windows)] -pub(crate) mod fd { - pub use super::io_lifetimes::*; -} -#[cfg(not(windows))] -#[cfg(feature = "std")] -pub(crate) mod fd { - pub use io_lifetimes::*; - - #[cfg(target_os = "wasi")] - #[allow(unused_imports)] - pub(crate) use super::c::c_int as LibcFd; - #[cfg(unix)] - #[allow(unused_imports)] - pub(crate) use std::os::unix::io::RawFd as LibcFd; - #[cfg(unix)] - pub use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; - #[cfg(target_os = "wasi")] - pub use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -} - -// On Windows we emulate selected libc-compatible interfaces. On non-Windows, -// we just use libc here, since this is the libc backend. -#[cfg(windows)] -#[path = "winsock_c.rs"] -pub(crate) mod c; -#[cfg(not(windows))] -pub(crate) use libc as c; - -#[cfg(not(windows))] -// #[cfg(feature = "fs")] // TODO: Enable this once `OwnedFd` moves out of the tree. -pub(crate) mod fs; -pub(crate) mod io; -#[cfg(any(target_os = "android", target_os = "linux"))] -#[cfg(feature = "io_uring")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))] -pub(crate) mod io_uring; -#[cfg(not(any(windows, target_os = "wasi")))] -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -pub(crate) mod mm; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[cfg(feature = "net")] -pub(crate) mod net; -#[cfg(not(windows))] -#[cfg(any( - feature = "param", - feature = "runtime", - feature = "time", - target_arch = "x86", -))] -pub(crate) mod param; -#[cfg(not(windows))] -pub(crate) mod process; -#[cfg(not(windows))] -#[cfg(feature = "rand")] -pub(crate) mod rand; -#[cfg(not(any(windows, target_os = "wasi")))] -#[cfg(feature = "termios")] -pub(crate) mod termios; -#[cfg(not(windows))] -#[cfg(feature = "thread")] -pub(crate) mod thread; -#[cfg(not(windows))] -pub(crate) mod time; - -/// If the host libc is glibc, return `true` if it is less than version 2.25. -/// -/// To restate and clarify, this function returning true does not mean the libc -/// is glibc just that if it is glibc, it is less than version 2.25. -/// -/// For now, this function is only available on Linux, but if it ends up being -/// used beyond that, this could be changed to e.g. `#[cfg(unix)]`. -#[cfg(all(unix, target_env = "gnu"))] -pub(crate) fn if_glibc_is_less_than_2_25() -> bool { - // This is also defined inside `weak_or_syscall!` in - // imp/libc/rand/syscalls.rs, but it's not convenient to re-export the weak - // symbol from that macro, so we duplicate it at a small cost here. - weak! { fn getrandom(*mut c::c_void, c::size_t, c::c_uint) -> c::ssize_t } - - // glibc 2.25 has `getrandom`, which is how we satisfy the API contract of - // this function. But, there are likely other libc versions which have it. - getrandom.get().is_none() -} diff --git a/vendor/rustix/src/imp/libc/net/addr.rs b/vendor/rustix/src/imp/libc/net/addr.rs deleted file mode 100644 index 1aeda5e5d..000000000 --- a/vendor/rustix/src/imp/libc/net/addr.rs +++ /dev/null @@ -1,320 +0,0 @@ -//! IPv4, IPv6, and Socket addresses. - -use super::super::c; -#[cfg(unix)] -use crate::ffi::CStr; -#[cfg(unix)] -use crate::io; -#[cfg(unix)] -use crate::path; -#[cfg(not(windows))] -use core::convert::TryInto; -#[cfg(unix)] -use core::fmt; -#[cfg(unix)] -use core::slice; - -/// `struct sockaddr_un` -#[cfg(unix)] -#[derive(Clone)] -#[doc(alias = "sockaddr_un")] -pub struct SocketAddrUnix { - pub(crate) unix: c::sockaddr_un, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - len: c::socklen_t, -} - -#[cfg(unix)] -impl SocketAddrUnix { - /// Construct a new Unix-domain address from a filesystem path. - #[inline] - pub fn new(path: P) -> io::Result { - path.into_with_c_str(Self::_new) - } - - #[inline] - fn _new(path: &CStr) -> io::Result { - let mut unix = Self::init(); - let bytes = path.to_bytes_with_nul(); - if bytes.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = *b as c::c_char; - } - - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - { - unix.sun_len = (offsetof_sun_path() + bytes.len()).try_into().unwrap(); - } - - Ok(Self { - unix, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - len: (offsetof_sun_path() + bytes.len()).try_into().unwrap(), - }) - } - - /// Construct a new abstract Unix-domain address from a byte slice. - #[cfg(any(target_os = "android", target_os = "linux"))] - #[inline] - pub fn new_abstract_name(name: &[u8]) -> io::Result { - 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 len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { - unix, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - len, - }) - } - - fn init() -> c::sockaddr_un { - c::sockaddr_un { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sun_len: 0, - sun_family: c::AF_UNIX as _, - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sun_path: [0; 104], - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - sun_path: [0; 108], - } - } - - /// For a filesystem path address, return the path. - #[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 { - 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(), - ))) - } - } else { - None - } - } - - /// For an abstract address, return the identifier. - #[cfg(any(target_os = "android", target_os = "linux"))] - #[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 { - 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())) } - } else { - None - } - } - - #[inline] - pub(crate) fn addr_len(&self) -> c::socklen_t { - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - { - self.len - } - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - { - c::socklen_t::from(self.unix.sun_len) - } - } - - #[inline] - pub(crate) fn len(&self) -> usize { - self.addr_len() as usize - } -} - -#[cfg(unix)] -impl PartialEq for SocketAddrUnix { - #[inline] - fn eq(&self, other: &Self) -> bool { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) - } -} - -#[cfg(unix)] -impl Eq for SocketAddrUnix {} - -#[cfg(unix)] -impl PartialOrd for SocketAddrUnix { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - 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]) - } -} - -#[cfg(unix)] -impl Ord for SocketAddrUnix { - #[inline] - fn cmp(&self, other: &Self) -> core::cmp::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]) - } -} - -#[cfg(unix)] -impl core::hash::Hash for SocketAddrUnix { - #[inline] - fn hash(&self, state: &mut H) { - let self_len = self.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].hash(state) - } -} - -#[cfg(unix)] -impl fmt::Debug for SocketAddrUnix { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(path) = self.path() { - path.fmt(fmt) - } else { - #[cfg(any(target_os = "android", target_os = "linux"))] - if let Some(name) = self.abstract_name() { - return name.fmt(fmt); - } - - "(unnamed)".fmt(fmt) - } - } -} - -/// `struct sockaddr_storage` as a raw struct. -pub type SocketAddrStorage = c::sockaddr_storage; - -/// Return the offset of the `sun_path` field of `sockaddr_un`. -#[cfg(not(windows))] -#[inline] -pub(crate) fn offsetof_sun_path() -> usize { - let z = c::sockaddr_un { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sun_len: 0_u8, - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sun_family: 0_u8, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - sun_family: 0_u16, - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sun_path: [0; 104], - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - sun_path: [0; 108], - }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) -} diff --git a/vendor/rustix/src/imp/libc/net/ext.rs b/vendor/rustix/src/imp/libc/net/ext.rs deleted file mode 100644 index 7b5313c51..000000000 --- a/vendor/rustix/src/imp/libc/net/ext.rs +++ /dev/null @@ -1,223 +0,0 @@ -use super::super::c; - -/// The windows `sockaddr_in6` type is a union with accessor functions which -/// are not `const fn`. Define our own layout-compatible version so that we -/// can transmute in and out of it. -#[cfg(windows)] -#[repr(C)] -struct sockaddr_in6 { - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - addr.s_addr -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. - unsafe { core::mem::transmute(addr) } -} - -// TODO: With Rust 1.55, we can use the above `in_addr_s_addr` definition that -// uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) fn in_addr_s_addr(addr: c::in_addr) -> u32 { - // This should be `*addr.S_un.S_addr()`, except that isn't a `const fn`. - unsafe { core::mem::transmute(addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - c::in_addr { s_addr } -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - unsafe { core::mem::transmute(s_addr) } -} - -// TODO: With Rust 1.55, we can use the above `in_addr_new` definition that -// uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) fn in_addr_new(s_addr: u32) -> c::in_addr { - unsafe { core::mem::transmute(s_addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - addr.s6_addr -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - unsafe { core::mem::transmute(addr) } -} - -// TODO: With Rust 1.55, we can use the above `in6_addr_s6_addr` definition -// that uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - unsafe { core::mem::transmute(addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - c::in6_addr { s6_addr } -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - unsafe { core::mem::transmute(s6_addr) } -} - -// TODO: With Rust 1.55, we can use the above `in6_addr_new` definition that -// uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - unsafe { core::mem::transmute(s6_addr) } -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { - addr.sin6_scope_id -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { - let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; - addr.sin6_scope_id -} - -// TODO: With Rust 1.55, we can use the above `sockaddr_in6_sin6_scope_id` -// definition that uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { - let addr: sockaddr_in6 = unsafe { core::mem::transmute(addr) }; - addr.sin6_scope_id -} - -#[cfg(not(feature = "std"))] -#[cfg(not(windows))] -#[inline] -pub(crate) fn sockaddr_in6_sin6_scope_id_mut(addr: &mut c::sockaddr_in6) -> &mut u32 { - &mut addr.sin6_scope_id -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) fn sockaddr_in6_sin6_scope_id_mut(addr: &mut c::sockaddr_in6) -> &mut u32 { - let addr: &mut sockaddr_in6 = unsafe { core::mem::transmute(addr) }; - &mut addr.sin6_scope_id -} - -#[cfg(not(windows))] -#[inline] -pub(crate) const fn sockaddr_in6_new( - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sin6_len: u8, - sin6_family: c::sa_family_t, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - c::sockaddr_in6 { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sin6_len, - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - #[cfg(target_os = "illumos")] - __sin6_src_id: 0, - } -} - -#[cfg(not(feature = "std"))] -#[cfg(windows)] -#[inline] -pub(crate) const fn sockaddr_in6_new( - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - let addr = sockaddr_in6 { - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - }; - unsafe { core::mem::transmute(addr) } -} - -// TODO: With Rust 1.55, we can use the above `sockaddr_in6_new` definition -// that uses a const-fn transmute. -#[cfg(feature = "std")] -#[cfg(windows)] -#[inline] -pub(crate) fn sockaddr_in6_new( - sin6_family: u16, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - let addr = sockaddr_in6 { - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - }; - unsafe { core::mem::transmute(addr) } -} diff --git a/vendor/rustix/src/imp/libc/net/mod.rs b/vendor/rustix/src/imp/libc/net/mod.rs deleted file mode 100644 index f7196ae4f..000000000 --- a/vendor/rustix/src/imp/libc/net/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub(crate) mod addr; -pub(crate) mod ext; -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/imp/libc/net/read_sockaddr.rs b/vendor/rustix/src/imp/libc/net/read_sockaddr.rs deleted file mode 100644 index cb76b296c..000000000 --- a/vendor/rustix/src/imp/libc/net/read_sockaddr.rs +++ /dev/null @@ -1,249 +0,0 @@ -use super::super::c; -#[cfg(unix)] -use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_sin6_scope_id}; -#[cfg(not(windows))] -use crate::ffi::CStr; -use crate::io; -use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; -#[cfg(not(windows))] -use alloc::vec::Vec; -use core::mem::size_of; - -// This must match the header of `sockaddr`. -#[repr(C)] -struct sockaddr_header { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sa_len: u8, - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - ss_family: u8, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - ss_family: u16, -} - -#[inline] -unsafe fn read_ss_family(storage: *const c::sockaddr_storage) -> u16 { - // Assert that we know the layout of `sockaddr`. - let _ = c::sockaddr { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sa_len: 0_u8, - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sa_family: 0_u8, - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - sa_family: 0_u16, - sa_data: [0; 14], - }; - - (*storage.cast::()).ss_family.into() -} - -/// Set the `ss_family` field of a socket address to `AF_UNSPEC`, so that we -/// can test for `AF_UNSPEC` to test whether it was stored to. -pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr_storage) { - (*storage.cast::()).ss_family = c::AF_UNSPEC as _; -} - -pub(crate) unsafe fn read_sockaddr( - storage: *const c::sockaddr_storage, - len: usize, -) -> io::Result { - #[cfg(unix)] - let offsetof_sun_path = super::addr::offsetof_sun_path(); - - if len < size_of::() { - return Err(io::Errno::INVAL); - } - match read_ss_family(storage).into() { - c::AF_INET => { - if len < size_of::() { - return Err(io::Errno::INVAL); - } - let decode = *storage.cast::(); - Ok(SocketAddrAny::V4(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), - u16::from_be(decode.sin_port), - ))) - } - c::AF_INET6 => { - if len < size_of::() { - return Err(io::Errno::INVAL); - } - let decode = *storage.cast::(); - #[cfg(not(windows))] - let s6_addr = decode.sin6_addr.s6_addr; - #[cfg(windows)] - let s6_addr = decode.sin6_addr.u.Byte; - #[cfg(not(windows))] - let sin6_scope_id = decode.sin6_scope_id; - #[cfg(windows)] - let sin6_scope_id = decode.Anonymous.sin6_scope_id; - Ok(SocketAddrAny::V6(SocketAddrV6::new( - Ipv6Addr::from(s6_addr), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - sin6_scope_id, - ))) - } - #[cfg(unix)] - c::AF_UNIX => { - if len < offsetof_sun_path { - return Err(io::Errno::INVAL); - } - if len == offsetof_sun_path { - Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap())) - } else { - let decode = *storage.cast::(); - - // Trim off unused bytes from the end of `path_bytes`. - let path_bytes = if cfg!(target_os = "freebsd") { - // FreeBSD sometimes sets the length to longer than the length - // of the NUL-terminated string. Find the NUL and truncate the - // string accordingly. - &decode.sun_path[..decode.sun_path.iter().position(|b| *b == 0).unwrap()] - } else { - // Otherwise, use the provided length. - let provided_len = len - 1 - offsetof_sun_path; - if decode.sun_path[provided_len] != b'\0' as c::c_char { - return Err(io::Errno::INVAL); - } - debug_assert_eq!( - CStr::from_ptr(decode.sun_path.as_ptr()).to_bytes().len(), - provided_len - ); - &decode.sun_path[..provided_len] - }; - - Ok(SocketAddrAny::Unix( - SocketAddrUnix::new(path_bytes.iter().map(|c| *c as u8).collect::>()) - .unwrap(), - )) - } - } - _ => Err(io::Errno::INVAL), - } -} - -pub(crate) unsafe fn maybe_read_sockaddr_os( - storage: *const c::sockaddr_storage, - len: usize, -) -> Option { - if len == 0 { - return None; - } - - assert!(len >= size_of::()); - let family = read_ss_family(storage).into(); - if family == c::AF_UNSPEC { - None - } else { - Some(inner_read_sockaddr_os(family, storage, len)) - } -} - -pub(crate) unsafe fn read_sockaddr_os( - storage: *const c::sockaddr_storage, - len: usize, -) -> SocketAddrAny { - assert!(len >= size_of::()); - let family = read_ss_family(storage).into(); - inner_read_sockaddr_os(family, storage, len) -} - -unsafe fn inner_read_sockaddr_os( - family: c::c_int, - storage: *const c::sockaddr_storage, - len: usize, -) -> SocketAddrAny { - #[cfg(unix)] - let offsetof_sun_path = super::addr::offsetof_sun_path(); - - assert!(len >= size_of::()); - match family { - c::AF_INET => { - assert!(len >= size_of::()); - let decode = *storage.cast::(); - SocketAddrAny::V4(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))), - u16::from_be(decode.sin_port), - )) - } - c::AF_INET6 => { - assert!(len >= size_of::()); - let decode = *storage.cast::(); - SocketAddrAny::V6(SocketAddrV6::new( - Ipv6Addr::from(in6_addr_s6_addr(decode.sin6_addr)), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - sockaddr_in6_sin6_scope_id(decode), - )) - } - #[cfg(unix)] - c::AF_UNIX => { - assert!(len >= offsetof_sun_path); - if len == offsetof_sun_path { - SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) - } else { - let decode = *storage.cast::(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); - let path_bytes = &decode.sun_path[..len - 1 - offsetof_sun_path]; - - // FreeBSD sometimes sets the length to longer than the length - // of the NUL-terminated string. Find the NUL and truncate the - // string accordingly. - #[cfg(target_os = "freebsd")] - let path_bytes = &path_bytes[..path_bytes.iter().position(|b| *b == 0).unwrap()]; - - SocketAddrAny::Unix( - SocketAddrUnix::new(path_bytes.iter().map(|c| *c as u8).collect::>()) - .unwrap(), - ) - } - } - other => unimplemented!("{:?}", other), - } -} diff --git a/vendor/rustix/src/imp/libc/net/send_recv.rs b/vendor/rustix/src/imp/libc/net/send_recv.rs deleted file mode 100644 index 9ab908d62..000000000 --- a/vendor/rustix/src/imp/libc/net/send_recv.rs +++ /dev/null @@ -1,77 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `MSG_*` - pub struct SendFlags: i32 { - /// `MSG_CONFIRM` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - const CONFIRM = c::MSG_CONFIRM; - /// `MSG_DONTROUTE` - const DONTROUTE = c::MSG_DONTROUTE; - /// `MSG_DONTWAIT` - #[cfg(not(windows))] - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_EOR` - #[cfg(not(windows))] - const EOT = c::MSG_EOR; - /// `MSG_MORE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - const MORE = c::MSG_MORE; - #[cfg(not(any(windows, target_os = "ios", target_os = "macos")))] - /// `MSG_NOSIGNAL` - const NOSIGNAL = c::MSG_NOSIGNAL; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - } -} - -bitflags! { - /// `MSG_*` - pub struct RecvFlags: i32 { - #[cfg(not(any(windows, target_os = "illumos", target_os = "ios", target_os = "macos")))] - /// `MSG_CMSG_CLOEXEC` - const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; - /// `MSG_DONTWAIT` - #[cfg(not(windows))] - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_ERRQUEUE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - const ERRQUEUE = c::MSG_ERRQUEUE; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - /// `MSG_PEEK` - const PEEK = c::MSG_PEEK; - /// `MSG_TRUNC` - const TRUNC = c::MSG_TRUNC as c::c_int; - /// `MSG_WAITALL` - const WAITALL = c::MSG_WAITALL; - } -} diff --git a/vendor/rustix/src/imp/libc/net/syscalls.rs b/vendor/rustix/src/imp/libc/net/syscalls.rs deleted file mode 100644 index b0bab2e31..000000000 --- a/vendor/rustix/src/imp/libc/net/syscalls.rs +++ /dev/null @@ -1,866 +0,0 @@ -//! libc syscalls supporting `rustix::net`. - -use super::super::c; -use super::super::conv::{borrowed_fd, ret, ret_owned_fd, ret_send_recv, send_recv_len}; -#[cfg(unix)] -use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_new, in_addr_new}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::read_sockaddr::initialize_family_to_unspec; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::read_sockaddr::{maybe_read_sockaddr_os, read_sockaddr_os}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::send_recv::{RecvFlags, SendFlags}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::types::{AcceptFlags, AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; -use crate::fd::BorrowedFd; -use crate::io::{self, OwnedFd}; -use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; -use crate::utils::as_ptr; -use core::convert::TryInto; -use core::mem::{size_of, MaybeUninit}; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -use core::ptr::null_mut; - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io::Result { - let nrecv = unsafe { - ret_send_recv(c::recv( - borrowed_fd(fd), - buf.as_mut_ptr().cast(), - send_recv_len(buf.len()), - flags.bits(), - ))? - }; - Ok(nrecv as usize) -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result { - let nwritten = unsafe { - ret_send_recv(c::send( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - flags.bits(), - ))? - }; - Ok(nwritten as usize) -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn recvfrom( - fd: BorrowedFd<'_>, - buf: &mut [u8], - flags: RecvFlags, -) -> io::Result<(usize, Option)> { - unsafe { - let mut storage = MaybeUninit::::uninit(); - let mut len = size_of::() as c::socklen_t; - - // `recvfrom` does not write to the storage if the socket is - // connection-oriented sockets, so we initialize the family field to - // `AF_UNSPEC` so that we can detect this case. - initialize_family_to_unspec(storage.as_mut_ptr()); - - let nread = ret_send_recv(c::recvfrom( - borrowed_fd(fd), - buf.as_mut_ptr().cast(), - send_recv_len(buf.len()), - flags.bits(), - storage.as_mut_ptr().cast(), - &mut len, - ))?; - Ok(( - nread as usize, - maybe_read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap()), - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn sendto_v4( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrV4, -) -> io::Result { - let nwritten = unsafe { - ret_send_recv(c::sendto( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - flags.bits(), - as_ptr(&encode_sockaddr_v4(addr)).cast::(), - size_of::() as _, - ))? - }; - Ok(nwritten as usize) -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn sendto_v6( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrV6, -) -> io::Result { - let nwritten = unsafe { - ret_send_recv(c::sendto( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - flags.bits(), - as_ptr(&encode_sockaddr_v6(addr)).cast::(), - size_of::() as _, - ))? - }; - Ok(nwritten as usize) -} - -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] -pub(crate) fn sendto_unix( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrUnix, -) -> io::Result { - let nwritten = unsafe { - ret_send_recv(c::sendto( - borrowed_fd(fd), - buf.as_ptr().cast(), - send_recv_len(buf.len()), - flags.bits(), - as_ptr(&addr.unix).cast(), - addr.addr_len(), - ))? - }; - Ok(nwritten as usize) -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn socket( - domain: AddressFamily, - type_: SocketType, - protocol: Protocol, -) -> io::Result { - unsafe { - ret_owned_fd(c::socket( - domain.0 as c::c_int, - type_.0 as c::c_int, - protocol.0, - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn socket_with( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Protocol, -) -> io::Result { - unsafe { - ret_owned_fd(c::socket( - domain.0 as c::c_int, - type_.0 as c::c_int | flags.bits(), - protocol.0, - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn bind_v4(sockfd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { - unsafe { - ret(c::bind( - borrowed_fd(sockfd), - as_ptr(&encode_sockaddr_v4(addr)).cast(), - size_of::() as c::socklen_t, - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn bind_v6(sockfd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { - unsafe { - ret(c::bind( - borrowed_fd(sockfd), - as_ptr(&encode_sockaddr_v6(addr)).cast(), - size_of::() as c::socklen_t, - )) - } -} - -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] -pub(crate) fn bind_unix(sockfd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { - unsafe { - ret(c::bind( - borrowed_fd(sockfd), - as_ptr(&addr.unix).cast(), - addr.addr_len(), - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn connect_v4(sockfd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { - unsafe { - ret(c::connect( - borrowed_fd(sockfd), - as_ptr(&encode_sockaddr_v4(addr)).cast(), - size_of::() as c::socklen_t, - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn connect_v6(sockfd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { - unsafe { - ret(c::connect( - borrowed_fd(sockfd), - as_ptr(&encode_sockaddr_v6(addr)).cast(), - size_of::() as c::socklen_t, - )) - } -} - -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] -pub(crate) fn connect_unix(sockfd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { - unsafe { - ret(c::connect( - borrowed_fd(sockfd), - as_ptr(&addr.unix).cast(), - addr.addr_len(), - )) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn listen(sockfd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { - unsafe { ret(c::listen(borrowed_fd(sockfd), backlog)) } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn accept(sockfd: BorrowedFd<'_>) -> io::Result { - unsafe { - let owned_fd = ret_owned_fd(c::accept(borrowed_fd(sockfd), null_mut(), null_mut()))?; - Ok(owned_fd) - } -} - -#[cfg(not(any( - windows, - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, flags: AcceptFlags) -> io::Result { - unsafe { - let owned_fd = ret_owned_fd(c::accept4( - borrowed_fd(sockfd), - null_mut(), - null_mut(), - flags.bits(), - ))?; - Ok(owned_fd) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn acceptfrom(sockfd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option)> { - unsafe { - let mut storage = MaybeUninit::::uninit(); - let mut len = size_of::() as c::socklen_t; - let owned_fd = ret_owned_fd(c::accept( - borrowed_fd(sockfd), - storage.as_mut_ptr().cast(), - &mut len, - ))?; - Ok(( - owned_fd, - maybe_read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap()), - )) - } -} - -#[cfg(not(any( - windows, - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -pub(crate) fn acceptfrom_with( - sockfd: BorrowedFd<'_>, - flags: AcceptFlags, -) -> io::Result<(OwnedFd, Option)> { - unsafe { - let mut storage = MaybeUninit::::uninit(); - let mut len = size_of::() as c::socklen_t; - let owned_fd = ret_owned_fd(c::accept4( - borrowed_fd(sockfd), - storage.as_mut_ptr().cast(), - &mut len, - flags.bits(), - ))?; - Ok(( - owned_fd, - maybe_read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap()), - )) - } -} - -/// Darwin lacks `accept4`, but does have `accept`. We define -/// `AcceptFlags` to have no flags, so we can discard it here. -#[cfg(any(windows, target_os = "ios", target_os = "macos"))] -pub(crate) fn accept_with(sockfd: BorrowedFd<'_>, _flags: AcceptFlags) -> io::Result { - accept(sockfd) -} - -/// Darwin lacks `accept4`, but does have `accept`. We define -/// `AcceptFlags` to have no flags, so we can discard it here. -#[cfg(any(windows, target_os = "ios", target_os = "macos"))] -pub(crate) fn acceptfrom_with( - sockfd: BorrowedFd<'_>, - _flags: AcceptFlags, -) -> io::Result<(OwnedFd, Option)> { - acceptfrom(sockfd) -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn shutdown(sockfd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { - unsafe { ret(c::shutdown(borrowed_fd(sockfd), how as c::c_int)) } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn getsockname(sockfd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut storage = MaybeUninit::::uninit(); - let mut len = size_of::() as c::socklen_t; - ret(c::getsockname( - borrowed_fd(sockfd), - storage.as_mut_ptr().cast(), - &mut len, - ))?; - Ok(read_sockaddr_os(storage.as_ptr(), len.try_into().unwrap())) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) fn getpeername(sockfd: BorrowedFd<'_>) -> io::Result> { - unsafe { - let mut storage = MaybeUninit::::uninit(); - let mut len = size_of::() as c::socklen_t; - ret(c::getpeername( - borrowed_fd(sockfd), - storage.as_mut_ptr().cast(), - &mut len, - ))?; - Ok(maybe_read_sockaddr_os( - storage.as_ptr(), - len.try_into().unwrap(), - )) - } -} - -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] -pub(crate) fn socketpair( - domain: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Protocol, -) -> io::Result<(OwnedFd, OwnedFd)> { - unsafe { - let mut fds = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(c::socketpair( - c::c_int::from(domain.0), - type_.0 as c::c_int | flags.bits(), - protocol.0, - fds.as_mut_ptr().cast::(), - ))?; - - let [fd0, fd1] = fds.assume_init(); - Ok((fd0, fd1)) - } -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -pub(crate) mod sockopt { - use super::{c, in6_addr_new, in_addr_new, BorrowedFd}; - use crate::io; - use crate::net::sockopt::Timeout; - use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; - use crate::utils::as_mut_ptr; - use core::convert::TryInto; - use core::time::Duration; - #[cfg(windows)] - use windows_sys::Win32::Foundation::BOOL; - - // TODO: With Rust 1.53 we can use `Duration::ZERO` instead. - const DURATION_ZERO: Duration = Duration::from_secs(0); - - #[inline] - fn getsockopt(fd: BorrowedFd<'_>, level: i32, optname: i32) -> io::Result { - use super::*; - - let mut optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - unsafe { - let mut value = core::mem::zeroed::(); - ret(c::getsockopt( - borrowed_fd(fd), - level, - optname, - as_mut_ptr(&mut value).cast(), - &mut optlen, - ))?; - // On Windows at least, `getsockopt` has been observed writing 1 - // byte on at least (`IPPROTO_TCP`, `TCP_NODELAY`), even though - // Windows' documentation says that should write a 4-byte `BOOL`. - // So, we initialize the memory to zeros above, and just assert - // that `getsockopt` doesn't write too many bytes here. - assert!( - optlen as usize <= size_of::(), - "unexpected getsockopt size" - ); - Ok(value) - } - } - - #[inline] - fn setsockopt( - fd: BorrowedFd<'_>, - level: i32, - optname: i32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - unsafe { - ret(c::setsockopt( - borrowed_fd(fd), - level, - optname, - as_ptr(&value).cast(), - optlen, - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - let mut l_linger = linger.as_secs(); - if linger.subsec_nanos() != 0 { - l_linger = l_linger.checked_add(1).ok_or(io::Errno::INVAL)?; - } - l_linger.try_into().map_err(|_e| io::Errno::INVAL)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: linger.is_some() as _, - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[inline] - pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - 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 - }) - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - #[inline] - pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - let timeout = match timeout { - Some(timeout) => { - if timeout == DURATION_ZERO { - return Err(io::Errno::INVAL); - } - - let tv_sec = timeout.as_secs().try_into(); - #[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] - let tv_sec = tv_sec.unwrap_or(c::c_long::MAX); - #[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] - let tv_sec = tv_sec.unwrap_or(i64::MAX); - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = c::timeval { - tv_sec, - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => c::timeval { - tv_sec: 0, - tv_usec: 0, - }, - }; - - #[cfg(windows)] - let timeout: u32 = match timeout { - Some(timeout) => { - if timeout == DURATION_ZERO { - return Err(io::Errno::INVAL); - } - - // `as_millis` rounds down, so we use `as_nanos` and - // manually round up. - let mut timeout: u32 = ((timeout.as_nanos() + 999_999) / 1_000_000) - .try_into() - .map_err(|_convert_err| io::Errno::INVAL)?; - if timeout == 0 { - timeout = 1; - } - timeout - } - None => 0, - }; - - setsockopt(fd, c::SOL_SOCKET, optname, timeout) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result> { - let optname = match id { - Timeout::Recv => c::SO_RCVTIMEO, - Timeout::Send => c::SO_SNDTIMEO, - }; - - #[cfg(not(windows))] - { - let timeout: c::timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - Ok(None) - } else { - Ok(Some( - Duration::from_secs(timeout.tv_sec as u64) - + Duration::from_micros(timeout.tv_usec as u64), - )) - } - } - - #[cfg(windows)] - { - let timeout: u32 = getsockopt(fd, c::SOL_SOCKET, optname)?; - if timeout == 0 { - Ok(None) - } else { - Ok(Some(Duration::from_millis(timeout as u64))) - } - } - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "haiku", - target_os = "illumos", - target_os = "ios", - target_os = "l4re", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris", - )))] - use c::IPV6_ADD_MEMBERSHIP; - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "haiku", - target_os = "illumos", - target_os = "ios", - target_os = "l4re", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris", - ))] - use c::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "haiku", - target_os = "illumos", - target_os = "ios", - target_os = "l4re", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris", - )))] - use c::IPV6_DROP_MEMBERSHIP; - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "haiku", - target_os = "illumos", - target_os = "ios", - target_os = "l4re", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris", - ))] - use c::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; - - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - in_addr_new(u32::from_ne_bytes(addr.octets())) - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_interface: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - in6_addr_new(multiaddr.octets()) - } - - #[cfg(target_os = "android")] - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[cfg(not(target_os = "android"))] - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_uint { - interface as c::c_uint - } - - // `getsockopt` and `setsockopt` represent boolean values as integers. - #[cfg(not(windows))] - type RawSocketBool = c::c_int; - #[cfg(windows)] - type RawSocketBool = BOOL; - - // Wrap `RawSocketBool` in a newtype to discourage misuse. - #[repr(transparent)] - #[derive(Copy, Clone)] - struct SocketBool(RawSocketBool); - - // Convert from a `bool` to a `SocketBool`. - #[inline] - fn from_bool(value: bool) -> SocketBool { - SocketBool(value as _) - } - - // Convert from a `SocketBool` to a `bool`. - #[inline] - fn to_bool(value: SocketBool) -> bool { - value.0 != 0 - } -} diff --git a/vendor/rustix/src/imp/libc/net/types.rs b/vendor/rustix/src/imp/libc/net/types.rs deleted file mode 100644 index 63e3a317e..000000000 --- a/vendor/rustix/src/imp/libc/net/types.rs +++ /dev/null @@ -1,621 +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 as u32); - - /// `SOCK_DGRAM` - pub const DGRAM: Self = Self(c::SOCK_DGRAM as u32); - - /// `SOCK_SEQPACKET` - pub const SEQPACKET: Self = Self(c::SOCK_SEQPACKET as u32); - - /// `SOCK_RAW` - pub const RAW: Self = Self(c::SOCK_RAW as u32); - - /// `SOCK_RDM` - pub const RDM: Self = Self(c::SOCK_RDM as u32); - - /// 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] -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` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - 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` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - 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` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const NETROM: Self = Self(c::AF_NETROM as _); - /// `AF_BRIDGE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const BRIDGE: Self = Self(c::AF_BRIDGE as _); - /// `AF_ATMPVC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const ATMPVC: Self = Self(c::AF_ATMPVC as _); - /// `AF_X25` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const X25: Self = Self(c::AF_X25 as _); - /// `AF_ROSE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const ROSE: Self = Self(c::AF_ROSE as _); - /// `AF_DECnet` - #[allow(non_upper_case_globals)] - pub const DECnet: Self = Self(c::AF_DECnet as _); - /// `AF_NETBEUI` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const NETBEUI: Self = Self(c::AF_NETBEUI as _); - /// `AF_SECURITY` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const SECURITY: Self = Self(c::AF_SECURITY as _); - /// `AF_KEY` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const KEY: Self = Self(c::AF_KEY as _); - /// `AF_PACKET` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const PACKET: Self = Self(c::AF_PACKET as _); - /// `AF_ASH` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const ASH: Self = Self(c::AF_ASH as _); - /// `AF_ECONET` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const ECONET: Self = Self(c::AF_ECONET as _); - /// `AF_ATMSVC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const ATMSVC: Self = Self(c::AF_ATMSVC as _); - /// `AF_RDS` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const RDS: Self = Self(c::AF_RDS as _); - /// `AF_SNA` - pub const SNA: Self = Self(c::AF_SNA as _); - /// `AF_IRDA` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const IRDA: Self = Self(c::AF_IRDA as _); - /// `AF_PPPOX` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const PPPOX: Self = Self(c::AF_PPPOX as _); - /// `AF_WANPIPE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const WANPIPE: Self = Self(c::AF_WANPIPE as _); - /// `AF_LLC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const LLC: Self = Self(c::AF_LLC as _); - /// `AF_CAN` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const CAN: Self = Self(c::AF_CAN as _); - /// `AF_TIPC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const TIPC: Self = Self(c::AF_TIPC as _); - /// `AF_BLUETOOTH` - #[cfg(not(any(windows, target_os = "illumos", target_os = "ios", target_os = "macos")))] - pub const BLUETOOTH: Self = Self(c::AF_BLUETOOTH as _); - /// `AF_IUCV` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const IUCV: Self = Self(c::AF_IUCV as _); - /// `AF_RXRPC` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const RXRPC: Self = Self(c::AF_RXRPC as _); - /// `AF_ISDN` - #[cfg(not(any(windows, target_os = "illumos")))] - pub const ISDN: Self = Self(c::AF_ISDN as _); - /// `AF_PHONET` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const PHONET: Self = Self(c::AF_PHONET as _); - /// `AF_IEEE802154` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - 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 = i32; - -/// `IPPROTO_*` -#[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` - #[cfg(not(target_os = "illumos"))] - pub const IGMP: Self = Self(c::IPPROTO_IGMP as _); - /// `IPPROTO_IPIP` - #[cfg(not(any(windows, target_os = "illumos")))] - pub const IPIP: Self = Self(c::IPPROTO_IPIP as _); - /// `IPPROTO_TCP` - pub const TCP: Self = Self(c::IPPROTO_TCP as _); - /// `IPPROTO_EGP` - #[cfg(not(target_os = "illumos"))] - pub const EGP: Self = Self(c::IPPROTO_EGP as _); - /// `IPPROTO_PUP` - #[cfg(not(target_os = "illumos"))] - pub const PUP: Self = Self(c::IPPROTO_PUP as _); - /// `IPPROTO_UDP` - pub const UDP: Self = Self(c::IPPROTO_UDP as _); - /// `IPPROTO_IDP` - #[cfg(not(target_os = "illumos"))] - pub const IDP: Self = Self(c::IPPROTO_IDP as _); - /// `IPPROTO_TP` - #[cfg(not(any(windows, target_os = "illumos")))] - pub const TP: Self = Self(c::IPPROTO_TP as _); - /// `IPPROTO_DCCP` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - )))] - pub const DCCP: Self = Self(c::IPPROTO_DCCP as _); - /// `IPPROTO_IPV6` - pub const IPV6: Self = Self(c::IPPROTO_IPV6 as _); - /// `IPPROTO_RSVP` - #[cfg(not(any(windows, target_os = "illumos")))] - pub const RSVP: Self = Self(c::IPPROTO_RSVP as _); - /// `IPPROTO_GRE` - #[cfg(not(any(windows, target_os = "illumos")))] - pub const GRE: Self = Self(c::IPPROTO_GRE as _); - /// `IPPROTO_ESP` - #[cfg(not(target_os = "illumos"))] - pub const ESP: Self = Self(c::IPPROTO_ESP as _); - /// `IPPROTO_AH` - #[cfg(not(target_os = "illumos"))] - pub const AH: Self = Self(c::IPPROTO_AH as _); - /// `IPPROTO_MTP` - #[cfg(not(any( - windows, - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const MTP: Self = Self(c::IPPROTO_MTP as _); - /// `IPPROTO_BEETPH` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const BEETPH: Self = Self(c::IPPROTO_BEETPH as _); - /// `IPPROTO_ENCAP` - #[cfg(not(any(windows, target_os = "illumos")))] - pub const ENCAP: Self = Self(c::IPPROTO_ENCAP as _); - /// `IPPROTO_PIM` - #[cfg(not(target_os = "illumos"))] - pub const PIM: Self = Self(c::IPPROTO_PIM as _); - /// `IPPROTO_COMP` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const COMP: Self = Self(c::IPPROTO_COMP as _); - /// `IPPROTO_SCTP` - #[cfg(not(any(target_os = "dragonfly", target_os = "illumos", target_os = "openbsd")))] - pub const SCTP: Self = Self(c::IPPROTO_SCTP as _); - /// `IPPROTO_UDPLITE` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const UDPLITE: Self = Self(c::IPPROTO_UDPLITE as _); - /// `IPPROTO_MPLS` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - )))] - pub const MPLS: Self = Self(c::IPPROTO_MPLS as _); - /// `IPPROTO_RAW` - pub const RAW: Self = Self(c::IPPROTO_RAW as _); - /// `IPPROTO_MPTCP` - #[cfg(not(any( - windows, - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const MPTCP: Self = Self(c::IPPROTO_MPTCP as _); - /// `IPPROTO_FRAGMENT` - #[cfg(not(target_os = "illumos"))] - pub const FRAGMENT: Self = Self(c::IPPROTO_FRAGMENT as _); - /// `IPPROTO_ICMPV6` - pub const ICMPV6: Self = Self(c::IPPROTO_ICMPV6 as _); - /// `IPPROTO_MH` - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - pub const MH: Self = Self(c::IPPROTO_MH as _); - /// `IPPROTO_ROUTING` - #[cfg(not(target_os = "illumos"))] - 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(i32)] -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 [`accept_with`] and [`acceptfrom_with`]. - /// - /// [`accept_with`]: crate::net::accept_with - /// [`acceptfrom_with`]: crate::net::acceptfrom_with - pub struct AcceptFlags: c::c_int { - /// `SOCK_NONBLOCK` - #[cfg(not(any(windows, target_os = "ios", target_os = "macos")))] - const NONBLOCK = c::SOCK_NONBLOCK; - - /// `SOCK_CLOEXEC` - #[cfg(not(any(windows, target_os = "ios", target_os = "macos")))] - const CLOEXEC = c::SOCK_CLOEXEC; - } -} - -bitflags! { - /// `SOCK_*` constants for use with [`socket`]. - /// - /// [`socket`]: crate::net::socket - pub struct SocketFlags: c::c_int { - /// `SOCK_NONBLOCK` - #[cfg(not(any(windows, target_os = "ios", target_os = "macos")))] - const NONBLOCK = c::SOCK_NONBLOCK; - - /// `SOCK_CLOEXEC` - #[cfg(not(any(windows, target_os = "ios", target_os = "macos")))] - const CLOEXEC = c::SOCK_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(i32)] -pub enum Timeout { - /// `SO_RCVTIMEO`—Timeout for receiving. - Recv = c::SO_RCVTIMEO, - - /// `SO_SNDTIMEO`—Timeout for sending. - Send = c::SO_SNDTIMEO, -} diff --git a/vendor/rustix/src/imp/libc/net/write_sockaddr.rs b/vendor/rustix/src/imp/libc/net/write_sockaddr.rs deleted file mode 100644 index adbf7255d..000000000 --- a/vendor/rustix/src/imp/libc/net/write_sockaddr.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! The BSD sockets API requires us to read the `ss_family` field before -//! we can interpret the rest of a `sockaddr` produced by the kernel. - -use super::super::c; -use super::addr::SocketAddrStorage; -#[cfg(unix)] -use super::addr::SocketAddrUnix; -use super::ext::{in6_addr_new, in_addr_new, sockaddr_in6_new}; -use crate::net::{SocketAddrAny, SocketAddrV4, SocketAddrV6}; -use core::mem::size_of; - -pub(crate) unsafe fn write_sockaddr( - addr: &SocketAddrAny, - storage: *mut SocketAddrStorage, -) -> usize { - match addr { - SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage), - SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage), - #[cfg(unix)] - SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage), - } -} - -pub(crate) unsafe fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { - c::sockaddr_in { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - sin_len: size_of::() as _, - sin_family: c::AF_INET as _, - sin_port: u16::to_be(v4.port()), - sin_addr: in_addr_new(u32::from_ne_bytes(v4.ip().octets())), - sin_zero: [0; 8_usize], - } -} - -unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize { - let encoded = encode_sockaddr_v4(v4); - core::ptr::write(storage.cast(), encoded); - size_of::() -} - -pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { - #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - ))] - { - sockaddr_in6_new( - size_of::() as _, - c::AF_INET6 as _, - u16::to_be(v6.port()), - u32::to_be(v6.flowinfo()), - in6_addr_new(v6.ip().octets()), - v6.scope_id(), - ) - } - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - { - sockaddr_in6_new( - c::AF_INET6 as _, - u16::to_be(v6.port()), - u32::to_be(v6.flowinfo()), - in6_addr_new(v6.ip().octets()), - v6.scope_id(), - ) - } -} - -unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize { - let encoded = encode_sockaddr_v6(v6); - core::ptr::write(storage.cast(), encoded); - size_of::() -} - -#[cfg(unix)] -unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize { - core::ptr::write(storage.cast(), unix.unix); - unix.len() -} diff --git a/vendor/rustix/src/imp/libc/offset.rs b/vendor/rustix/src/imp/libc/offset.rs deleted file mode 100644 index 3002e8bdd..000000000 --- a/vendor/rustix/src/imp/libc/offset.rs +++ /dev/null @@ -1,361 +0,0 @@ -//! Automatically enable “large file” support features. - -#[cfg(not(windows))] -use super::c; - -#[cfg(not(any( - windows, - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -)))] -pub(super) use c::{ - fstat as libc_fstat, fstatat as libc_fstatat, ftruncate as libc_ftruncate, lseek as libc_lseek, - off_t as libc_off_t, -}; - -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -pub(super) use c::{ - fstat64 as libc_fstat, fstatat64 as libc_fstatat, ftruncate64 as libc_ftruncate, - lseek64 as libc_lseek, off64_t as libc_off_t, rlimit64 as libc_rlimit, -}; - -#[cfg(not(any( - windows, - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", - target_os = "wasi", -)))] -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -pub(super) use c::mmap as libc_mmap; - -#[cfg(not(any( - windows, - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "l4re", - target_os = "redox", - target_os = "wasi", -)))] -pub(super) use c::{rlimit as libc_rlimit, RLIM_INFINITY as LIBC_RLIM_INFINITY}; - -#[cfg(not(any( - windows, - target_os = "android", - target_os = "fuchsia", - target_os = "emscripten", - target_os = "l4re", - target_os = "linux", - target_os = "wasi", -)))] -pub(super) use c::{getrlimit as libc_getrlimit, setrlimit as libc_setrlimit}; - -// TODO: Add `RLIM64_INFINITY` to upstream libc. -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -pub(super) const LIBC_RLIM_INFINITY: u64 = !0_u64; - -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -pub(super) use c::{getrlimit64 as libc_getrlimit, setrlimit64 as libc_setrlimit}; - -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -pub(super) use c::mmap64 as libc_mmap; - -// `prlimit64` wasn't supported in glibc until 2.13. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -weak_or_syscall! { - fn prlimit64( - pid: c::pid_t, - resource: c::__rlimit_resource_t, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64 - ) via SYS_prlimit64 -> c::c_int -} -#[cfg(all(target_os = "linux", target_env = "musl"))] -weak_or_syscall! { - fn prlimit64( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64 - ) via SYS_prlimit64 -> c::c_int -} -#[cfg(target_os = "android")] -weak_or_syscall! { - fn prlimit64( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64 - ) via SYS_prlimit64 -> c::c_int -} -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(super) unsafe fn libc_prlimit( - pid: c::pid_t, - resource: c::__rlimit_resource_t, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64, -) -> c::c_int { - prlimit64(pid, resource, new_limit, old_limit) -} -#[cfg(all(target_os = "linux", target_env = "musl"))] -pub(super) unsafe fn libc_prlimit( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64, -) -> c::c_int { - prlimit64(pid, resource, new_limit, old_limit) -} -#[cfg(target_os = "android")] -pub(super) unsafe fn libc_prlimit( - pid: c::pid_t, - resource: c::c_int, - new_limit: *const c::rlimit64, - old_limit: *mut c::rlimit64, -) -> c::c_int { - prlimit64(pid, resource, new_limit, old_limit) -} - -#[cfg(not(any( - windows, - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", - target_os = "redox", -)))] -pub(super) use c::openat as libc_openat; -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -pub(super) use c::openat64 as libc_openat; - -#[cfg(target_os = "fuchsia")] -pub(super) use c::fallocate as libc_fallocate; -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(super) use c::fallocate64 as libc_fallocate; -#[cfg(not(any( - windows, - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "illumos", - target_os = "ios", - target_os = "linux", - target_os = "l4re", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub(super) use c::posix_fadvise as libc_posix_fadvise; -#[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "linux", - target_os = "l4re", -))] -pub(super) use c::posix_fadvise64 as libc_posix_fadvise; - -#[cfg(all(not(any( - windows, - target_os = "android", - target_os = "linux", - target_os = "emscripten", -))))] -pub(super) use c::{pread as libc_pread, pwrite as libc_pwrite}; -#[cfg(any(target_os = "android", target_os = "linux", target_os = "emscripten"))] -pub(super) use c::{pread64 as libc_pread, pwrite64 as libc_pwrite}; -#[cfg(any(target_os = "linux", target_os = "emscripten"))] -pub(super) use c::{preadv64 as libc_preadv, pwritev64 as libc_pwritev}; -#[cfg(target_os = "android")] -mod readwrite_pv64 { - use super::c; - - // 64-bit offsets on 32-bit platforms are passed in endianness-specific - // lo/hi pairs. See src/imp/linux_raw/conv.rs for details. - #[cfg(all(target_endian = "little", target_pointer_width = "32"))] - fn lo(x: u64) -> usize { - (x >> 32) as usize - } - #[cfg(all(target_endian = "little", target_pointer_width = "32"))] - fn hi(x: u64) -> usize { - (x & 0xffff_ffff) as usize - } - #[cfg(all(target_endian = "big", target_pointer_width = "32"))] - fn lo(x: u64) -> usize { - (x & 0xffff_ffff) as usize - } - #[cfg(all(target_endian = "big", target_pointer_width = "32"))] - fn hi(x: u64) -> usize { - (x >> 32) as usize - } - - pub(in super::super) unsafe fn preadv64( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off64_t, - ) -> c::ssize_t { - // Older Android libc lacks `preadv64`, so use the `weak!` mechanism to - // test for it, and call back to `c::syscall`. We don't use - // `weak_or_syscall` here because we need to pass the 64-bit offset - // specially. - weak! { - fn preadv64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t - } - if let Some(fun) = preadv64.get() { - fun(fd, iov, iovcnt, offset) - } else { - #[cfg(target_pointer_width = "32")] - { - c::syscall( - c::SYS_preadv, - fd, - iov, - iovcnt, - hi(offset as u64), - lo(offset as u64), - ) as c::ssize_t - } - #[cfg(target_pointer_width = "64")] - { - c::syscall(c::SYS_preadv, fd, iov, iovcnt, offset) as c::ssize_t - } - } - } - pub(in super::super) unsafe fn pwritev64( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off64_t, - ) -> c::ssize_t { - // See the comments in `preadv64`. - weak! { - fn pwritev64(c::c_int, *const c::iovec, c::c_int, c::off64_t) -> c::ssize_t - } - if let Some(fun) = pwritev64.get() { - fun(fd, iov, iovcnt, offset) - } else { - #[cfg(target_pointer_width = "32")] - { - c::syscall( - c::SYS_pwritev, - fd, - iov, - iovcnt, - hi(offset as u64), - lo(offset as u64), - ) as c::ssize_t - } - #[cfg(target_pointer_width = "64")] - { - c::syscall(c::SYS_pwritev, fd, iov, iovcnt, offset) as c::ssize_t - } - } - } -} -#[cfg(not(any( - windows, - target_os = "android", - target_os = "emscripten", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "redox", -)))] -pub(super) use c::{preadv as libc_preadv, pwritev as libc_pwritev}; -#[cfg(target_os = "android")] -pub(super) use readwrite_pv64::{preadv64 as libc_preadv, pwritev64 as libc_pwritev}; -// macOS added preadv and pwritev in version 11.0 -#[cfg(any(target_os = "ios", target_os = "macos"))] -mod readwrite_pv { - use super::c; - - weakcall! { - pub(in super::super) fn preadv( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, - offset: c::off_t - ) -> c::ssize_t - } - weakcall! { - pub(in super::super) fn pwritev( - fd: c::c_int, - iov: *const c::iovec, - iovcnt: c::c_int, offset: c::off_t - ) -> c::ssize_t - } -} -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(super) use c::{preadv64v2 as libc_preadv2, pwritev64v2 as libc_pwritev2}; -#[cfg(any(target_os = "ios", target_os = "macos"))] -pub(super) use readwrite_pv::{preadv as libc_preadv, pwritev as libc_pwritev}; - -#[cfg(not(any( - windows, - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "linux", - target_os = "l4re", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub(super) use c::posix_fallocate as libc_posix_fallocate; -#[cfg(any(target_os = "l4re"))] -pub(super) use c::posix_fallocate64 as libc_posix_fallocate; -#[cfg(not(any( - windows, - target_os = "android", - target_os = "emscripten", - target_os = "illumos", - target_os = "linux", - target_os = "l4re", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -pub(super) use {c::fstatfs as libc_fstatfs, c::statfs as libc_statfs}; - -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "emscripten", - target_os = "l4re", -))] -pub(super) use {c::fstatfs64 as libc_fstatfs, c::statfs64 as libc_statfs}; diff --git a/vendor/rustix/src/imp/libc/param/auxv.rs b/vendor/rustix/src/imp/libc/param/auxv.rs deleted file mode 100644 index 584329da9..000000000 --- a/vendor/rustix/src/imp/libc/param/auxv.rs +++ /dev/null @@ -1,66 +0,0 @@ -use super::super::c; -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -use crate::ffi::CStr; - -// `getauxval` wasn't supported in glibc until 2.16. -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -weak!(fn getauxval(c::c_ulong) -> *mut c::c_void); - -#[inline] -pub(crate) fn page_size() -> usize { - unsafe { c::sysconf(c::_SC_PAGESIZE) as usize } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn clock_ticks_per_second() -> u64 { - unsafe { c::sysconf(c::_SC_CLK_TCK) as u64 } -} - -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -#[inline] -pub(crate) fn linux_hwcap() -> (usize, usize) { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { - let hwcap = libc_getauxval(c::AT_HWCAP) as usize; - let hwcap2 = libc_getauxval(c::AT_HWCAP2) as usize; - (hwcap, hwcap2) - } - } else { - (0, 0) - } -} - -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -#[inline] -pub(crate) fn linux_execfn() -> &'static CStr { - if let Some(libc_getauxval) = getauxval.get() { - unsafe { CStr::from_ptr(libc_getauxval(c::AT_EXECFN).cast()) } - } else { - cstr!("") - } -} - -/// Initialize process-wide state. -#[cfg(any( - target_vendor = "mustang", - not(any(target_env = "gnu", target_env = "musl")), -))] -#[inline] -#[doc(hidden)] -pub(crate) unsafe fn init(_envp: *mut *mut u8) { - // Nothing to do. This is the libc backend, and libc does the - // initialization for us. -} diff --git a/vendor/rustix/src/imp/libc/param/mod.rs b/vendor/rustix/src/imp/libc/param/mod.rs deleted file mode 100644 index 2cb2fe78a..000000000 --- a/vendor/rustix/src/imp/libc/param/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod auxv; diff --git a/vendor/rustix/src/imp/libc/process/cpu_set.rs b/vendor/rustix/src/imp/libc/process/cpu_set.rs deleted file mode 100644 index 14ad8d208..000000000 --- a/vendor/rustix/src/imp/libc/process/cpu_set.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![allow(non_snake_case)] - -use super::super::c; -use super::types::{RawCpuSet, CPU_SETSIZE}; - -#[inline] -pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { - assert!( - cpu < CPU_SETSIZE, - "cpu out of bounds: the cpu max is {} but the cpu is {}", - CPU_SETSIZE, - cpu - ); - unsafe { c::CPU_SET(cpu, cpuset) } -} - -#[inline] -pub(crate) fn CPU_ZERO(cpuset: &mut RawCpuSet) { - unsafe { c::CPU_ZERO(cpuset) } -} - -#[inline] -pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { - assert!( - cpu < CPU_SETSIZE, - "cpu out of bounds: the cpu max is {} but the cpu is {}", - CPU_SETSIZE, - cpu - ); - unsafe { c::CPU_CLR(cpu, cpuset) } -} - -#[inline] -pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { - assert!( - cpu < CPU_SETSIZE, - "cpu out of bounds: the cpu max is {} but the cpu is {}", - CPU_SETSIZE, - cpu - ); - unsafe { c::CPU_ISSET(cpu, cpuset) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { - use core::convert::TryInto; - unsafe { c::CPU_COUNT(cpuset).try_into().unwrap() } -} diff --git a/vendor/rustix/src/imp/libc/process/mod.rs b/vendor/rustix/src/imp/libc/process/mod.rs deleted file mode 100644 index 8675c1af9..000000000 --- a/vendor/rustix/src/imp/libc/process/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -pub(crate) mod cpu_set; -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; -#[cfg(not(target_os = "wasi"))] -pub(crate) mod wait; diff --git a/vendor/rustix/src/imp/libc/process/syscalls.rs b/vendor/rustix/src/imp/libc/process/syscalls.rs deleted file mode 100644 index 9874f617f..000000000 --- a/vendor/rustix/src/imp/libc/process/syscalls.rs +++ /dev/null @@ -1,419 +0,0 @@ -//! libc syscalls supporting `rustix::process`. - -use super::super::c; -#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] -use super::super::conv::borrowed_fd; -use super::super::conv::{c_str, ret, ret_c_int, ret_discarded_char_ptr}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use super::super::conv::{syscall_ret, syscall_ret_u32}; -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -use super::types::RawCpuSet; -#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] -use crate::fd::BorrowedFd; -use crate::ffi::CStr; -use crate::io; -use core::mem::MaybeUninit; -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -use { - super::super::conv::ret_infallible, - super::super::offset::{libc_getrlimit, libc_rlimit, libc_setrlimit, LIBC_RLIM_INFINITY}, - crate::process::{Resource, Rlimit}, - core::convert::TryInto, -}; -#[cfg(any(target_os = "android", target_os = "linux"))] -use { - super::super::offset::libc_prlimit, - crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}, -}; -#[cfg(not(target_os = "wasi"))] -use { - super::types::RawUname, - crate::process::{Gid, Pid, RawNonZeroPid, RawPid, Signal, Uid, WaitOptions, WaitStatus}, -}; - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn chdir(path: &CStr) -> io::Result<()> { - unsafe { ret(c::chdir(c_str(path))) } -} - -#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] -pub(crate) fn fchdir(dirfd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(c::fchdir(borrowed_fd(dirfd))) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result<()> { - unsafe { ret_discarded_char_ptr(c::getcwd(buf.as_mut_ptr().cast(), buf.len())) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn membarrier_query() -> MembarrierQuery { - // GLIBC does not have a wrapper for `membarrier`; [the documentation] - // says to use `syscall`. - // - // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES - const MEMBARRIER_CMD_QUERY: u32 = 0; - unsafe { - match syscall_ret_u32(c::syscall(c::SYS_membarrier, MEMBARRIER_CMD_QUERY, 0)) { - Ok(query) => MembarrierQuery::from_bits_unchecked(query), - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { syscall_ret(c::syscall(c::SYS_membarrier, cmd as u32, 0)) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; - unsafe { - syscall_ret(c::syscall( - c::SYS_membarrier, - cmd as u32, - MEMBARRIER_CMD_FLAG_CPU, - cpu.as_raw(), - )) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getuid() -> Uid { - unsafe { - let uid = c::getuid(); - Uid::from_raw(uid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn geteuid() -> Uid { - unsafe { - let uid = c::geteuid(); - Uid::from_raw(uid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getgid() -> Gid { - unsafe { - let gid = c::getgid(); - Gid::from_raw(gid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getegid() -> Gid { - unsafe { - let gid = c::getegid(); - Gid::from_raw(gid) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getpid() -> Pid { - unsafe { - let pid = c::getpid(); - debug_assert_ne!(pid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid)) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn getppid() -> Option { - unsafe { - let pid: i32 = c::getppid(); - Pid::from_raw(pid) - } -} - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -#[inline] -pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - ret(c::sched_getaffinity( - Pid::as_raw(pid) as _, - core::mem::size_of::(), - cpuset, - )) - } -} - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -#[inline] -pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(c::sched_setaffinity( - Pid::as_raw(pid) as _, - core::mem::size_of::(), - cpuset, - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - let _ = c::sched_yield(); - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::::uninit(); - unsafe { - ret(c::uname(uname.as_mut_ptr())).unwrap(); - uname.assume_init() - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -#[inline] -pub(crate) fn nice(inc: i32) -> io::Result { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::nice(inc) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn getpriority_user(uid: Uid) -> io::Result { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::getpriority(c::PRIO_USER, uid.as_raw() as _) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn getpriority_pgrp(pgid: Option) -> io::Result { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::getpriority(c::PRIO_PGRP, Pid::as_raw(pgid) as _) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn getpriority_process(pid: Option) -> io::Result { - libc_errno::set_errno(libc_errno::Errno(0)); - let r = unsafe { c::getpriority(c::PRIO_PROCESS, Pid::as_raw(pid) as _) }; - if libc_errno::errno().0 != 0 { - ret_c_int(r) - } else { - Ok(r) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - unsafe { ret(c::setpriority(c::PRIO_USER, uid.as_raw() as _, priority)) } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { - unsafe { - ret(c::setpriority( - c::PRIO_PGRP, - Pid::as_raw(pgid) as _, - priority, - )) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { - unsafe { - ret(c::setpriority( - c::PRIO_PROCESS, - Pid::as_raw(pid) as _, - priority, - )) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn getrlimit(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::::uninit(); - unsafe { - ret_infallible(libc_getrlimit(limit as _, result.as_mut_ptr())); - rlimit_from_libc(result.assume_init()) - } -} - -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { - let lim = rlimit_to_libc(new)?; - unsafe { ret(libc_setrlimit(limit as _, &lim)) } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -pub(crate) fn prlimit(pid: Option, limit: Resource, new: Rlimit) -> io::Result { - let lim = rlimit_to_libc(new)?; - let mut result = MaybeUninit::::uninit(); - unsafe { - ret(libc_prlimit( - Pid::as_raw(pid), - limit as _, - &lim, - result.as_mut_ptr(), - )) - .map(|()| rlimit_from_libc(result.assume_init())) - } -} - -/// Convert a Rust [`Rlimit`] to a C `libc_rlimit`. -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -fn rlimit_from_libc(lim: libc_rlimit) -> Rlimit { - let current = if lim.rlim_cur == LIBC_RLIM_INFINITY { - None - } else { - Some(lim.rlim_cur.try_into().unwrap()) - }; - let maximum = if lim.rlim_max == LIBC_RLIM_INFINITY { - None - } else { - Some(lim.rlim_max.try_into().unwrap()) - }; - Rlimit { current, maximum } -} - -/// Convert a C `libc_rlimit` to a Rust `Rlimit`. -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -fn rlimit_to_libc(lim: Rlimit) -> io::Result { - let Rlimit { current, maximum } = lim; - let rlim_cur = match current { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => LIBC_RLIM_INFINITY as _, - }; - let rlim_max = match maximum { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => LIBC_RLIM_INFINITY as _, - }; - Ok(libc_rlimit { rlim_cur, rlim_max }) -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn wait(waitopts: WaitOptions) -> io::Result> { - _waitpid(!0, waitopts) -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn waitpid( - pid: Option, - waitopts: WaitOptions, -) -> io::Result> { - _waitpid(Pid::as_raw(pid), waitopts) -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn _waitpid( - pid: RawPid, - waitopts: WaitOptions, -) -> io::Result> { - unsafe { - let mut status: c::c_int = 0; - let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?; - Ok(RawNonZeroPid::new(pid).map(|non_zero| { - ( - Pid::from_raw_nonzero(non_zero), - WaitStatus::new(status as _), - ) - })) - } -} - -#[inline] -pub(crate) fn exit_group(code: c::c_int) -> ! { - // `_exit` and `_Exit` are the same; it's just a matter of which ones - // the libc bindings expose. - #[cfg(any(target_os = "wasi", target_os = "solid"))] - unsafe { - c::_Exit(code) - } - #[cfg(unix)] - unsafe { - c::_exit(code) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn setsid() -> io::Result { - unsafe { - let pid = ret_c_int(c::setsid())?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(c::kill(pid.as_raw_nonzero().get(), sig as i32)) } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { - ret(c::kill( - pid.as_raw_nonzero().get().wrapping_neg(), - sig as i32, - )) - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { - unsafe { ret(c::kill(0, sig as i32)) } -} diff --git a/vendor/rustix/src/imp/libc/process/types.rs b/vendor/rustix/src/imp/libc/process/types.rs deleted file mode 100644 index 60d629d81..000000000 --- a/vendor/rustix/src/imp/libc/process/types.rs +++ /dev/null @@ -1,361 +0,0 @@ -use super::super::c; - -/// A command for use with [`membarrier`] and [`membarrier_cpu`]. -/// -/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. -/// -/// [`membarrier`]: crate::process::membarrier -/// [`membarrier_cpu`]: crate::process::membarrier_cpu -/// [`membarrier_query`]: crate::process::membarrier_query -// TODO: These are not yet exposed through libc, so we define the -// constants ourselves. -#[cfg(any(target_os = "android", target_os = "linux"))] -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[repr(u32)] -pub enum MembarrierCommand { - /// `MEMBARRIER_CMD_GLOBAL` - #[doc(alias = "Shared")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - Global = 1, - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - GlobalExpedited = 2, - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - RegisterGlobalExpedited = 4, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - PrivateExpedited = 8, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - RegisterPrivateExpedited = 16, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - PrivateExpeditedSyncCore = 32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - RegisterPrivateExpeditedSyncCore = 64, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - PrivateExpeditedRseq = 128, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - RegisterPrivateExpeditedRseq = 256, -} - -/// A resource value for use with [`getrlimit`], [`setrlimit`], and -/// [`prlimit`]. -/// -/// [`getrlimit`]: crate::process::getrlimit -/// [`setrlimit`]: crate::process::setrlimit -/// [`prlimit`]: crate::process::prlimit -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum Resource { - /// `RLIMIT_CPU` - Cpu = c::RLIMIT_CPU as c::c_int, - /// `RLIMIT_FSIZE` - Fsize = c::RLIMIT_FSIZE as c::c_int, - /// `RLIMIT_DATA` - Data = c::RLIMIT_DATA as c::c_int, - /// `RLIMIT_STACK` - Stack = c::RLIMIT_STACK as c::c_int, - /// `RLIMIT_CORE` - Core = c::RLIMIT_CORE as c::c_int, - /// `RLIMIT_RSS` - #[cfg(not(any(target_os = "illumos", target_os = "ios", target_os = "macos")))] - Rss = c::RLIMIT_RSS as c::c_int, - /// `RLIMIT_NPROC` - #[cfg(not(target_os = "illumos"))] - Nproc = c::RLIMIT_NPROC as c::c_int, - /// `RLIMIT_NOFILE` - Nofile = c::RLIMIT_NOFILE as c::c_int, - /// `RLIMIT_MEMLOCK` - #[cfg(not(target_os = "illumos"))] - Memlock = c::RLIMIT_MEMLOCK as c::c_int, - /// `RLIMIT_AS` - #[cfg(not(target_os = "openbsd"))] - As = c::RLIMIT_AS as c::c_int, - /// `RLIMIT_LOCKS` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - Locks = c::RLIMIT_LOCKS as c::c_int, - /// `RLIMIT_SIGPENDING` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - Sigpending = c::RLIMIT_SIGPENDING as c::c_int, - /// `RLIMIT_MSGQUEUE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - Msgqueue = c::RLIMIT_MSGQUEUE as c::c_int, - /// `RLIMIT_NICE` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - Nice = c::RLIMIT_NICE as c::c_int, - /// `RLIMIT_RTPRIO` - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - Rtprio = c::RLIMIT_RTPRIO as c::c_int, - /// `RLIMIT_RTTIME` - #[cfg(not(any( - target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - Rttime = c::RLIMIT_RTTIME as c::c_int, -} - -#[cfg(any(target_os = "ios", target_os = "macos"))] -impl Resource { - /// `RLIMIT_RSS` - #[allow(non_upper_case_globals)] - pub const Rss: Self = Self::As; -} - -/// 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 -#[cfg(not(target_os = "wasi"))] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum Signal { - /// `SIGHUP` - Hup = c::SIGHUP, - /// `SIGINT` - Int = c::SIGINT, - /// `SIGQUIT` - Quit = c::SIGQUIT, - /// `SIGILL` - Ill = c::SIGILL, - /// `SIGTRAP` - Trap = c::SIGTRAP, - /// `SIGABRT`, aka `SIGIOT` - #[doc(alias = "Iot")] - #[doc(alias = "Abrt")] - Abort = c::SIGABRT, - /// `SIGBUS` - Bus = c::SIGBUS, - /// `SIGFPE` - Fpe = c::SIGFPE, - /// `SIGKILL` - Kill = c::SIGKILL, - /// `SIGUSR1` - Usr1 = c::SIGUSR1, - /// `SIGSEGV` - Segv = c::SIGSEGV, - /// `SIGUSR2` - Usr2 = c::SIGUSR2, - /// `SIGPIPE` - Pipe = c::SIGPIPE, - /// `SIGALRM` - #[doc(alias = "Alrm")] - Alarm = c::SIGALRM, - /// `SIGTERM` - Term = c::SIGTERM, - /// `SIGSTKFLT` - #[cfg(not(any( - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - all( - any(target_os = "android", target_os = "linux"), - any(target_arch = "mips", target_arch = "mips64"), - ) - )))] - Stkflt = c::SIGSTKFLT, - /// `SIGCHLD` - #[doc(alias = "Chld")] - Child = c::SIGCHLD, - /// `SIGCONT` - Cont = c::SIGCONT, - /// `SIGSTOP` - Stop = c::SIGSTOP, - /// `SIGTSTP` - Tstp = c::SIGTSTP, - /// `SIGTTIN` - Ttin = c::SIGTTIN, - /// `SIGTTOU` - Ttou = c::SIGTTOU, - /// `SIGURG` - Urg = c::SIGURG, - /// `SIGXCPU` - Xcpu = c::SIGXCPU, - /// `SIGXFSZ` - Xfsz = c::SIGXFSZ, - /// `SIGVTALRM` - #[doc(alias = "Vtalrm")] - Vtalarm = c::SIGVTALRM, - /// `SIGPROF` - Prof = c::SIGPROF, - /// `SIGWINCH` - Winch = c::SIGWINCH, - /// `SIGIO`, aka `SIGPOLL` - #[doc(alias = "Poll")] - Io = c::SIGIO, - /// `SIGPWR` - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - #[doc(alias = "Pwr")] - Power = c::SIGPWR, - /// `SIGSYS`, aka `SIGUNUSED` - #[doc(alias = "Unused")] - Sys = c::SIGSYS, -} - -#[cfg(not(target_os = "wasi"))] -impl Signal { - /// Convert a raw signal number into a `Signal`, if possible. - pub fn from_raw(sig: i32) -> Option { - match sig as _ { - c::SIGHUP => Some(Self::Hup), - c::SIGINT => Some(Self::Int), - c::SIGQUIT => Some(Self::Quit), - c::SIGILL => Some(Self::Ill), - c::SIGTRAP => Some(Self::Trap), - c::SIGABRT => Some(Self::Abort), - c::SIGBUS => Some(Self::Bus), - c::SIGFPE => Some(Self::Fpe), - c::SIGKILL => Some(Self::Kill), - c::SIGUSR1 => Some(Self::Usr1), - c::SIGSEGV => Some(Self::Segv), - c::SIGUSR2 => Some(Self::Usr2), - c::SIGPIPE => Some(Self::Pipe), - c::SIGALRM => Some(Self::Alarm), - c::SIGTERM => Some(Self::Term), - #[cfg(not(any( - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - all( - any(target_os = "android", target_os = "linux"), - any(target_arch = "mips", target_arch = "mips64"), - ) - )))] - c::SIGSTKFLT => Some(Self::Stkflt), - c::SIGCHLD => Some(Self::Child), - c::SIGCONT => Some(Self::Cont), - c::SIGSTOP => Some(Self::Stop), - c::SIGTSTP => Some(Self::Tstp), - c::SIGTTIN => Some(Self::Ttin), - c::SIGTTOU => Some(Self::Ttou), - c::SIGURG => Some(Self::Urg), - c::SIGXCPU => Some(Self::Xcpu), - c::SIGXFSZ => Some(Self::Xfsz), - c::SIGVTALRM => Some(Self::Vtalarm), - c::SIGPROF => Some(Self::Prof), - c::SIGWINCH => Some(Self::Winch), - c::SIGIO => Some(Self::Io), - #[cfg(not(any( - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - c::SIGPWR => Some(Self::Power), - c::SIGSYS => Some(Self::Sys), - _ => None, - } - } -} - -pub const EXIT_SUCCESS: c::c_int = c::EXIT_SUCCESS; -pub const EXIT_FAILURE: c::c_int = c::EXIT_FAILURE; -#[cfg(not(target_os = "wasi"))] -pub const EXIT_SIGNALED_SIGABRT: c::c_int = 128 + c::SIGABRT; - -/// A process identifier as a raw integer. -#[cfg(not(target_os = "wasi"))] -pub type RawPid = c::pid_t; -/// A non-zero process identifier as a raw non-zero integer. -#[cfg(not(target_os = "wasi"))] -pub type RawNonZeroPid = core::num::NonZeroI32; -/// A group identifier as a raw integer. -#[cfg(not(target_os = "wasi"))] -pub type RawGid = c::gid_t; -/// A user identifier as a raw integer. -#[cfg(not(target_os = "wasi"))] -pub type RawUid = c::uid_t; -/// A CPU identifier as a raw integer. -#[cfg(any(target_os = "android", target_os = "linux"))] -pub type RawCpuid = u32; - -#[cfg(not(target_os = "wasi"))] -pub(crate) type RawUname = c::utsname; - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -pub(crate) type RawCpuSet = c::cpu_set_t; - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -#[inline] -pub(crate) fn raw_cpu_set_new() -> RawCpuSet { - let mut set = unsafe { core::mem::zeroed() }; - super::cpu_set::CPU_ZERO(&mut set); - set -} - -#[cfg(any( - target_os = "android", - target_os = "dragonfly", - target_os = "fuchsia", - target_os = "linux", -))] -pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; diff --git a/vendor/rustix/src/imp/libc/process/wait.rs b/vendor/rustix/src/imp/libc/process/wait.rs deleted file mode 100644 index 6de79955d..000000000 --- a/vendor/rustix/src/imp/libc/process/wait.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::super::c; - -pub(crate) use c::{ - WCONTINUED, WEXITSTATUS, WIFCONTINUED, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, - WTERMSIG, WUNTRACED, -}; diff --git a/vendor/rustix/src/imp/libc/rand/mod.rs b/vendor/rustix/src/imp/libc/rand/mod.rs deleted file mode 100644 index 1e0181a99..000000000 --- a/vendor/rustix/src/imp/libc/rand/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/libc/rand/syscalls.rs b/vendor/rustix/src/imp/libc/rand/syscalls.rs deleted file mode 100644 index 1c4286235..000000000 --- a/vendor/rustix/src/imp/libc/rand/syscalls.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! libc syscalls supporting `rustix::rand`. - -#[cfg(target_os = "linux")] -use {super::super::c, super::super::conv::ret_ssize_t, crate::io, crate::rand::GetRandomFlags}; - -#[cfg(target_os = "linux")] -pub(crate) fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result { - // `getrandom` wasn't supported in glibc until 2.25. - weak_or_syscall! { - fn getrandom(buf: *mut c::c_void, buflen: c::size_t, flags: c::c_uint) via SYS_getrandom -> c::ssize_t - } - - let nread = - unsafe { ret_ssize_t(getrandom(buf.as_mut_ptr().cast(), buf.len(), flags.bits()))? }; - Ok(nread as usize) -} diff --git a/vendor/rustix/src/imp/libc/rand/types.rs b/vendor/rustix/src/imp/libc/rand/types.rs deleted file mode 100644 index 2ba3f1119..000000000 --- a/vendor/rustix/src/imp/libc/rand/types.rs +++ /dev/null @@ -1,19 +0,0 @@ -#[cfg(target_os = "linux")] -use super::super::c; -#[cfg(target_os = "linux")] -use bitflags::bitflags; - -#[cfg(target_os = "linux")] -bitflags! { - /// `GRND_*` flags for use with [`getrandom`]. - /// - /// [`getrandom`]: crate::rand::getrandom - pub struct GetRandomFlags: u32 { - /// `GRND_RANDOM` - const RANDOM = c::GRND_RANDOM; - /// `GRND_NONBLOCK` - const NONBLOCK = c::GRND_NONBLOCK; - /// `GRND_INSECURE` - const INSECURE = c::GRND_INSECURE; - } -} diff --git a/vendor/rustix/src/imp/libc/termios/mod.rs b/vendor/rustix/src/imp/libc/termios/mod.rs deleted file mode 100644 index 1e0181a99..000000000 --- a/vendor/rustix/src/imp/libc/termios/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/libc/termios/syscalls.rs b/vendor/rustix/src/imp/libc/termios/syscalls.rs deleted file mode 100644 index 91b01b4a1..000000000 --- a/vendor/rustix/src/imp/libc/termios/syscalls.rs +++ /dev/null @@ -1,159 +0,0 @@ -//! libc syscalls supporting `rustix::termios`. -//! -//! # Safety -//! -//! See the `rustix::imp::syscalls` module documentation for details. - -#![allow(unsafe_code)] - -use super::super::c; -use super::super::conv::{borrowed_fd, ret, ret_pid_t}; -use crate::fd::BorrowedFd; -#[cfg(feature = "procfs")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -use crate::ffi::CStr; -use crate::io; -use crate::process::{Pid, RawNonZeroPid}; -use crate::termios::{Action, OptionalActions, QueueSelector, Speed, Termios, Winsize}; -use core::mem::MaybeUninit; -use libc_errno::errno; - -pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result { - let mut result = MaybeUninit::::uninit(); - unsafe { - ret(c::tcgetattr(borrowed_fd(fd), result.as_mut_ptr())).map(|()| result.assume_init()) - } -} - -pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - let pid = ret_pid_t(c::tcgetpgrp(borrowed_fd(fd)))?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) - } -} - -pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { - unsafe { ret(c::tcsetpgrp(borrowed_fd(fd), pid.as_raw_nonzero().get())) } -} - -pub(crate) fn tcsetattr( - fd: BorrowedFd, - optional_actions: OptionalActions, - termios: &Termios, -) -> io::Result<()> { - unsafe { - ret(c::tcsetattr( - borrowed_fd(fd), - optional_actions as _, - termios, - )) - } -} - -pub(crate) fn tcsendbreak(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(c::tcsendbreak(borrowed_fd(fd), 0)) } -} - -pub(crate) fn tcdrain(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(c::tcdrain(borrowed_fd(fd))) } -} - -pub(crate) fn tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()> { - unsafe { ret(c::tcflush(borrowed_fd(fd), queue_selector as _)) } -} - -pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { - unsafe { ret(c::tcflow(borrowed_fd(fd), action as _)) } -} - -pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result { - unsafe { - let pid = ret_pid_t(c::tcgetsid(borrowed_fd(fd)))?; - debug_assert_ne!(pid, 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid))) - } -} - -pub(crate) fn tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()> { - unsafe { ret(c::ioctl(borrowed_fd(fd), c::TIOCSWINSZ, &winsize)) } -} - -pub(crate) fn tcgetwinsize(fd: BorrowedFd) -> io::Result { - unsafe { - let mut buf = MaybeUninit::::uninit(); - ret(c::ioctl( - borrowed_fd(fd), - c::TIOCGWINSZ.into(), - buf.as_mut_ptr(), - ))?; - Ok(buf.assume_init()) - } -} - -#[inline] -#[must_use] -pub(crate) fn cfgetospeed(termios: &Termios) -> Speed { - unsafe { c::cfgetospeed(termios) } -} - -#[inline] -#[must_use] -pub(crate) fn cfgetispeed(termios: &Termios) -> Speed { - unsafe { c::cfgetispeed(termios) } -} - -#[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - unsafe { c::cfmakeraw(termios) } -} - -#[inline] -pub(crate) fn cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - unsafe { ret(c::cfsetospeed(termios, speed)) } -} - -#[inline] -pub(crate) fn cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - unsafe { ret(c::cfsetispeed(termios, speed)) } -} - -#[inline] -pub(crate) fn cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - unsafe { ret(c::cfsetspeed(termios, speed)) } -} - -pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { - let res = unsafe { c::isatty(borrowed_fd(fd)) }; - if res == 0 { - match errno().0 { - #[cfg(not(any(target_os = "android", target_os = "linux")))] - c::ENOTTY => false, - - // Old Linux versions reportedly return `EINVAL`. - // - #[cfg(any(target_os = "android", target_os = "linux"))] - c::ENOTTY | c::EINVAL => false, - - // Darwin mysteriously returns `EOPNOTSUPP` sometimes. - #[cfg(any(target_os = "ios", target_os = "macos"))] - c::EOPNOTSUPP => false, - - err => panic!("unexpected error from isatty: {:?}", err), - } - } else { - true - } -} - -#[cfg(feature = "procfs")] -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -pub(crate) fn ttyname(dirfd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { - unsafe { - // `ttyname_r` returns its error status rather than using `errno`. - match c::ttyname_r(borrowed_fd(dirfd), buf.as_mut_ptr().cast(), buf.len()) { - 0 => Ok(CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len()), - err => Err(io::Errno::from_raw_os_error(err)), - } - } -} diff --git a/vendor/rustix/src/imp/libc/termios/types.rs b/vendor/rustix/src/imp/libc/termios/types.rs deleted file mode 100644 index 7e6728755..000000000 --- a/vendor/rustix/src/imp/libc/termios/types.rs +++ /dev/null @@ -1,951 +0,0 @@ -use super::super::c; - -/// `TCSA*` values for use with [`tcsetattr`]. -/// -/// [`tcsetattr`]: crate::termios::tcsetattr -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum OptionalActions { - /// `TCSANOW`—Make the change immediately. - Now = c::TCSANOW, - - /// `TCSADRAIN`—Make the change after all output has been transmitted. - Drain = c::TCSADRAIN, - - /// `TCSAFLUSH`—Discard any pending input and then make the change - /// after all output has been transmitted. - Flush = c::TCSAFLUSH, -} - -/// `TC*` values for use with [`tcflush`]. -/// -/// [`tcflush`]: crate::termios::tcflush -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum QueueSelector { - /// `TCIFLUSH`—Flush data received but not read. - IFlush = c::TCIFLUSH, - - /// `TCOFLUSH`—Flush data written but not transmitted. - OFlush = c::TCOFLUSH, - - /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. - IOFlush = c::TCIOFLUSH, -} - -/// `TC*` values for use with [`tcflow`]. -/// -/// [`tcflow`]: crate::termios::tcflow -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] -#[repr(i32)] -pub enum Action { - /// `TCOOFF`—Suspend output. - OOff = c::TCOOFF, - - /// `TCOON`—Restart suspended output. - OOn = c::TCOON, - - /// `TCIOFF`—Transmits a STOP byte. - IOff = c::TCIOFF, - - /// `TCION`—Transmits a START byte. - IOn = c::TCION, -} - -/// `struct termios` for use with [`tcgetattr`]. -/// -/// [`tcgetattr`]: crate::termios::tcgetattr -pub type Termios = c::termios; - -/// `struct winsize` for use with [`tcgetwinsize`]. -/// -/// [`tcgetwinsize`]: crate::termios::tcgetwinsize -pub type Winsize = c::winsize; - -/// `tcflag_t`—A type for the flags fields of [`Termios`]. -pub type Tcflag = c::tcflag_t; - -/// `speed_t`—A return type for [`cfsetspeed`] and similar. -/// -/// [`cfsetspeed`]: crate::termios::cfsetspeed -pub type Speed = c::speed_t; - -/// `VINTR` -pub const VINTR: usize = c::VINTR as usize; - -/// `VQUIT` -pub const VQUIT: usize = c::VQUIT as usize; - -/// `VERASE` -pub const VERASE: usize = c::VERASE as usize; - -/// `VKILL` -pub const VKILL: usize = c::VKILL as usize; - -/// `VEOF` -pub const VEOF: usize = c::VEOF as usize; - -/// `VTIME` -pub const VTIME: usize = c::VTIME as usize; - -/// `VMIN` -pub const VMIN: usize = c::VMIN as usize; - -/// `VSWTC` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const VSWTC: usize = c::VSWTC as usize; - -/// `VSTART` -pub const VSTART: usize = c::VSTART as usize; - -/// `VSTOP` -pub const VSTOP: usize = c::VSTOP as usize; - -/// `VSUSP` -pub const VSUSP: usize = c::VSUSP as usize; - -/// `VEOL` -pub const VEOL: usize = c::VEOL as usize; - -/// `VREPRINT` -pub const VREPRINT: usize = c::VREPRINT as usize; - -/// `VDISCARD` -pub const VDISCARD: usize = c::VDISCARD as usize; - -/// `VWERASE` -pub const VWERASE: usize = c::VWERASE as usize; - -/// `VLNEXT` -pub const VLNEXT: usize = c::VLNEXT as usize; - -/// `VEOL2` -pub const VEOL2: usize = c::VEOL2 as usize; - -/// `IGNBRK` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const IGNBRK: c::c_uint = c::IGNBRK; - -/// `BRKINT` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const BRKINT: c::c_uint = c::BRKINT; - -/// `IGNPAR` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const IGNPAR: c::c_uint = c::IGNPAR; - -/// `PARMRK` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const PARMRK: c::c_uint = c::PARMRK; - -/// `INPCK` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const INPCK: c::c_uint = c::INPCK; - -/// `ISTRIP` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ISTRIP: c::c_uint = c::ISTRIP; - -/// `INLCR` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const INLCR: c::c_uint = c::INLCR; - -/// `IGNCR` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const IGNCR: c::c_uint = c::IGNCR; - -/// `ICRNL` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ICRNL: c::c_uint = c::ICRNL; - -/// `IUCLC` -#[cfg(any(target_os = "haiku", target_os = "illumos", target_os = "solaris"))] -pub const IUCLC: c::c_uint = c::IUCLC; - -/// `IXON` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const IXON: c::c_uint = c::IXON; - -/// `IXANY` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const IXANY: c::c_uint = c::IXANY; - -/// `IXOFF` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const IXOFF: c::c_uint = c::IXOFF; - -/// `IMAXBEL` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const IMAXBEL: c::c_uint = c::IMAXBEL; - -/// `IUTF8` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const IUTF8: c::c_uint = c::IUTF8; - -/// `OPOST` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const OPOST: c::c_uint = c::OPOST; - -/// `OLCUC` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "redox", -)))] -pub const OLCUC: c::c_uint = c::OLCUC; - -/// `ONLCR` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ONLCR: c::c_uint = c::ONLCR; - -/// `OCRNL` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const OCRNL: c::c_uint = c::OCRNL; - -/// `ONOCR` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ONOCR: c::c_uint = c::ONOCR; - -/// `ONLRET` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ONLRET: c::c_uint = c::ONLRET; - -/// `OFILL` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const OFILL: c::c_uint = c::OFILL; - -/// `OFDEL` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const OFDEL: c::c_uint = c::OFDEL; - -/// `NLDLY` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const NLDLY: c::c_uint = c::NLDLY; - -/// `NL0` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const NL0: c::c_uint = c::NL0; - -/// `NL1` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const NL1: c::c_uint = c::NL1; - -/// `CRDLY` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CRDLY: c::c_uint = c::CRDLY; - -/// `CR0` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CR0: c::c_uint = c::CR0; - -/// `CR1` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CR1: c::c_uint = c::CR1; - -/// `CR2` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CR2: c::c_uint = c::CR2; - -/// `CR3` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CR3: c::c_uint = c::CR3; - -/// `TABDLY` -#[cfg(not(any( - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "illumos", - target_os = "redox", -)))] -pub const TABDLY: c::c_uint = c::TABDLY; - -/// `TAB0` -#[cfg(not(any( - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const TAB0: c::c_uint = c::TAB0; - -/// `TAB1` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const TAB1: c::c_uint = c::TAB1; - -/// `TAB2` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const TAB2: c::c_uint = c::TAB2; - -/// `TAB3` -#[cfg(not(any( - target_env = "musl", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const TAB3: c::c_uint = c::TAB3; - -/// `BSDLY` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const BSDLY: c::c_uint = c::BSDLY; - -/// `BS0` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const BS0: c::c_uint = c::BS0; - -/// `BS1` -#[cfg(not(any( - target_env = "musl", - target_os = "emscripten", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const BS1: c::c_uint = c::BS1; - -/// `FFDLY` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const FFDLY: c::c_uint = c::FFDLY; - -/// `FF0` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const FF0: c::c_uint = c::FF0; - -/// `FF1` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const FF1: c::c_uint = c::FF1; - -/// `VTDLY` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const VTDLY: c::c_uint = c::VTDLY; - -/// `VT0` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const VT0: c::c_uint = c::VT0; - -/// `VT1` -#[cfg(not(any( - target_env = "musl", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const VT1: c::c_uint = c::VT1; - -/// `B0` -pub const B0: Speed = c::B0; - -/// `B50` -pub const B50: Speed = c::B50; - -/// `B75` -pub const B75: Speed = c::B75; - -/// `B110` -pub const B110: Speed = c::B110; - -/// `B134` -pub const B134: Speed = c::B134; - -/// `B150` -pub const B150: Speed = c::B150; - -/// `B200` -pub const B200: Speed = c::B200; - -/// `B300` -pub const B300: Speed = c::B300; - -/// `B600` -pub const B600: Speed = c::B600; - -/// `B1200` -pub const B1200: Speed = c::B1200; - -/// `B1800` -pub const B1800: Speed = c::B1800; - -/// `B2400` -pub const B2400: Speed = c::B2400; - -/// `B4800` -pub const B4800: Speed = c::B4800; - -/// `B9600` -pub const B9600: Speed = c::B9600; - -/// `B19200` -pub const B19200: Speed = c::B19200; - -/// `B38400` -pub const B38400: Speed = c::B38400; - -/// `B57600` -pub const B57600: Speed = c::B57600; - -/// `B115200` -pub const B115200: Speed = c::B115200; - -/// `B230400` -pub const B230400: Speed = c::B230400; - -/// `B460800` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] -pub const B460800: Speed = c::B460800; - -/// `B500000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B500000: Speed = c::B500000; - -/// `B576000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B576000: Speed = c::B576000; - -/// `B921600` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] -pub const B921600: Speed = c::B921600; - -/// `B1000000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B1000000: Speed = c::B1000000; - -/// `B1152000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B1152000: Speed = c::B1152000; - -/// `B1500000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B1500000: Speed = c::B1500000; - -/// `B2000000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B2000000: Speed = c::B2000000; - -/// `B2500000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B2500000: Speed = c::B2500000; - -/// `B3000000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B3000000: Speed = c::B3000000; - -/// `B3500000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B3500000: Speed = c::B3500000; - -/// `B4000000` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", -)))] -pub const B4000000: Speed = c::B4000000; - -/// `CSIZE` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CSIZE: c::c_uint = c::CSIZE; - -/// `CS5` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CS5: c::c_uint = c::CS5; - -/// `CS6` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CS6: c::c_uint = c::CS6; - -/// `CS7` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CS7: c::c_uint = c::CS7; - -/// `CS8` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CS8: c::c_uint = c::CS8; - -/// `CSTOPB` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CSTOPB: c::c_uint = c::CSTOPB; - -/// `CREAD` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CREAD: c::c_uint = c::CREAD; - -/// `PARENB` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const PARENB: c::c_uint = c::PARENB; - -/// `PARODD` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const PARODD: c::c_uint = c::PARODD; - -/// `HUPCL` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const HUPCL: c::c_uint = c::HUPCL; - -/// `CLOCAL` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const CLOCAL: c::c_uint = c::CLOCAL; - -/// `ISIG` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ISIG: c::c_uint = c::ISIG; - -/// `ICANON`—A flag for the `c_lflag` field of [`Termios`] indicating -/// canonical mode. -pub const ICANON: Tcflag = c::ICANON; - -/// `ECHO` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ECHO: c::c_uint = c::ECHO; - -/// `ECHOE` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ECHOE: c::c_uint = c::ECHOE; - -/// `ECHOK` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ECHOK: c::c_uint = c::ECHOK; - -/// `ECHONL` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const ECHONL: c::c_uint = c::ECHONL; - -/// `NOFLSH` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const NOFLSH: c::c_uint = c::NOFLSH; - -/// `TOSTOP` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const TOSTOP: c::c_uint = c::TOSTOP; - -/// `IEXTEN` -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub const IEXTEN: c::c_uint = c::IEXTEN; - -/// `EXTA` -#[cfg(not(any( - target_os = "emscripten", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "redox", -)))] -pub const EXTA: c::c_uint = c::EXTA; - -/// `EXTB` -#[cfg(not(any( - target_os = "emscripten", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "redox", -)))] -pub const EXTB: c::c_uint = c::EXTB; - -/// `CBAUD` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CBAUD: c::c_uint = c::CBAUD; - -/// `CBAUDEX` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CBAUDEX: c::c_uint = c::CBAUDEX; - -/// `CIBAUD` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_arch = "powerpc", - target_arch = "powerpc64", -)))] -pub const CIBAUD: c::tcflag_t = c::CIBAUD; - -/// `CIBAUD` -// TODO: Upstream this. -#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] -pub const CIBAUD: c::tcflag_t = 0o77600000; - -/// `CMSPAR` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const CMSPAR: c::c_uint = c::CMSPAR; - -/// `CRTSCTS` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const CRTSCTS: c::c_uint = c::CRTSCTS; - -/// `XCASE` -#[cfg(any(target_arch = "s390x", target_os = "haiku"))] -pub const XCASE: c::c_uint = c::XCASE; - -/// `ECHOCTL` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const ECHOCTL: c::c_uint = c::ECHOCTL; - -/// `ECHOPRT` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const ECHOPRT: c::c_uint = c::ECHOPRT; - -/// `ECHOKE` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const ECHOKE: c::c_uint = c::ECHOKE; - -/// `FLUSHO` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const FLUSHO: c::c_uint = c::FLUSHO; - -/// `PENDIN` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const PENDIN: c::c_uint = c::PENDIN; - -/// `EXTPROC` -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub const EXTPROC: c::c_uint = c::EXTPROC; - -/// `XTABS` -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -pub const XTABS: c::c_uint = c::XTABS; diff --git a/vendor/rustix/src/imp/libc/thread/mod.rs b/vendor/rustix/src/imp/libc/thread/mod.rs deleted file mode 100644 index 40e0d1135..000000000 --- a/vendor/rustix/src/imp/libc/thread/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[cfg(not(windows))] -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/imp/libc/thread/syscalls.rs b/vendor/rustix/src/imp/libc/thread/syscalls.rs deleted file mode 100644 index c885372dc..000000000 --- a/vendor/rustix/src/imp/libc/thread/syscalls.rs +++ /dev/null @@ -1,282 +0,0 @@ -//! libc syscalls supporting `rustix::thread`. - -use super::super::c; -use super::super::conv::ret; -use super::super::time::types::LibcTimespec; -use crate::io; -#[cfg(any(target_os = "android", target_os = "linux"))] -use crate::process::{Pid, RawNonZeroPid}; -#[cfg(not(target_os = "redox"))] -use crate::thread::{NanosleepRelativeResult, Timespec}; -use core::mem::MaybeUninit; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "emscripten", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -use {crate::thread::ClockId, core::ptr::null_mut}; - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -weak!(fn __clock_nanosleep_time64(c::clockid_t, c::c_int, *const LibcTimespec, *mut LibcTimespec) -> c::c_int); -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -weak!(fn __nanosleep64(*const LibcTimespec, *mut LibcTimespec) -> c::c_int); - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - let mut remain = MaybeUninit::::uninit(); - let flags = 0; - - // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe by - // default. - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { - match libc_clock_nanosleep( - id as c::clockid_t, - flags, - &request.clone().into(), - remain.as_mut_ptr(), - ) { - 0 => NanosleepRelativeResult::Ok, - err if err == io::Errno::INTR.0 => { - NanosleepRelativeResult::Interrupted(remain.assume_init().into()) - } - err => NanosleepRelativeResult::Err(io::Errno(err)), - } - } else { - clock_nanosleep_relative_old(id, request) - } - } - - // Main version: libc is y2038 safe and has `clock_nanosleep`. - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - unsafe { - match c::clock_nanosleep(id as c::clockid_t, flags, request, remain.as_mut_ptr()) { - 0 => NanosleepRelativeResult::Ok, - err if err == io::Errno::INTR.0 => { - NanosleepRelativeResult::Interrupted(remain.assume_init()) - } - err => NanosleepRelativeResult::Err(io::Errno(err)), - } - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -unsafe fn clock_nanosleep_relative_old(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - use core::convert::TryInto; - let tv_sec = match request.tv_sec.try_into() { - Ok(tv_sec) => tv_sec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), - }; - let tv_nsec = match request.tv_nsec.try_into() { - Ok(tv_nsec) => tv_nsec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::INVAL), - }; - let old_request = c::timespec { tv_sec, tv_nsec }; - let mut old_remain = MaybeUninit::::uninit(); - let flags = 0; - - match c::clock_nanosleep( - id as c::clockid_t, - flags, - &old_request, - old_remain.as_mut_ptr(), - ) { - 0 => NanosleepRelativeResult::Ok, - err if err == io::Errno::INTR.0 => { - let old_remain = old_remain.assume_init(); - let remain = Timespec { - tv_sec: old_remain.tv_sec.into(), - tv_nsec: old_remain.tv_nsec.into(), - }; - NanosleepRelativeResult::Interrupted(remain) - } - err => NanosleepRelativeResult::Err(io::Errno(err)), - } -} - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. - target_os = "emscripten", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[inline] -pub(crate) fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { - let flags = c::TIMER_ABSTIME; - - // 32-bit gnu version: libc has `clock_nanosleep` but it is not y2038 safe by - // default. - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - { - if let Some(libc_clock_nanosleep) = __clock_nanosleep_time64.get() { - match unsafe { - libc_clock_nanosleep( - id as c::clockid_t, - flags, - &request.clone().into(), - null_mut(), - ) - } { - 0 => Ok(()), - err => Err(io::Errno(err)), - } - } else { - clock_nanosleep_absolute_old(id, request) - } - } - - // Main version: libc is y2038 safe and has `clock_nanosleep`. - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - match unsafe { c::clock_nanosleep(id as c::clockid_t, flags, request, null_mut()) } { - 0 => Ok(()), - err => Err(io::Errno(err)), - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -fn clock_nanosleep_absolute_old(id: ClockId, request: &Timespec) -> io::Result<()> { - use core::convert::TryInto; - - let flags = c::TIMER_ABSTIME; - - let old_request = c::timespec { - tv_sec: request.tv_sec.try_into().map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: request.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - match unsafe { c::clock_nanosleep(id as c::clockid_t, flags, &old_request, null_mut()) } { - 0 => Ok(()), - err => Err(io::Errno(err)), - } -} - -#[cfg(not(target_os = "redox"))] -#[inline] -pub(crate) fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { - let mut remain = MaybeUninit::::uninit(); - - // 32-bit gnu version: libc has `nanosleep` but it is not y2038 safe by - // default. - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_nanosleep) = __nanosleep64.get() { - match ret(libc_nanosleep(&request.clone().into(), remain.as_mut_ptr())) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => { - NanosleepRelativeResult::Interrupted(remain.assume_init().into()) - } - Err(err) => NanosleepRelativeResult::Err(err), - } - } else { - nanosleep_old(request) - } - } - - // Main version: libc is y2038 safe and has `nanosleep`. - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - unsafe { - match ret(c::nanosleep(request, remain.as_mut_ptr())) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(remain.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -unsafe fn nanosleep_old(request: &Timespec) -> NanosleepRelativeResult { - use core::convert::TryInto; - let tv_sec = match request.tv_sec.try_into() { - Ok(tv_sec) => tv_sec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::OVERFLOW), - }; - let tv_nsec = match request.tv_nsec.try_into() { - Ok(tv_nsec) => tv_nsec, - Err(_) => return NanosleepRelativeResult::Err(io::Errno::INVAL), - }; - let old_request = c::timespec { tv_sec, tv_nsec }; - let mut old_remain = MaybeUninit::::uninit(); - - match ret(c::nanosleep(&old_request, old_remain.as_mut_ptr())) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => { - let old_remain = old_remain.assume_init(); - let remain = Timespec { - tv_sec: old_remain.tv_sec.into(), - tv_nsec: old_remain.tv_nsec.into(), - }; - NanosleepRelativeResult::Interrupted(remain) - } - Err(err) => NanosleepRelativeResult::Err(err), - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[inline] -#[must_use] -pub(crate) fn gettid() -> Pid { - // `gettid` wasn't supported in glibc until 2.30, and musl until 1.2.2, - // so use `syscall`. - // - weak_or_syscall! { - fn gettid() via SYS_gettid -> c::pid_t - } - - unsafe { - let tid = gettid(); - debug_assert_ne!(tid, 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid)) - } -} diff --git a/vendor/rustix/src/imp/libc/time/mod.rs b/vendor/rustix/src/imp/libc/time/mod.rs deleted file mode 100644 index bff7fd564..000000000 --- a/vendor/rustix/src/imp/libc/time/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/libc/time/syscalls.rs b/vendor/rustix/src/imp/libc/time/syscalls.rs deleted file mode 100644 index 2bbaf8ff1..000000000 --- a/vendor/rustix/src/imp/libc/time/syscalls.rs +++ /dev/null @@ -1,414 +0,0 @@ -//! libc syscalls supporting `rustix::time`. - -use super::super::c; -use super::super::conv::ret; -#[cfg(feature = "time")] -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -use super::super::time::types::LibcItimerspec; -use super::super::time::types::LibcTimespec; -use super::types::Timespec; -#[cfg(not(target_os = "wasi"))] -use super::types::{ClockId, DynamicClockId}; -use crate::io; -use core::mem::MaybeUninit; -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(feature = "time")] -use { - super::super::conv::{borrowed_fd, ret_owned_fd}, - crate::fd::BorrowedFd, - crate::io::OwnedFd, - crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}, -}; - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -weak!(fn __clock_gettime64(c::clockid_t, *mut LibcTimespec) -> c::c_int); -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -weak!(fn __clock_getres64(c::clockid_t, *mut LibcTimespec) -> c::c_int); -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[cfg(feature = "time")] -weak!(fn __timerfd_gettime64(c::c_int, *mut LibcItimerspec) -> c::c_int); -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[cfg(feature = "time")] -weak!(fn __timerfd_settime64(c::c_int, c::c_int, *const LibcItimerspec, *mut LibcItimerspec) -> c::c_int); - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[inline] -#[must_use] -pub(crate) fn clock_getres(id: ClockId) -> Timespec { - let mut timespec = MaybeUninit::::uninit(); - - // 32-bit gnu version: libc has `clock_getres` but it is not y2038 safe by - // default. - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_clock_getres) = __clock_getres64.get() { - ret(libc_clock_getres(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); - timespec.assume_init().into() - } else { - clock_getres_old(id) - } - } - - // Main version: libc is y2038 safe and has `clock_getres`. - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - unsafe { - let _ = c::clock_getres(id as c::clockid_t, timespec.as_mut_ptr()); - timespec.assume_init() - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[must_use] -unsafe fn clock_getres_old(id: ClockId) -> Timespec { - let mut old_timespec = MaybeUninit::::uninit(); - ret(c::clock_getres( - id as c::clockid_t, - old_timespec.as_mut_ptr(), - )) - .unwrap(); - let old_timespec = old_timespec.assume_init(); - Timespec { - tv_sec: old_timespec.tv_sec.into(), - tv_nsec: old_timespec.tv_nsec.into(), - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -#[must_use] -pub(crate) fn clock_gettime(id: ClockId) -> Timespec { - let mut timespec = MaybeUninit::::uninit(); - - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_clock_gettime) = __clock_gettime64.get() { - ret(libc_clock_gettime( - id as c::clockid_t, - timespec.as_mut_ptr(), - )) - .unwrap(); - timespec.assume_init().into() - } else { - clock_gettime_old(id) - } - } - - // Use `unwrap()` here because `clock_getres` can fail if the clock itself - // overflows a number of seconds, but if that happens, the monotonic clocks - // can't maintain their invariants, or the realtime clocks aren't properly - // configured. - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - unsafe { - ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr())).unwrap(); - timespec.assume_init() - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[must_use] -unsafe fn clock_gettime_old(id: ClockId) -> Timespec { - let mut old_timespec = MaybeUninit::::uninit(); - ret(c::clock_gettime( - id as c::clockid_t, - old_timespec.as_mut_ptr(), - )) - .unwrap(); - let old_timespec = old_timespec.assume_init(); - Timespec { - tv_sec: old_timespec.tv_sec.into(), - tv_nsec: old_timespec.tv_nsec.into(), - } -} - -#[cfg(not(target_os = "wasi"))] -#[inline] -pub(crate) fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result { - let mut timespec = MaybeUninit::::uninit(); - unsafe { - let id: c::clockid_t = match id { - DynamicClockId::Known(id) => id as c::clockid_t, - - #[cfg(any(target_os = "android", target_os = "linux"))] - DynamicClockId::Dynamic(fd) => { - use crate::fd::AsRawFd; - const CLOCKFD: i32 = 3; - (!fd.as_raw_fd() << 3) | CLOCKFD - } - - #[cfg(not(any(target_os = "android", target_os = "linux")))] - DynamicClockId::Dynamic(_fd) => { - // Dynamic clocks are not supported on this platform. - return Err(io::Errno::INVAL); - } - - #[cfg(any(target_os = "android", target_os = "linux"))] - DynamicClockId::RealtimeAlarm => c::CLOCK_REALTIME_ALARM, - - #[cfg(any(target_os = "android", target_os = "linux"))] - DynamicClockId::Tai => c::CLOCK_TAI, - - #[cfg(any(target_os = "android", target_os = "linux"))] - DynamicClockId::Boottime => c::CLOCK_BOOTTIME, - - #[cfg(any(target_os = "android", target_os = "linux"))] - DynamicClockId::BoottimeAlarm => c::CLOCK_BOOTTIME_ALARM, - }; - - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - { - if let Some(libc_clock_gettime) = __clock_gettime64.get() { - ret(libc_clock_gettime( - id as c::clockid_t, - timespec.as_mut_ptr(), - ))?; - - Ok(timespec.assume_init().into()) - } else { - clock_gettime_dynamic_old(id) - } - } - - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - { - ret(c::clock_gettime(id as c::clockid_t, timespec.as_mut_ptr()))?; - - Ok(timespec.assume_init()) - } - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[inline] -unsafe fn clock_gettime_dynamic_old(id: c::clockid_t) -> io::Result { - let mut old_timespec = MaybeUninit::::uninit(); - - ret(c::clock_gettime( - id as c::clockid_t, - old_timespec.as_mut_ptr(), - ))?; - - let old_timespec = old_timespec.assume_init(); - Ok(Timespec { - tv_sec: old_timespec.tv_sec.into(), - tv_nsec: old_timespec.tv_nsec.into(), - }) -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(feature = "time")] -pub(crate) fn timerfd_create(id: TimerfdClockId, flags: TimerfdFlags) -> io::Result { - unsafe { ret_owned_fd(c::timerfd_create(id as c::clockid_t, flags.bits())) } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(feature = "time")] -pub(crate) fn timerfd_settime( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_timerfd_settime) = __timerfd_settime64.get() { - ret(libc_timerfd_settime( - borrowed_fd(fd), - flags.bits(), - &new_value.clone().into(), - result.as_mut_ptr(), - )) - .map(|()| result.assume_init().into()) - } else { - timerfd_settime_old(fd, flags, new_value) - } - } - - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - unsafe { - ret(c::timerfd_settime( - borrowed_fd(fd), - flags.bits(), - new_value, - result.as_mut_ptr(), - )) - .map(|()| result.assume_init()) - } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[cfg(feature = "time")] -unsafe fn timerfd_settime_old( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result { - use core::convert::TryInto; - - let mut old_result = MaybeUninit::::uninit(); - - // Convert `new_value` to the old `itimerspec` format. - let old_new_value = c::itimerspec { - it_interval: c::timespec { - tv_sec: new_value - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_interval - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - it_value: c::timespec { - tv_sec: new_value - .it_value - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_value - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - }; - - ret(c::timerfd_settime( - borrowed_fd(fd), - flags.bits(), - &old_new_value, - old_result.as_mut_ptr(), - ))?; - - let old_result = old_result.assume_init(); - Ok(Itimerspec { - it_interval: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - it_value: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - }) -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(feature = "time")] -pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - ))] - unsafe { - if let Some(libc_timerfd_gettime) = __timerfd_gettime64.get() { - ret(libc_timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr())) - .map(|()| result.assume_init().into()) - } else { - timerfd_gettime_old(fd) - } - } - - #[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", - )))] - unsafe { - ret(c::timerfd_gettime(borrowed_fd(fd), result.as_mut_ptr())).map(|()| result.assume_init()) - } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[cfg(feature = "time")] -unsafe fn timerfd_gettime_old(fd: BorrowedFd<'_>) -> io::Result { - use core::convert::TryInto; - - let mut old_result = MaybeUninit::::uninit(); - - ret(c::timerfd_gettime(borrowed_fd(fd), old_result.as_mut_ptr()))?; - - let old_result = old_result.assume_init(); - Ok(Itimerspec { - it_interval: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - it_value: Timespec { - tv_sec: old_result - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: old_result.it_interval.tv_nsec as _, - }, - }) -} diff --git a/vendor/rustix/src/imp/libc/time/types.rs b/vendor/rustix/src/imp/libc/time/types.rs deleted file mode 100644 index 4aa2b22e5..000000000 --- a/vendor/rustix/src/imp/libc/time/types.rs +++ /dev/null @@ -1,362 +0,0 @@ -use super::super::c; -#[cfg(not(target_os = "wasi"))] -use crate::fd::BorrowedFd; -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -use bitflags::bitflags; - -/// `struct timespec` -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -pub type Timespec = c::timespec; - -/// `struct timespec` -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[derive(Debug, Clone)] -#[repr(C)] -pub struct Timespec { - /// Seconds. - pub tv_sec: Secs, - - /// Nanoseconds. Must be less than 1_000_000_000. - pub tv_nsec: Nsecs, -} - -/// A type for the `tv_sec` field of [`Timespec`]. -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -#[allow(deprecated)] -pub type Secs = c::time_t; - -/// A type for the `tv_sec` field of [`Timespec`]. -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -pub type Secs = i64; - -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "32"))] -pub type Nsecs = i64; - -/// A type for the `tv_nsec` field of [`Timespec`]. -#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))] -pub type Nsecs = c::c_long; - -/// On most platforms, `LibcTimespec` is just `Timespec`. -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -pub(crate) type LibcTimespec = Timespec; - -/// On 32-bit glibc platforms, `timespec` has anonymous padding fields, which -/// Rust doesn't support yet (see `unnamed_fields`), so we define our own -/// struct with explicit padding, with bidirectional `From` impls. -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[repr(C)] -#[derive(Debug, Clone)] -pub(crate) struct LibcTimespec { - pub(crate) tv_sec: Secs, - - #[cfg(target_endian = "big")] - padding: core::mem::MaybeUninit, - - pub(crate) tv_nsec: Nsecs, - - #[cfg(target_endian = "little")] - padding: core::mem::MaybeUninit, -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -impl From for Timespec { - #[inline] - fn from(t: LibcTimespec) -> Self { - Self { - tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec, - } - } -} - -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -impl From for LibcTimespec { - #[inline] - fn from(t: Timespec) -> Self { - Self { - tv_sec: t.tv_sec, - tv_nsec: t.tv_nsec, - padding: core::mem::MaybeUninit::uninit(), - } - } -} - -/// `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 -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "wasi")))] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[cfg_attr(not(target_os = "dragonfly"), repr(i32))] -#[cfg_attr(target_os = "dragonfly", repr(u64))] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - Realtime = c::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC` - Monotonic = c::CLOCK_MONOTONIC, - - /// `CLOCK_PROCESS_CPUTIME_ID` - #[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, - - /// `CLOCK_THREAD_CPUTIME_ID` - #[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, - - /// `CLOCK_REALTIME_COARSE` - #[cfg(any(target_os = "android", target_os = "linux"))] - RealtimeCoarse = c::CLOCK_REALTIME_COARSE, - - /// `CLOCK_MONOTONIC_COARSE` - #[cfg(any(target_os = "android", target_os = "linux"))] - MonotonicCoarse = c::CLOCK_MONOTONIC_COARSE, - - /// `CLOCK_MONOTONIC_RAW` - #[cfg(any(target_os = "android", target_os = "linux"))] - MonotonicRaw = c::CLOCK_MONOTONIC_RAW, -} - -/// `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. -#[cfg(any(target_os = "ios", target_os = "macos"))] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum ClockId { - /// `CLOCK_REALTIME` - Realtime = c::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC` - Monotonic = c::CLOCK_MONOTONIC, - - /// `CLOCK_PROCESS_CPUTIME_ID` - ProcessCPUTime = c::CLOCK_PROCESS_CPUTIME_ID, - - /// `CLOCK_THREAD_CPUTIME_ID` - ThreadCPUTime = c::CLOCK_THREAD_CPUTIME_ID, -} - -/// `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 -#[cfg(not(target_os = "wasi"))] -#[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 - #[cfg(any(target_os = "android", target_os = "linux"))] - RealtimeAlarm, - - /// `CLOCK_TAI`, available on Linux >= 3.10 - #[cfg(any(target_os = "android", target_os = "linux"))] - Tai, - - /// `CLOCK_BOOTTIME`, available on Linux >= 2.6.39 - #[cfg(any(target_os = "android", target_os = "linux"))] - Boottime, - - /// `CLOCK_BOOTTIME_ALARM`, available on Linux >= 2.6.39 - #[cfg(any(target_os = "android", target_os = "linux"))] - BoottimeAlarm, -} - -/// `struct itimerspec` -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -pub type Itimerspec = c::itimerspec; - -/// `struct itimerspec` -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct Itimerspec { - pub it_interval: Timespec, - pub it_value: Timespec, -} - -/// On most platforms, `LibcItimerspec` is just `Itimerspec`. -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(not(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -)))] -pub(crate) type LibcItimerspec = Itimerspec; - -/// On 32-bit glibc platforms, `LibcTimespec` differs from `Timespec`, so we -/// define our own struct, with bidirectional `From` impls. -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -#[repr(C)] -#[derive(Debug, Clone)] -pub(crate) struct LibcItimerspec { - pub it_interval: LibcTimespec, - pub it_value: LibcTimespec, -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -impl From for Itimerspec { - #[inline] - fn from(t: LibcItimerspec) -> Self { - Self { - it_interval: t.it_interval.into(), - it_value: t.it_value.into(), - } - } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[cfg(all( - any(target_arch = "arm", target_arch = "mips", target_arch = "x86"), - target_env = "gnu", -))] -impl From for LibcItimerspec { - #[inline] - fn from(t: Itimerspec) -> Self { - Self { - it_interval: t.it_interval.into(), - it_value: t.it_value.into(), - } - } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -bitflags! { - /// `TFD_*` flags for use with [`timerfd_create`]. - pub struct TimerfdFlags: c::c_int { - /// `TFD_NONBLOCK` - const NONBLOCK = c::TFD_NONBLOCK; - - /// `TFD_CLOEXEC` - const CLOEXEC = c::TFD_CLOEXEC; - } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -bitflags! { - /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. - pub struct TimerfdTimerFlags: c::c_int { - /// `TFD_TIMER_ABSTIME` - const ABSTIME = c::TFD_TIMER_ABSTIME; - - /// `TFD_TIMER_CANCEL_ON_SET` - #[cfg(any(target_os = "android", target_os = "linux"))] - const CANCEL_ON_SET = 2; // TODO: upstream TFD_TIMER_CANCEL_ON_SET - } -} - -/// `CLOCK_*` constants for use with [`timerfd_create`]. -/// -/// [`timerfd_create`]: crate::time::timerfd_create -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(i32)] -#[non_exhaustive] -pub enum TimerfdClockId { - /// `CLOCK_REALTIME`—A clock that tells the "real" time. - /// - /// This is a clock that tells the amount of time elapsed since the - /// Unix epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so - /// it is not monotonic. Successive reads may see decreasing times, so it - /// isn't reliable for measuring durations. - Realtime = c::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. - /// - /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so - /// individual times aren't meaningful. However, since it isn't settable, - /// it is reliable for measuring durations. - /// - /// This clock does not advance while the system is suspended; see - /// `Boottime` for a clock that does. - Monotonic = c::CLOCK_MONOTONIC, - - /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. - /// - /// This clock is similar to `Monotonic`, but does advance while the system - /// is suspended. - Boottime = c::CLOCK_BOOTTIME, - - /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. - /// - /// This clock is like `Realtime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - RealtimeAlarm = c::CLOCK_REALTIME_ALARM, - - /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. - /// - /// This clock is like `Boottime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - BoottimeAlarm = c::CLOCK_BOOTTIME_ALARM, -} diff --git a/vendor/rustix/src/imp/libc/weak.rs b/vendor/rustix/src/imp/libc/weak.rs deleted file mode 100644 index 893403b1c..000000000 --- a/vendor/rustix/src/imp/libc/weak.rs +++ /dev/null @@ -1,226 +0,0 @@ -// Implementation derived from `weak` in Rust's -// library/std/src/sys/unix/weak.rs at revision -// fd0cb0cdc21dd9c06025277d772108f8d42cb25f. - -//! Support for "weak linkage" to symbols on Unix -//! -//! Some I/O operations we do in libstd require newer versions of OSes but we -//! need to maintain binary compatibility with older releases for now. In order -//! to use the new functionality when available we use this module for -//! detection. -//! -//! One option to use here is weak linkage, but that is unfortunately only -//! really workable on Linux. Hence, use dlsym to get the symbol value at -//! runtime. This is also done for compatibility with older versions of glibc, -//! and to avoid creating dependencies on `GLIBC_PRIVATE` symbols. It assumes -//! that we've been dynamically linked to the library the symbol comes from, -//! but that is currently always the case for things like libpthread/libc. -//! -//! A long time ago this used weak linkage for the `__pthread_get_minstack` -//! symbol, but that caused Debian to detect an unnecessarily strict versioned -//! dependency on libc6 (#23628). - -// There are a variety of `#[cfg]`s controlling which targets are involved in -// each instance of `weak!` and `syscall!`. Rather than trying to unify all of -// that, we'll just allow that some unix targets don't use this module at all. -#![allow(dead_code, unused_macros)] -#![allow(clippy::doc_markdown)] - -use crate::ffi::CStr; -use core::ffi::c_void; -use core::ptr::null_mut; -use core::sync::atomic::{self, AtomicPtr, Ordering}; -use core::{marker, mem}; - -const NULL: *mut c_void = null_mut(); -const INVALID: *mut c_void = 1 as *mut c_void; - -macro_rules! weak { - ($vis:vis fn $name:ident($($t:ty),*) -> $ret:ty) => ( - #[allow(non_upper_case_globals)] - $vis static $name: $crate::imp::weak::Weak $ret> = - $crate::imp::weak::Weak::new(concat!(stringify!($name), '\0')); - ) -} - -pub(crate) struct Weak { - name: &'static str, - addr: AtomicPtr, - _marker: marker::PhantomData, -} - -impl Weak { - pub(crate) const fn new(name: &'static str) -> Self { - Self { - name, - addr: AtomicPtr::new(INVALID), - _marker: marker::PhantomData, - } - } - - pub(crate) fn get(&self) -> Option { - assert_eq!(mem::size_of::(), mem::size_of::()); - unsafe { - // Relaxed is fine here because we fence before reading through the - // pointer (see the comment below). - match self.addr.load(Ordering::Relaxed) { - INVALID => self.initialize(), - NULL => None, - addr => { - let func = mem::transmute_copy::<*mut c_void, F>(&addr); - // The caller is presumably going to read through this value - // (by calling the function we've dlsymed). This means we'd - // need to have loaded it with at least C11's consume - // ordering in order to be guaranteed that the data we read - // from the pointer isn't from before the pointer was - // stored. Rust has no equivalent to memory_order_consume, - // so we use an acquire fence (sorry, ARM). - // - // Now, in practice this likely isn't needed even on CPUs - // where relaxed and consume mean different things. The - // symbols we're loading are probably present (or not) at - // init, and even if they aren't the runtime dynamic loader - // is extremely likely have sufficient barriers internally - // (possibly implicitly, for example the ones provided by - // invoking `mprotect`). - // - // That said, none of that's *guaranteed*, and so we fence. - atomic::fence(Ordering::Acquire); - Some(func) - } - } - } - } - - // Cold because it should only happen during first-time initialization. - #[cold] - unsafe fn initialize(&self) -> Option { - let val = fetch(self.name); - // This synchronizes with the acquire fence in `get`. - self.addr.store(val, Ordering::Release); - - match val { - NULL => None, - addr => Some(mem::transmute_copy::<*mut c_void, F>(&addr)), - } - } -} - -unsafe fn fetch(name: &str) -> *mut c_void { - let name = match CStr::from_bytes_with_nul(name.as_bytes()) { - Ok(c_str) => c_str, - Err(..) => return null_mut(), - }; - libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr().cast()) -} - -#[cfg(not(any(target_os = "android", target_os = "linux")))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) via $_sys_name:ident -> $ret:ty) => ( - unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - libc_errno::set_errno(libc_errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) via $sys_name:ident -> $ret:ty) => ( - unsafe fn $name($($arg_name:$t),*) -> $ret { - // This looks like a hack, but concat_idents only accepts idents - // (not paths). - use libc::*; - - trait AsSyscallArg { - type SyscallArgType; - fn into_syscall_arg(self) -> Self::SyscallArgType; - } - - // Pass pointer types as pointers, to preserve provenance. - impl AsSyscallArg for *mut T { - type SyscallArgType = *mut T; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - impl AsSyscallArg for *const T { - type SyscallArgType = *const T; - fn into_syscall_arg(self) -> Self::SyscallArgType { self } - } - - // Pass `BorrowedFd` values as the integer value. - impl AsSyscallArg for $crate::fd::BorrowedFd<'_> { - type SyscallArgType = c::c_long; - fn into_syscall_arg(self) -> Self::SyscallArgType { - $crate::fd::AsRawFd::as_raw_fd(&self) as _ - } - } - - // Coerce integer values into `c_long`. - impl AsSyscallArg for i32 { - type SyscallArgType = c::c_long; - fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - impl AsSyscallArg for u32 { - type SyscallArgType = c::c_long; - fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - impl AsSyscallArg for usize { - type SyscallArgType = c::c_long; - fn into_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - - // `concat_idents is unstable, so we take an extra `sys_name` - // parameter and have our users do the concat for us for now. - /* - syscall( - concat_idents!(SYS_, $name), - $($arg_name.into_syscall_arg()),* - ) as $ret - */ - - syscall($sys_name, $($arg_name.into_syscall_arg()),*) as $ret - } - ) -} - -macro_rules! weakcall { - ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - $vis unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` - // interposition, but if it's not found just fail. - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - libc_errno::set_errno(libc_errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} - -/// A combination of `weakcall` and `syscall`. Use the libc function if it's -/// available, and fall back to `libc::syscall` otherwise. -macro_rules! weak_or_syscall { - ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) via $sys_name:ident -> $ret:ty) => ( - $vis unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` - // interposition, but if it's not found just fail. - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - syscall! { fn $name($($arg_name: $t),*) via $sys_name -> $ret } - $name($($arg_name),*) - } - } - ) -} diff --git a/vendor/rustix/src/imp/libc/winsock_c.rs b/vendor/rustix/src/imp/libc/winsock_c.rs deleted file mode 100644 index 1fbce416f..000000000 --- a/vendor/rustix/src/imp/libc/winsock_c.rs +++ /dev/null @@ -1,82 +0,0 @@ -//! Adapt the Winsock2 API to resemble a POSIX-style libc API. - -#![allow(unused_imports)] -#![allow(non_camel_case_types)] - -use windows_sys::Win32::Networking::WinSock; - -pub(crate) use libc::{ - c_char, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint, c_ulong, c_ulonglong, - c_ushort, c_void, ssize_t, -}; -pub(crate) type socklen_t = i32; - -// windows-sys declares these constants as unsigned. For better compatibility -// with Unix-family APIs, redeclare them as signed. Filed upstream: -// -pub(crate) const AF_INET: i32 = WinSock::AF_INET as _; -pub(crate) const AF_INET6: i32 = WinSock::AF_INET6 as _; -pub(crate) const AF_UNSPEC: i32 = WinSock::AF_UNSPEC as _; -pub(crate) const SO_TYPE: i32 = WinSock::SO_TYPE as _; -pub(crate) const SO_REUSEADDR: i32 = WinSock::SO_REUSEADDR as _; -pub(crate) const SO_BROADCAST: i32 = WinSock::SO_BROADCAST as _; -pub(crate) const SO_LINGER: i32 = WinSock::SO_LINGER as _; -pub(crate) const SOL_SOCKET: i32 = WinSock::SOL_SOCKET as _; -pub(crate) const SO_RCVTIMEO: i32 = WinSock::SO_RCVTIMEO as _; -pub(crate) const SO_SNDTIMEO: i32 = WinSock::SO_SNDTIMEO as _; -pub(crate) const IP_TTL: i32 = WinSock::IP_TTL as _; -pub(crate) const TCP_NODELAY: i32 = WinSock::TCP_NODELAY as _; -pub(crate) const IP_ADD_MEMBERSHIP: i32 = WinSock::IP_ADD_MEMBERSHIP as _; -pub(crate) const IP_DROP_MEMBERSHIP: i32 = WinSock::IP_DROP_MEMBERSHIP as _; -pub(crate) const IP_MULTICAST_TTL: i32 = WinSock::IP_MULTICAST_TTL as _; -pub(crate) const IP_MULTICAST_LOOP: i32 = WinSock::IP_MULTICAST_LOOP as _; -pub(crate) const IPV6_ADD_MEMBERSHIP: i32 = WinSock::IPV6_ADD_MEMBERSHIP as _; -pub(crate) const IPV6_DROP_MEMBERSHIP: i32 = WinSock::IPV6_DROP_MEMBERSHIP as _; -pub(crate) const IPV6_MULTICAST_LOOP: i32 = WinSock::IPV6_MULTICAST_LOOP as _; -pub(crate) const IPV6_V6ONLY: i32 = WinSock::IPV6_V6ONLY as _; -pub(crate) const POLLERR: i16 = WinSock::POLLERR as _; -pub(crate) const POLLIN: i16 = WinSock::POLLIN as _; -pub(crate) const POLLNVAL: i16 = WinSock::POLLNVAL as _; -pub(crate) const POLLHUP: i16 = WinSock::POLLHUP as _; -pub(crate) const POLLPRI: i16 = WinSock::POLLPRI as _; -pub(crate) const POLLOUT: i16 = WinSock::POLLOUT as _; -pub(crate) const POLLRDNORM: i16 = WinSock::POLLRDNORM as _; -pub(crate) const POLLWRNORM: i16 = WinSock::POLLWRNORM as _; -pub(crate) const POLLRDBAND: i16 = WinSock::POLLRDBAND as _; -pub(crate) const POLLWRBAND: i16 = WinSock::POLLWRBAND as _; - -// As above, cast the types for better compatibility, and also rename these to -// their Unix names. -pub(crate) const SHUT_RDWR: i32 = WinSock::SD_BOTH as _; -pub(crate) const SHUT_RD: i32 = WinSock::SD_RECEIVE as _; -pub(crate) const SHUT_WR: i32 = WinSock::SD_SEND as _; - -// Include the contents of `WinSock`, renaming as needed to match POSIX. -// -// Use `WSA_E_CANCELLED` for `ECANCELED` instead of `WSAECANCELLED`, because -// `WSAECANCELLED` will be removed in the future. -// -pub(crate) use WinSock::{ - closesocket as close, ioctlsocket as ioctl, WSAPoll as poll, ADDRESS_FAMILY as sa_family_t, - ADDRINFOA as addrinfo, IN6_ADDR as in6_addr, IN_ADDR as in_addr, IPV6_MREQ as ipv6_mreq, - IP_MREQ as ip_mreq, SOCKADDR as sockaddr, SOCKADDR_IN as sockaddr_in, - SOCKADDR_IN6 as sockaddr_in6, SOCKADDR_STORAGE as sockaddr_storage, WSAEACCES as EACCES, - WSAEADDRINUSE as EADDRINUSE, WSAEADDRNOTAVAIL as EADDRNOTAVAIL, - WSAEAFNOSUPPORT as EAFNOSUPPORT, WSAEALREADY as EALREADY, WSAEBADF as EBADF, - WSAECONNABORTED as ECONNABORTED, WSAECONNREFUSED as ECONNREFUSED, WSAECONNRESET as ECONNRESET, - WSAEDESTADDRREQ as EDESTADDRREQ, WSAEDISCON as EDISCON, WSAEDQUOT as EDQUOT, - WSAEFAULT as EFAULT, WSAEHOSTDOWN as EHOSTDOWN, WSAEHOSTUNREACH as EHOSTUNREACH, - WSAEINPROGRESS as EINPROGRESS, WSAEINTR as EINTR, WSAEINVAL as EINVAL, - WSAEINVALIDPROCTABLE as EINVALIDPROCTABLE, WSAEINVALIDPROVIDER as EINVALIDPROVIDER, - WSAEISCONN as EISCONN, WSAELOOP as ELOOP, WSAEMFILE as EMFILE, WSAEMSGSIZE as EMSGSIZE, - WSAENAMETOOLONG as ENAMETOOLONG, WSAENETDOWN as ENETDOWN, WSAENETRESET as ENETRESET, - WSAENETUNREACH as ENETUNREACH, WSAENOBUFS as ENOBUFS, WSAENOMORE as ENOMORE, - WSAENOPROTOOPT as ENOPROTOOPT, WSAENOTCONN as ENOTCONN, WSAENOTEMPTY as ENOTEMPTY, - WSAENOTSOCK as ENOTSOCK, WSAEOPNOTSUPP as EOPNOTSUPP, WSAEPFNOSUPPORT as EPFNOSUPPORT, - WSAEPROCLIM as EPROCLIM, WSAEPROTONOSUPPORT as EPROTONOSUPPORT, WSAEPROTOTYPE as EPROTOTYPE, - WSAEPROVIDERFAILEDINIT as EPROVIDERFAILEDINIT, WSAEREFUSED as EREFUSED, WSAEREMOTE as EREMOTE, - WSAESHUTDOWN as ESHUTDOWN, WSAESOCKTNOSUPPORT as ESOCKTNOSUPPORT, WSAESTALE as ESTALE, - WSAETIMEDOUT as ETIMEDOUT, WSAETOOMANYREFS as ETOOMANYREFS, WSAEUSERS as EUSERS, - WSAEWOULDBLOCK as EWOULDBLOCK, WSAEWOULDBLOCK as EAGAIN, WSAPOLLFD as pollfd, - WSA_E_CANCELLED as ECANCELED, *, -}; diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/aarch64.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/aarch64.rs deleted file mode 100644 index 7d33a4a52..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/aarch64.rs +++ /dev/null @@ -1,266 +0,0 @@ -//! aarch64 Linux system calls. - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use core::arch::asm; - -#[cfg(target_pointer_width = "32")] -compile_error!("arm64-ilp32 is not supported yet"); - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - lateout("x0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "svc 0", - in("x8") nr.to_asm(), - in("x0") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - in("x5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("x8") nr.to_asm(), - inlateout("x0") a0.to_asm() => r0, - in("x1") a1.to_asm(), - in("x2") a2.to_asm(), - in("x3") a3.to_asm(), - in("x4") a4.to_asm(), - in("x5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/arm.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/arm.rs deleted file mode 100644 index 9acccd6dc..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/arm.rs +++ /dev/null @@ -1,263 +0,0 @@ -//! arm Linux system calls. - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use core::arch::asm; - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - lateout("r0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "svc 0", - in("r7") nr.to_asm(), - in("r0") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - in("r5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "svc 0", - in("r7") nr.to_asm(), - inlateout("r0") a0.to_asm() => r0, - in("r1") a1.to_asm(), - in("r2") a2.to_asm(), - in("r3") a3.to_asm(), - in("r4") a4.to_asm(), - in("r5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/mips.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/mips.rs deleted file mode 100644 index 0f2b9d9d2..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/mips.rs +++ /dev/null @@ -1,543 +0,0 @@ -//! mipsel Linux system calls. -//! -//! On mipsel, Linux indicates success or failure using `$a3` rather -//! than by returning a negative error code as most other architectures do. -//! -//! Mips-family platforms have a special calling convention for `__NR_pipe`, -//! however we use `__NR_pipe2` instead to avoid having to implement it. - -use crate::imp::reg::{ - ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, A6, R0, -}; -use core::arch::asm; - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - in("$2" /*$v0*/) nr.to_asm(), - in("$4" /*$a0*/) a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall7_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - a6: ArgReg<'_, A6>, -) -> RetReg { - let x0; - let err: usize; - asm!( - ".set noat", - "subu $sp, 32", - "sw {}, 16($sp)", - "sw {}, 20($sp)", - "sw {}, 24($sp)", - "syscall", - "addu $sp, 32", - ".set at", - in(reg) a4.to_asm(), - in(reg) a5.to_asm(), - in(reg) a6.to_asm(), - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$t0*/) _, - lateout("$9" /*$t1*/) _, - lateout("$10" /*$t2*/) _, - lateout("$11" /*$t3*/) _, - lateout("$12" /*$t4*/) _, - lateout("$13" /*$t5*/) _, - lateout("$14" /*$t6*/) _, - lateout("$15" /*$t7*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/mips64.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/mips64.rs deleted file mode 100644 index 36dd79316..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/mips64.rs +++ /dev/null @@ -1,464 +0,0 @@ -//! mips64el Linux system calls. -//! -//! On mips64el, Linux indicates success or failure using `$a3` (`$7`) rather -//! than by returning a negative error code as most other architectures do. -//! -//! Mips-family platforms have a special calling convention for `__NR_pipe`, -//! however we use `__NR_pipe2` instead to avoid having to implement it. - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use core::arch::asm; - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - in("$2" /*$v0*/) nr.to_asm(), - in("$4" /*$a0*/) a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - lateout("$7" /*$a3*/) err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - lateout("$8" /*$a4*/) _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - lateout("$9" /*$a5*/) _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - inlateout("$9" /*$a5*/) a5.to_asm() => _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let x0; - let err: usize; - asm!( - "syscall", - inlateout("$2" /*$v0*/) nr.to_asm() => x0, - in("$4" /*$a0*/) a0.to_asm(), - in("$5" /*$a1*/) a1.to_asm(), - in("$6" /*$a2*/) a2.to_asm(), - inlateout("$7" /*$a3*/) a3.to_asm() => err, - inlateout("$8" /*$a4*/) a4.to_asm() => _, - inlateout("$9" /*$a5*/) a5.to_asm() => _, - lateout("$10" /*$a6*/) _, - lateout("$11" /*$a7*/) _, - lateout("$12" /*$t0*/) _, - lateout("$13" /*$t1*/) _, - lateout("$14" /*$t2*/) _, - lateout("$15" /*$t3*/) _, - lateout("$24" /*$t8*/) _, - lateout("$25" /*$t9*/) _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(if err != 0 { - (x0 as usize).wrapping_neg() as *mut _ - } else { - x0 - }) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/mod.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/mod.rs deleted file mode 100644 index 3e25e2149..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! Inline asm for making system calls. -//! -//! Compilers should really have intrinsics for making system calls. They're -//! much like regular calls, with custom calling conventions, and calling -//! conventions are otherwise the compiler's job. But for now, use inline asm. - -#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")] -#[cfg_attr(target_arch = "arm", path = "arm.rs")] -#[cfg_attr(target_arch = "mips", path = "mips.rs")] -#[cfg_attr(target_arch = "mips64", path = "mips64.rs")] -#[cfg_attr(target_arch = "powerpc64", path = "powerpc64.rs")] -#[cfg_attr(target_arch = "riscv64", path = "riscv64.rs")] -#[cfg_attr(target_arch = "x86", path = "x86.rs")] -#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")] -mod target_arch; - -pub(in crate::imp) use self::target_arch::*; diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/powerpc64.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/powerpc64.rs deleted file mode 100644 index 520bd4d79..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/powerpc64.rs +++ /dev/null @@ -1,411 +0,0 @@ -//! powerpc64le Linux system calls. -//! -//! On powerpc64le, Linux indicates success or failure using `cr0.SO` rather -//! than by returning a negative error code as most other architectures do. In -//! theory we could immediately translate this into a `Result`, and it'd save a -//! few branches. And in theory we could have specialized sequences for use -//! with syscalls that are known to never fail. However, those would require -//! more extensive changes in rustix's platform-independent code. For now, we -//! check the flag and negate the error value to make PowerPC64 look like other -//! architectures. - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use core::arch::asm; - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - lateout("r3") r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - lateout("r4") _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "sc", - in("r0") nr.to_asm(), - in("r3") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - lateout("r5") _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - lateout("r6") _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - lateout("r7") _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - lateout("r8") _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - inlateout("r8") a5.to_asm() => _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "sc", - "bns 0f", - "neg 3, 3", - "0:", - inlateout("r0") nr.to_asm() => _, - inlateout("r3") a0.to_asm() => r0, - inlateout("r4") a1.to_asm() => _, - inlateout("r5") a2.to_asm() => _, - inlateout("r6") a3.to_asm() => _, - inlateout("r7") a4.to_asm() => _, - inlateout("r8") a5.to_asm() => _, - lateout("r9") _, - lateout("r10") _, - lateout("r11") _, - lateout("r12") _, - lateout("cr0") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/riscv64.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/riscv64.rs deleted file mode 100644 index 3ed36a16c..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/riscv64.rs +++ /dev/null @@ -1,263 +0,0 @@ -//! riscv64 Linux system calls. - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use core::arch::asm; - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - lateout("a0") r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "ecall", - in("a7") nr.to_asm(), - in("a0") a0.to_asm(), - options(noreturn) - ); -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - in("a5") a5.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "ecall", - in("a7") nr.to_asm(), - inlateout("a0") a0.to_asm() => r0, - in("a1") a1.to_asm(), - in("a2") a2.to_asm(), - in("a3") a3.to_asm(), - in("a4") a4.to_asm(), - in("a5") a5.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/x86.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/x86.rs deleted file mode 100644 index 8d1b4ed0a..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/x86.rs +++ /dev/null @@ -1,492 +0,0 @@ -//! 32-bit x86 Linux system calls. -//! -//! There are two forms; `indirect_*` which take a callee, which allow calling -//! through the vDSO when possible, and plain forms, which use the `int 0x80` -//! instruction. -//! -//! Most `rustix` syscalls use the vsyscall mechanism rather than going using -//! `int 0x80` sequences. - -#![allow(dead_code)] - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use crate::imp::vdso_wrappers::SyscallType; -use core::arch::asm; - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall0( - callee: SyscallType, - nr: SyscallNumber<'_>, -) -> RetReg { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall1( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall1_noreturn( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> ! { - asm!( - "call {callee}", - callee = in(reg) callee, - in("eax") nr.to_asm(), - in("ebx") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall2( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall3( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "call {callee}", - callee = in(reg) callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall4( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - 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. - // - // 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 - // satisfy `in(reg)`. - asm!( - "xchg esi, {a3}", - "call edi", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - in("edi") callee, - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall5( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - // Oof. a3 should go in esi, and `asm!` won't let us use that register as - // an operand. And we can't request stack slots. And there are no other - // registers free. Use eax as a temporary pointer to a slice, since it - // gets clobbered as the return value anyway. - asm!( - "push esi", - "push DWORD PTR [eax + 0]", - "mov esi, DWORD PTR [eax + 4]", - "mov eax, DWORD PTR [eax + 8]", - "call DWORD PTR [esp]", - "pop esi", - "pop esi", - inout("eax") &[callee as _, a3.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[allow(clippy::too_many_arguments)] -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall6( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - // Oof again. a3 should go in esi, and a5 should go in ebp, and `asm!` - // won't let us use either of those registers as operands. And we can't - // request stack slots. And there are no other registers free. Use eax as a - // temporary pointer to a slice, since it gets clobbered as the return - // value anyway. - // - // This is another reason that syscalls should be compiler intrinsics - // rather than inline asm. - asm!( - "push ebp", - "push esi", - "push DWORD PTR [eax + 0]", - "mov esi, DWORD PTR [eax + 4]", - "mov ebp, DWORD PTR [eax + 8]", - "mov eax, DWORD PTR [eax + 12]", - "call DWORD PTR [esp]", - "pop esi", - "pop esi", - "pop ebp", - inout("eax") &[callee as _, a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "int $$0x80", - in("eax") nr.to_asm(), - in("ebx") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "int $$0x80", - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - 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. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - // As in `syscall4`, use xchg to handle a3. a4 should go in edi, and we can - // use that register as an operand. Unlike in `indirect_syscall5`, we don't - // have a `callee` operand taking up a register, so we have enough - // registers and don't need to use a slice. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - // See the comments in `syscall5`. - asm!( - "xchg esi, {a3}", - "int $$0x80", - "xchg esi, {a3}", - a3 = in(reg) a3.to_asm(), - inlateout("eax") nr.to_asm() => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - // See the comments in `indirect_syscall6`. - asm!( - "push ebp", - "push esi", - "mov esi, DWORD PTR [eax + 0]", - "mov ebp, DWORD PTR [eax + 4]", - "mov eax, DWORD PTR [eax + 8]", - "int $$0x80", - "pop esi", - "pop ebp", - inout("eax") &[a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - // See the comments in `indirect_syscall6`. - asm!( - "push ebp", - "push esi", - "mov esi, DWORD PTR [eax + 0]", - "mov ebp, DWORD PTR [eax + 4]", - "mov eax, DWORD PTR [eax + 8]", - "int $$0x80", - "pop esi", - "pop ebp", - inout("eax") &[a3.to_asm(), a5.to_asm(), nr.to_asm()] => r0, - in("ebx") a0.to_asm(), - in("ecx") a1.to_asm(), - in("edx") a2.to_asm(), - in("edi") a4.to_asm(), - options(preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/inline/x86_64.rs b/vendor/rustix/src/imp/linux_raw/arch/inline/x86_64.rs deleted file mode 100644 index 75d6124f7..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/inline/x86_64.rs +++ /dev/null @@ -1,291 +0,0 @@ -//! x86-64 Linux system calls. - -use crate::imp::reg::{ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0}; -use core::arch::asm; - -#[cfg(target_pointer_width = "32")] -compile_error!("x32 is not yet supported"); - -#[inline] -pub(in crate::imp) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - asm!( - "syscall", - in("rax") nr.to_asm(), - in("rdi") a0.to_asm(), - options(noreturn) - ) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall2_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall3_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall4_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall5_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - in("r9") a5.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags) - ); - FromAsm::from_asm(r0) -} - -#[inline] -pub(in crate::imp) unsafe fn syscall6_readonly( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - let r0; - asm!( - "syscall", - inlateout("rax") nr.to_asm() => r0, - in("rdi") a0.to_asm(), - in("rsi") a1.to_asm(), - in("rdx") a2.to_asm(), - in("r10") a3.to_asm(), - in("r8") a4.to_asm(), - in("r9") a5.to_asm(), - lateout("rcx") _, - lateout("r11") _, - options(nostack, preserves_flags, readonly) - ); - FromAsm::from_asm(r0) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/mod.rs b/vendor/rustix/src/imp/linux_raw/arch/mod.rs deleted file mode 100644 index 81f3a255e..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/mod.rs +++ /dev/null @@ -1,218 +0,0 @@ -//! 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). -//! -//! This module also has a `choose` submodule which chooses a scheme and is -//! what most of the `rustix` syscalls use. -//! -//! # Safety -//! -//! This contains the inline `asm` statements performing the syscall -//! instructions and FFI declarations declaring the out-of-line ("outline") -//! syscall instructions. - -#![allow(unsafe_code)] -#![cfg_attr(not(feature = "all-apis"), allow(unused_imports))] - -// When inline asm is available, use it. Otherwise, use out-of-line asm. These -// functions always use the machine's syscall instruction, even when it isn't -// the fastest option available. -#[cfg_attr(asm, path = "inline/mod.rs")] -#[cfg_attr(not(asm), path = "outline/mod.rs")] -pub(in crate::imp) mod asm; - -// On most architectures, the architecture syscall instruction is fast, so use -// it directly. -#[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::imp) use self::asm as choose; - -// On 32-bit x86, use vDSO wrappers for all syscalls. We could use the -// architecture syscall instruction (`int 0x80`), but the vDSO kernel_vsyscall -// mechanism is much faster. -#[cfg(target_arch = "x86")] -pub(in crate::imp) use super::vdso_wrappers::x86_via_vdso as choose; - -// This would be the code for always using `int 0x80` on 32-bit x86. -//#[cfg(target_arch = "x86")] -//pub(in crate::imp) use self::asm as choose; - -// Macros for invoking system calls. -// -// These factor out: -// - Calling `nr` on the syscall number to convert it into `SyscallNumber`. -// - Calling `.into()` on each of the arguments to convert them into `ArgReg`. -// - Qualifying the `syscall*` and `__NR_*` identifiers. -// - Counting the number of arguments. -macro_rules! syscall { - ($nr:ident) => { - $crate::imp::arch::choose::syscall0($crate::imp::reg::nr(linux_raw_sys::general::$nr)) - }; - - ($nr:ident, $a0:expr) => { - $crate::imp::arch::choose::syscall1( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr) => { - $crate::imp::arch::choose::syscall2( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { - $crate::imp::arch::choose::syscall3( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => { - $crate::imp::arch::choose::syscall4( - $crate::imp::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::imp::arch::choose::syscall5( - $crate::imp::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::imp::arch::choose::syscall6( - $crate::imp::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::imp::arch::choose::syscall7( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - $a6.into(), - ) - }; -} - -macro_rules! syscall_readonly { - ($nr:ident) => { - $crate::imp::arch::choose::syscall0_readonly($crate::imp::reg::nr( - linux_raw_sys::general::$nr, - )) - }; - - ($nr:ident, $a0:expr) => { - $crate::imp::arch::choose::syscall1_readonly( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr) => { - $crate::imp::arch::choose::syscall2_readonly( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr) => { - $crate::imp::arch::choose::syscall3_readonly( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - ) - }; - - ($nr:ident, $a0:expr, $a1:expr, $a2:expr, $a3:expr) => { - $crate::imp::arch::choose::syscall4_readonly( - $crate::imp::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::imp::arch::choose::syscall5_readonly( - $crate::imp::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::imp::arch::choose::syscall6_readonly( - $crate::imp::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::imp::arch::choose::syscall7_readonly( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - $a1.into(), - $a2.into(), - $a3.into(), - $a4.into(), - $a5.into(), - $a6.into(), - ) - }; -} - -#[cfg(feature = "runtime")] -macro_rules! syscall_noreturn { - ($nr:ident, $a0:expr) => { - $crate::imp::arch::choose::syscall1_noreturn( - $crate::imp::reg::nr(linux_raw_sys::general::$nr), - $a0.into(), - ) - }; -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/aarch64.s b/vendor/rustix/src/imp/linux_raw/arch/outline/aarch64.s deleted file mode 100644 index 1fad2fa6d..000000000 --- a/vendor/rustix/src/imp/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/imp/linux_raw/arch/outline/arm.s b/vendor/rustix/src/imp/linux_raw/arch/outline/arm.s deleted file mode 100644 index 7001686f1..000000000 --- a/vendor/rustix/src/imp/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/imp/linux_raw/arch/outline/mips.s b/vendor/rustix/src/imp/linux_raw/arch/outline/mips.s deleted file mode 100644 index ab1bbfa2d..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/mips.s +++ /dev/null @@ -1,213 +0,0 @@ -# Assembly code for making mips64 syscalls. -# -# mips64 syscall argument register ordering is the same as the mips64 -# userspace argument register ordering except that the syscall number -# (nr) is passed in v0. -# -# 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" - .section .mdebug.abi32 - .previous - .abicalls - - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall0_nr_last -rustix_syscall0_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $4 - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall0_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall1_nr_last -rustix_syscall1_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $5 - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall1_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall1_noreturn_nr_last -rustix_syscall1_noreturn_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $5 - syscall - teq $zero, $zero - .end rustix_syscall1_noreturn_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall2_nr_last -rustix_syscall2_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $6 - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall2_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall3_nr_last -rustix_syscall3_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $7 - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall3_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall4_nr_last -rustix_syscall4_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - lw $2, 16($sp) - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall4_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall5_nr_last -rustix_syscall5_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - lw $2, 20($sp) - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall5_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall6_nr_last -rustix_syscall6_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - lw $2, 24($sp) - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .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 - .hidden rustix_syscall7_nr_last - .type rustix_syscall7_nr_last, @function - .set nomips16 - .set nomicromips - .ent rustix_syscall7_nr_last -rustix_syscall7_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - lw $2, 28($sp) - syscall - negu $8, $2 - jr $31 - movn $2, $8, $7 - .end rustix_syscall7_nr_last - .size rustix_syscall7_nr_last, .-rustix_syscall7_nr_last - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/mips64.s b/vendor/rustix/src/imp/linux_raw/arch/outline/mips64.s deleted file mode 100644 index 3c5e76e36..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/mips64.s +++ /dev/null @@ -1,189 +0,0 @@ -# Assembly code for making mips64 syscalls. -# -# mips64 syscall argument register ordering is the same as the mips64 -# userspace argument register ordering except that the syscall number -# (nr) is passed in v0. -# -# 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" - .section .mdebug.abi64 - .previous - .abicalls - - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall0_nr_last -rustix_syscall0_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $4 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall0_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall1_nr_last -rustix_syscall1_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $5 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall1_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall1_noreturn_nr_last -rustix_syscall1_noreturn_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $5 - syscall - teq $0, $0 - .end rustix_syscall1_noreturn_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall2_nr_last -rustix_syscall2_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $6 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall2_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall3_nr_last -rustix_syscall3_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $7 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall3_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall4_nr_last -rustix_syscall4_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $8 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall4_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall5_nr_last -rustix_syscall5_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $9 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall5_nr_last - .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 - .set nomips16 - .set nomicromips - .ent rustix_syscall6_nr_last -rustix_syscall6_nr_last: - .frame $sp,0,$31 - .mask 0x00000000,0 - .fmask 0x00000000,0 - .set noreorder - .set nomacro - move $2, $10 - syscall - dnegu $12, $2 - jr $31 - movn $2, $12, $7 - .end rustix_syscall6_nr_last - .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/mod.rs b/vendor/rustix/src/imp/linux_raw/arch/outline/mod.rs deleted file mode 100644 index ce1352751..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/mod.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! Declare functions defined in out-of-line ("outline") asm files. -//! -//! Kernel calling conventions differ from userspace calling conventions, -//! so we also define inline function wrappers which reorder the arguments -//! so that they match with the kernel convention as closely as possible, -//! to minimize the amount of out-of-line code we need. - -#[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::imp) use nr_last::*; -#[cfg(target_arch = "x86")] -pub(in crate::imp) use x86::*; diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/nr_last.rs b/vendor/rustix/src/imp/linux_raw/arch/outline/nr_last.rs deleted file mode 100644 index fdcd11021..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/nr_last.rs +++ /dev/null @@ -1,166 +0,0 @@ -//! Syscall wrappers for platforms which pass the syscall number specially. -//! -//! Rustix aims to minimize the amount of assembly code it needs. To that end, -//! this code reorders syscall arguments as close as feasible to the actual -//! syscall convention before calling the assembly functions. -//! -//! Many architectures use a convention where the syscall number is passed in a -//! special register, with the regular syscall arguments passed in either the -//! same or similar registers as the platform C convention. This code -//! approximates that order by passing the regular syscall arguments first, and -//! the syscall number last. That way, the outline assembly code typically just -//! needs to move the syscall number to its special register, and leave the -//! other arguments mostly as they are. - -#[cfg(target_arch = "mips")] -use crate::imp::reg::A6; -use crate::imp::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; - -// First we declare the actual assembly routines with `*_nr_last` names and -// reordered arguments. If the signatures or calling conventions are ever -// changed, the symbol names should also be updated accordingly, to avoid -// collisions with other versions of this crate. -// -// We don't define `_readonly` versions of these because we have no way to tell -// Rust that calls to our outline assembly are readonly. -extern "C" { - fn rustix_syscall0_nr_last(nr: SyscallNumber<'_>) -> RetReg; - fn rustix_syscall1_nr_last(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> RetReg; - fn rustix_syscall1_noreturn_nr_last(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> !; - fn rustix_syscall2_nr_last( - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall3_nr_last( - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall4_nr_last( - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall5_nr_last( - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall6_nr_last( - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - nr: SyscallNumber<'_>, - ) -> RetReg; - #[cfg(target_arch = "mips")] - fn rustix_syscall7_nr_last( - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - a6: ArgReg<'_, A6>, - nr: SyscallNumber<'_>, - ) -> RetReg; -} - -// Then we define inline wrapper functions that do the reordering. - -#[inline] -pub(in crate::imp) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { - rustix_syscall0_nr_last(nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - rustix_syscall1_nr_last(a0, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - rustix_syscall1_noreturn_nr_last(a0, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - rustix_syscall2_nr_last(a0, a1, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - rustix_syscall3_nr_last(a0, a1, a2, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - rustix_syscall4_nr_last(a0, a1, a2, a3, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - rustix_syscall5_nr_last(a0, a1, a2, a3, a4, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - rustix_syscall6_nr_last(a0, a1, a2, a3, a4, a5, nr) -} -#[cfg(target_arch = "mips")] -#[inline] -pub(in crate::imp) unsafe fn syscall7( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - a6: ArgReg<'_, A6>, -) -> RetReg { - rustix_syscall7_nr_last(a0, a1, a2, a3, a4, a5, a6, nr) -} - -// Then we define the `_readonly` versions of the wrappers. We don't have -// separate `_readonly` implementations, so these can just be aliases to -// their non-`_readonly` counterparts. -#[cfg(target_arch = "mips")] -pub(in crate::imp) use syscall7 as syscall7_readonly; -pub(in crate::imp) use { - syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly, - syscall3 as syscall3_readonly, syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, - syscall6 as syscall6_readonly, -}; diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/powerpc64.s b/vendor/rustix/src/imp/linux_raw/arch/outline/powerpc64.s deleted file mode 100644 index 29d4c0a95..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/powerpc64.s +++ /dev/null @@ -1,132 +0,0 @@ -# Assembly code for making powerpc64le syscalls. -# -# powerpc64le syscall argument register ordering is the same as the -# powerpc64le userspace argument register ordering except that the syscall -# number (nr) is passed in r0. -# -# outline.rs takes care of reordering the nr argument to the end for us, -# so we only need to move nr into r0. - - .file "powerpc64le.s" - .machine power8 - .abiversion 2 - - .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 - mr 0, 3 - sc - bnslr - neg 3, 3 - blr - .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 - mr 0, 4 - sc - bnslr - neg 3, 3 - blr - .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 - mr 0, 4 - sc - trap - .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 - mr 0, 5 - sc - bnslr - neg 3, 3 - blr - .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 - mr 0, 6 - sc - bnslr - neg 3, 3 - blr - .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 - mr 0, 7 - sc - bnslr - neg 3, 3 - blr - .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 - mr 0, 8 - sc - bnslr - neg 3, 3 - blr - .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 - mr 0, 9 - sc - bnslr - neg 3, 3 - blr - .cfi_endproc - .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/riscv64.s b/vendor/rustix/src/imp/linux_raw/arch/outline/riscv64.s deleted file mode 100644 index 28d692f7c..000000000 --- a/vendor/rustix/src/imp/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/imp/linux_raw/arch/outline/x86.rs b/vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs deleted file mode 100644 index 938a4a09d..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/x86.rs +++ /dev/null @@ -1,285 +0,0 @@ -//! Syscall wrappers for 32-bit x86. -//! -//! This module is similar to the `nr_last` module, except specialized for -//! 32-bit x86. -//! -//! The syscall convention passes all arguments in registers. The closest we -//! can easily get to that from Rust is to use the fastcall convention which -//! passes the first two arguments in `ecx` and `edx`, which are the second -//! and third Linux syscall arguments. To line them up, this function passes -//! the second and third syscall argument as the first and second argument to -//! the outline assembly, followed by the first syscall argument, and then the -//! rest of the syscall arguments. The assembly code still has to do some work, -//! but at least we can get up to two arguments into the right place for it. - -#![allow(dead_code, unused_imports)] - -use crate::imp::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; -use crate::imp::vdso_wrappers::SyscallType; - -// First we declare the actual assembly routines with `*_nr_last_fastcall` -// names and reordered arguments. If the signatures or calling conventions are -// ever changed, the symbol names should also be updated accordingly, to avoid -// collisions with other versions of this crate. -// -// We don't define `_readonly` versions of these because we have no way to tell -// Rust that calls to our outline assembly are readonly. -extern "fastcall" { - fn rustix_syscall0_nr_last_fastcall(nr: SyscallNumber<'_>) -> RetReg; - fn rustix_syscall1_nr_last_fastcall(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> RetReg; - fn rustix_syscall1_noreturn_nr_last_fastcall(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> !; - fn rustix_syscall2_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a0: ArgReg<'_, A0>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall3_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall4_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - a3: ArgReg<'_, A3>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall5_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - nr: SyscallNumber<'_>, - ) -> RetReg; - fn rustix_syscall6_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - nr: SyscallNumber<'_>, - ) -> RetReg; -} - -// Then we define inline wrapper functions that do the reordering. - -#[inline] -pub(in crate::imp) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { - rustix_syscall0_nr_last_fastcall(nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { - rustix_syscall1_nr_last_fastcall(a0, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { - rustix_syscall1_noreturn_nr_last_fastcall(a0, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall2( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - rustix_syscall2_nr_last_fastcall(a1, a0, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall3( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - rustix_syscall3_nr_last_fastcall(a1, a2, a0, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall4( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - rustix_syscall4_nr_last_fastcall(a1, a2, a0, a3, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall5( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - rustix_syscall5_nr_last_fastcall(a1, a2, a0, a3, a4, nr) -} -#[inline] -pub(in crate::imp) unsafe fn syscall6( - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - rustix_syscall6_nr_last_fastcall(a1, a2, a0, a3, a4, a5, nr) -} - -// Then we define the `_readonly` versions of the wrappers. We don't have -// separate `_readonly` implementations, so these can just be aliases to -// their non-`_readonly` counterparts. -pub(in crate::imp) use { - syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly, - syscall3 as syscall3_readonly, syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, - syscall6 as syscall6_readonly, -}; - -// x86 prefers to route all syscalls through the vDSO, though this isn't -// always possible, so it also has a special form for doing the dispatch. -// -// First we declare the actual assembly routines with `*_nr_last_fastcall` -// names and reordered arguments. If the signatures or calling conventions are -// ever changed, the symbol names should also be updated accordingly, to avoid -// collisions with other versions of this crate. -extern "fastcall" { - fn rustix_indirect_syscall0_nr_last_fastcall( - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; - fn rustix_indirect_syscall1_nr_last_fastcall( - a0: ArgReg<'_, A0>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; - fn rustix_indirect_syscall1_noreturn_nr_last_fastcall( - a0: ArgReg<'_, A0>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> !; - fn rustix_indirect_syscall2_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a0: ArgReg<'_, A0>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; - fn rustix_indirect_syscall3_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; - fn rustix_indirect_syscall4_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - a3: ArgReg<'_, A3>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; - fn rustix_indirect_syscall5_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; - fn rustix_indirect_syscall6_nr_last_fastcall( - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a0: ArgReg<'_, A0>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, - nr: SyscallNumber<'_>, - callee: SyscallType, - ) -> RetReg; -} - -// Then we define inline wrapper functions that do the reordering. - -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall0( - callee: SyscallType, - nr: SyscallNumber<'_>, -) -> RetReg { - rustix_indirect_syscall0_nr_last_fastcall(nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall1( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> RetReg { - rustix_indirect_syscall1_nr_last_fastcall(a0, nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall1_noreturn( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, -) -> ! { - rustix_indirect_syscall1_noreturn_nr_last_fastcall(a0, nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall2( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, -) -> RetReg { - rustix_indirect_syscall2_nr_last_fastcall(a1, a0, nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall3( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, -) -> RetReg { - rustix_indirect_syscall3_nr_last_fastcall(a1, a2, a0, nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall4( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, -) -> RetReg { - rustix_indirect_syscall4_nr_last_fastcall(a1, a2, a0, a3, nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall5( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, -) -> RetReg { - rustix_indirect_syscall5_nr_last_fastcall(a1, a2, a0, a3, a4, nr, callee) -} -#[inline] -pub(in crate::imp) unsafe fn indirect_syscall6( - callee: SyscallType, - nr: SyscallNumber<'_>, - a0: ArgReg<'_, A0>, - a1: ArgReg<'_, A1>, - a2: ArgReg<'_, A2>, - a3: ArgReg<'_, A3>, - a4: ArgReg<'_, A4>, - a5: ArgReg<'_, A5>, -) -> RetReg { - rustix_indirect_syscall6_nr_last_fastcall(a1, a2, a0, a3, a4, a5, nr, callee) -} diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/x86.s b/vendor/rustix/src/imp/linux_raw/arch/outline/x86.s deleted file mode 100644 index bda234e1a..000000000 --- a/vendor/rustix/src/imp/linux_raw/arch/outline/x86.s +++ /dev/null @@ -1,381 +0,0 @@ -// Assembly code for making x86 syscalls. -// -// On x86 we use the "fastcall" convention which passes the first two -// arguments in ecx and edx. Outline.rs reorders the arguments to put -// a1 and a2 in those registers so they we don't have to move them to -// set up the kernel convention. -// -// "fastcall" expects callee to pop argument stack space, so we use -// `ret imm` instructions to clean up the stack. We don't need callee -// cleanup per se, it just comes along with using "fastcall". - - .file "x86.s" - .intel_syntax noprefix - - .section .text.rustix_indirect_syscall0_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall0_nr_last_fastcall - .hidden rustix_indirect_syscall0_nr_last_fastcall - .type rustix_indirect_syscall0_nr_last_fastcall, @function -rustix_indirect_syscall0_nr_last_fastcall: - .cfi_startproc - mov eax,ecx - call edx - ret - .cfi_endproc - .size rustix_indirect_syscall0_nr_last_fastcall, .-rustix_indirect_syscall0_nr_last_fastcall - - .section .text.rustix_indirect_syscall1_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall1_nr_last_fastcall - .hidden rustix_indirect_syscall1_nr_last_fastcall - .type rustix_indirect_syscall1_nr_last_fastcall, @function -rustix_indirect_syscall1_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - .cfi_offset ebx, -8 - mov ebx,ecx - mov eax,edx - call DWORD PTR [esp+0x8] - pop ebx - .cfi_def_cfa_offset 4 - ret 0x4 - .cfi_endproc - .size rustix_indirect_syscall1_nr_last_fastcall, .-rustix_indirect_syscall1_nr_last_fastcall - - .section .text.rustix_indirect_syscall1_noreturn_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall1_noreturn_nr_last_fastcall - .hidden rustix_indirect_syscall1_noreturn_nr_last_fastcall - .type rustix_indirect_syscall1_noreturn_nr_last_fastcall, @function -rustix_indirect_syscall1_noreturn_nr_last_fastcall: - .cfi_startproc - mov ebx,ecx - mov eax,edx - call DWORD PTR [esp+0x4] - ud2 - .cfi_endproc - .size rustix_indirect_syscall1_noreturn_nr_last_fastcall, .-rustix_indirect_syscall1_noreturn_nr_last_fastcall - - .section .text.rustix_indirect_syscall2_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall2_nr_last_fastcall - .hidden rustix_indirect_syscall2_nr_last_fastcall - .type rustix_indirect_syscall2_nr_last_fastcall, @function -rustix_indirect_syscall2_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - .cfi_offset ebx, -8 - mov ebx,edx - mov eax,DWORD PTR [esp+0x8] - call DWORD PTR [esp+0xc] - pop ebx - .cfi_def_cfa_offset 4 - ret 0x8 - .cfi_endproc - .size rustix_indirect_syscall2_nr_last_fastcall, .-rustix_indirect_syscall2_nr_last_fastcall - - .section .text.rustix_indirect_syscall3_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall3_nr_last_fastcall - .hidden rustix_indirect_syscall3_nr_last_fastcall - .type rustix_indirect_syscall3_nr_last_fastcall, @function -rustix_indirect_syscall3_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0x8] - mov eax,DWORD PTR [esp+0xc] - call DWORD PTR [esp+0x10] - pop ebx - .cfi_def_cfa_offset 4 - ret 0xc - .cfi_endproc - .size rustix_indirect_syscall3_nr_last_fastcall, .-rustix_indirect_syscall3_nr_last_fastcall - - .section .text.rustix_indirect_syscall4_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall4_nr_last_fastcall - .hidden rustix_indirect_syscall4_nr_last_fastcall - .type rustix_indirect_syscall4_nr_last_fastcall, @function -rustix_indirect_syscall4_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - push esi - .cfi_def_cfa_offset 12 - .cfi_offset esi, -12 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0xc] - mov esi,DWORD PTR [esp+0x10] - mov eax,DWORD PTR [esp+0x14] - call DWORD PTR [esp+0x18] - pop esi - .cfi_def_cfa_offset 8 - pop ebx - .cfi_def_cfa_offset 4 - ret 0x10 - .cfi_endproc - .size rustix_indirect_syscall4_nr_last_fastcall, .-rustix_indirect_syscall4_nr_last_fastcall - - .section .text.rustix_indirect_syscall5_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall5_nr_last_fastcall - .hidden rustix_indirect_syscall5_nr_last_fastcall - .type rustix_indirect_syscall5_nr_last_fastcall, @function -rustix_indirect_syscall5_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - push esi - .cfi_def_cfa_offset 12 - push edi - .cfi_def_cfa_offset 16 - .cfi_offset edi, -16 - .cfi_offset esi, -12 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0x10] - mov esi,DWORD PTR [esp+0x14] - mov edi,DWORD PTR [esp+0x18] - mov eax,DWORD PTR [esp+0x1c] - call DWORD PTR [esp+0x20] - pop edi - .cfi_def_cfa_offset 12 - pop esi - .cfi_def_cfa_offset 8 - pop ebx - .cfi_def_cfa_offset 4 - ret 0x14 - .cfi_endproc - .size rustix_indirect_syscall5_nr_last_fastcall, .-rustix_indirect_syscall5_nr_last_fastcall - - .section .text.rustix_indirect_syscall6_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_indirect_syscall6_nr_last_fastcall - .hidden rustix_indirect_syscall6_nr_last_fastcall - .type rustix_indirect_syscall6_nr_last_fastcall, @function -rustix_indirect_syscall6_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - push esi - .cfi_def_cfa_offset 12 - push edi - .cfi_def_cfa_offset 16 - push ebp - .cfi_def_cfa_offset 20 - .cfi_offset ebp, -20 - .cfi_offset edi, -16 - .cfi_offset esi, -12 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0x14] - mov esi,DWORD PTR [esp+0x18] - mov edi,DWORD PTR [esp+0x1c] - mov ebp,DWORD PTR [esp+0x20] - mov eax,DWORD PTR [esp+0x24] - call DWORD PTR [esp+0x28] - pop ebp - .cfi_def_cfa_offset 16 - pop edi - .cfi_def_cfa_offset 12 - pop esi - .cfi_def_cfa_offset 8 - pop ebx - .cfi_def_cfa_offset 4 - ret 0x18 - .cfi_endproc - .size rustix_indirect_syscall6_nr_last_fastcall, .-rustix_indirect_syscall6_nr_last_fastcall - - .section .text.rustix_syscall0_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall0_nr_last_fastcall - .hidden rustix_syscall0_nr_last_fastcall - .type rustix_syscall0_nr_last_fastcall, @function -rustix_syscall0_nr_last_fastcall: - .cfi_startproc - mov eax,ecx - int 0x80 - ret - .cfi_endproc - .size rustix_syscall0_nr_last_fastcall, .-rustix_syscall0_nr_last_fastcall - - .section .text.rustix_syscall1_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall1_nr_last_fastcall - .hidden rustix_syscall1_nr_last_fastcall - .type rustix_syscall1_nr_last_fastcall, @function -rustix_syscall1_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - .cfi_offset ebx, -8 - mov eax,edx - mov ebx,ecx - int 0x80 - pop ebx - .cfi_def_cfa_offset 4 - ret - .cfi_endproc - .size rustix_syscall1_nr_last_fastcall, .-rustix_syscall1_nr_last_fastcall - - .section .text.rustix_syscall1_noreturn_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall1_noreturn_nr_last_fastcall - .hidden rustix_syscall1_noreturn_nr_last_fastcall - .type rustix_syscall1_noreturn_nr_last_fastcall, @function -rustix_syscall1_noreturn_nr_last_fastcall: - .cfi_startproc - mov eax,edx - mov ebx,ecx - int 0x80 - ud2 - .cfi_endproc - .size rustix_syscall1_noreturn_nr_last_fastcall, .-rustix_syscall1_noreturn_nr_last_fastcall - - .section .text.rustix_syscall2_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall2_nr_last_fastcall - .hidden rustix_syscall2_nr_last_fastcall - .type rustix_syscall2_nr_last_fastcall, @function -rustix_syscall2_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - .cfi_offset ebx, -8 - mov ebx,edx - mov eax,DWORD PTR [esp+0x8] - int 0x80 - pop ebx - .cfi_def_cfa_offset 4 - ret 0x4 - .cfi_endproc - .size rustix_syscall2_nr_last_fastcall, .-rustix_syscall2_nr_last_fastcall - - .section .text.rustix_syscall3_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall3_nr_last_fastcall - .hidden rustix_syscall3_nr_last_fastcall - .type rustix_syscall3_nr_last_fastcall, @function -rustix_syscall3_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0x8] - mov eax,DWORD PTR [esp+0xc] - int 0x80 - pop ebx - .cfi_def_cfa_offset 4 - ret 0x8 - .cfi_endproc - .size rustix_syscall3_nr_last_fastcall, .-rustix_syscall3_nr_last_fastcall - - .section .text.rustix_syscall4_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall4_nr_last_fastcall - .hidden rustix_syscall4_nr_last_fastcall - .type rustix_syscall4_nr_last_fastcall, @function -rustix_syscall4_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - push esi - .cfi_def_cfa_offset 12 - .cfi_offset esi, -12 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0xc] - mov esi,DWORD PTR [esp+0x10] - mov eax,DWORD PTR [esp+0x14] - int 0x80 - pop esi - .cfi_def_cfa_offset 8 - pop ebx - .cfi_def_cfa_offset 4 - ret 0xc - .cfi_endproc - .size rustix_syscall4_nr_last_fastcall, .-rustix_syscall4_nr_last_fastcall - - .section .text.rustix_syscall5_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall5_nr_last_fastcall - .hidden rustix_syscall5_nr_last_fastcall - .type rustix_syscall5_nr_last_fastcall, @function -rustix_syscall5_nr_last_fastcall: - .cfi_startproc - push ebx - .cfi_def_cfa_offset 8 - push edi - .cfi_def_cfa_offset 12 - push esi - .cfi_def_cfa_offset 16 - .cfi_offset esi, -16 - .cfi_offset edi, -12 - .cfi_offset ebx, -8 - mov ebx,DWORD PTR [esp+0x10] - mov esi,DWORD PTR [esp+0x14] - mov edi,DWORD PTR [esp+0x18] - mov eax,DWORD PTR [esp+0x1c] - int 0x80 - pop esi - .cfi_def_cfa_offset 12 - pop edi - .cfi_def_cfa_offset 8 - pop ebx - .cfi_def_cfa_offset 4 - ret 0x10 - .cfi_endproc - .size rustix_syscall5_nr_last_fastcall, .-rustix_syscall5_nr_last_fastcall - - .section .text.rustix_syscall6_nr_last_fastcall,"ax",@progbits - .p2align 4 - .weak rustix_syscall6_nr_last_fastcall - .hidden rustix_syscall6_nr_last_fastcall - .type rustix_syscall6_nr_last_fastcall, @function -rustix_syscall6_nr_last_fastcall: - .cfi_startproc - push ebp - .cfi_def_cfa_offset 8 - push ebx - .cfi_def_cfa_offset 12 - push edi - .cfi_def_cfa_offset 16 - push esi - .cfi_def_cfa_offset 20 - .cfi_offset esi, -20 - .cfi_offset edi, -16 - .cfi_offset ebx, -12 - .cfi_offset ebp, -8 - mov ebx,DWORD PTR [esp+0x14] - mov esi,DWORD PTR [esp+0x18] - mov edi,DWORD PTR [esp+0x1c] - mov ebp,DWORD PTR [esp+0x20] - mov eax,DWORD PTR [esp+0x24] - int 0x80 - pop esi - .cfi_def_cfa_offset 16 - pop edi - .cfi_def_cfa_offset 12 - pop ebx - .cfi_def_cfa_offset 8 - pop ebp - .cfi_def_cfa_offset 4 - ret 0x14 - .cfi_endproc - .size rustix_syscall6_nr_last_fastcall, .-rustix_syscall6_nr_last_fastcall - - .section .text.rustix_int_0x80,"ax",@progbits - .p2align 4 - .weak rustix_int_0x80 - .hidden rustix_int_0x80 - .type rustix_int_0x80, @function -rustix_int_0x80: - .cfi_startproc - int 0x80 - ret - .cfi_endproc - .size rustix_int_0x80, .-rustix_int_0x80 - - .section .note.GNU-stack,"",@progbits diff --git a/vendor/rustix/src/imp/linux_raw/arch/outline/x86_64.s b/vendor/rustix/src/imp/linux_raw/arch/outline/x86_64.s deleted file mode 100644 index 2beda323b..000000000 --- a/vendor/rustix/src/imp/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/imp/linux_raw/c.rs b/vendor/rustix/src/imp/linux_raw/c.rs deleted file mode 100644 index a6f0b8ff6..000000000 --- a/vendor/rustix/src/imp/linux_raw/c.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Adapt the Linux API to resemble a POSIX-style libc API. -//! -//! The linux_raw backend doesn't use actual libc; this just defines certain -//! types that are convenient to have defined. - -#![allow(unused_imports)] - -pub(crate) use linux_raw_sys::ctypes::*; -pub(crate) use linux_raw_sys::errno::EINVAL; -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, 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_LOOP, 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, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, - SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_LINGER, - SO_PASSCRED, SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD, - SO_TYPE, TCP_NODELAY, -}; diff --git a/vendor/rustix/src/imp/linux_raw/conv.rs b/vendor/rustix/src/imp/linux_raw/conv.rs deleted file mode 100644 index c80ad58cc..000000000 --- a/vendor/rustix/src/imp/linux_raw/conv.rs +++ /dev/null @@ -1,770 +0,0 @@ -//! Convert values to [`ArgReg`] and from [`RetReg`]. -//! -//! System call arguments and return values are all communicated with inline -//! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping -//! or being accidentally misused as they travel through the code, we wrap -//! them in [`ArgReg`] and [`RetReg`] structs. This file provides `From` -//! implementations and explicit conversion functions for converting values -//! into and out of these wrapper structs. -//! -//! # Safety -//! -//! Some of this code is `unsafe` in order to work with raw file descriptors, -//! and some is `unsafe` to interpret the values in a `RetReg`. -#![allow(unsafe_code)] - -use super::c; -use super::fd::{AsRawFd, BorrowedFd, FromRawFd, RawFd}; -#[cfg(not(debug_assertions))] -use super::io::errno::decode_usize_infallible; -#[cfg(feature = "runtime")] -use super::io::errno::try_decode_error; -#[cfg(target_pointer_width = "64")] -use super::io::errno::try_decode_u64; -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; -use crate::ffi::CStr; -use crate::fs::{FileType, Mode, OFlags}; -use crate::io::{self, OwnedFd}; -use crate::process::{Pid, Resource, Signal}; -use crate::utils::{as_mut_ptr, as_ptr}; -use core::mem::MaybeUninit; -use core::ptr::null_mut; -#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] -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")] -use linux_raw_sys::general::O_LARGEFILE; - -/// Convert `SYS_*` constants for socketcall. -#[cfg(target_arch = "x86")] -#[inline] -pub(super) fn x86_sys<'a, Num: ArgNumber>(sys: u32) -> ArgReg<'a, Num> { - pass_usize(sys as usize) -} - -/// Pass the "low" half of the endian-specific memory encoding of a `u64`, for -/// 32-bit architectures. -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) fn lo<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> { - #[cfg(target_endian = "little")] - let x = x >> 32; - #[cfg(target_endian = "big")] - let x = x & 0xffff_ffff; - - pass_usize(x as usize) -} - -/// Pass the "high" half of the endian-specific memory encoding of a `u64`, for -/// 32-bit architectures. -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) fn hi<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> { - #[cfg(target_endian = "little")] - let x = x & 0xffff_ffff; - #[cfg(target_endian = "big")] - let x = x >> 32; - - pass_usize(x as usize) -} - -/// Pass a zero, or null, argument. -#[inline] -pub(super) fn zero<'a, Num: ArgNumber>() -> ArgReg<'a, Num> { - raw_arg(null_mut()) -} - -/// Pass the `mem::size_of` of a type. -#[inline] -pub(super) fn size_of<'a, T: Sized, Num: ArgNumber>() -> ArgReg<'a, Num> { - pass_usize(core::mem::size_of::()) -} - -/// Pass an arbitrary `usize` value. -/// -/// For passing pointers, use `void_star` or other functions which take a raw -/// pointer instead of casting to `usize`, so that provenance is preserved. -#[inline] -pub(super) fn pass_usize<'a, Num: ArgNumber>(t: usize) -> ArgReg<'a, Num> { - raw_arg(t as *mut _) -} - -impl<'a, Num: ArgNumber, T> From<*mut T> for ArgReg<'a, Num> { - #[inline] - fn from(c: *mut T) -> ArgReg<'a, Num> { - raw_arg(c.cast()) - } -} - -impl<'a, Num: ArgNumber, T> From<*const T> for ArgReg<'a, Num> { - #[inline] - fn from(c: *const T) -> ArgReg<'a, Num> { - let mut_ptr = c as *mut T; - raw_arg(mut_ptr.cast()) - } -} - -impl<'a, Num: ArgNumber> From<&'a CStr> for ArgReg<'a, Num> { - #[inline] - fn from(c: &'a CStr) -> Self { - let mut_ptr = c.as_ptr() as *mut u8; - raw_arg(mut_ptr.cast()) - } -} - -impl<'a, Num: ArgNumber> From> for ArgReg<'a, Num> { - #[inline] - fn from(t: Option<&'a CStr>) -> Self { - raw_arg(match t { - Some(s) => { - let mut_ptr = s.as_ptr() as *mut u8; - mut_ptr.cast() - } - None => null_mut(), - }) - } -} - -/// Pass a borrowed file-descriptor argument. -impl<'a, Num: ArgNumber> From> 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. - unsafe { raw_fd(fd.as_raw_fd()) } - } -} - -/// Pass a raw file-descriptor argument. Most users should use [`ArgReg::from`] -/// instead, to preserve I/O safety as long as possible. -/// -/// # Safety -/// -/// `fd` must be a valid open file descriptor. -#[inline] -pub(super) unsafe fn raw_fd<'a, Num: ArgNumber>(fd: RawFd) -> ArgReg<'a, Num> { - // Use `no_fd` when passing `-1` is intended. - 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")] - debug_assert_ne!( - fd, - crate::io_uring::io_uring_register_files_skip().as_raw_fd() - ); - - // Linux doesn't look at the high bits beyond the `c_int`, so use - // zero-extension rather than sign-extension because it's a smaller - // instruction. - let fd: c::c_int = fd; - pass_usize(fd as c::c_uint as usize) -} - -/// Deliberately pass `-1` to a file-descriptor argument, for system calls -/// like `mmap` where this indicates the argument is omitted. -#[inline] -pub(super) fn no_fd<'a, Num: ArgNumber>() -> ArgReg<'a, Num> { - pass_usize(!0_usize) -} - -#[inline] -pub(super) fn slice_just_addr(v: &[T]) -> ArgReg { - let mut_ptr = v.as_ptr() as *mut T; - raw_arg(mut_ptr.cast()) -} - -#[inline] -pub(super) fn slice( - v: &[T], -) -> (ArgReg, ArgReg) { - (slice_just_addr(v), pass_usize(v.len())) -} - -#[inline] -pub(super) fn slice_mut( - v: &mut [T], -) -> (ArgReg, ArgReg) { - (raw_arg(v.as_mut_ptr().cast()), pass_usize(v.len())) -} - -#[inline] -pub(super) fn by_ref(t: &T) -> ArgReg { - let mut_ptr = as_ptr(t) as *mut T; - raw_arg(mut_ptr.cast()) -} - -#[inline] -pub(super) fn by_mut(t: &mut T) -> ArgReg { - raw_arg(as_mut_ptr(t).cast()) -} - -/// Convert an optional mutable reference into a `usize` for passing to a -/// syscall. -#[inline] -pub(super) fn opt_mut(t: Option<&mut T>) -> ArgReg { - // This optimizes into the equivalent of `transmute(t)`, and has the - // advantage of not requiring `unsafe`. - match t { - Some(t) => by_mut(t), - None => raw_arg(null_mut()), - } -} - -/// Convert an optional immutable reference into a `usize` for passing to a -/// syscall. -#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] -#[inline] -pub(super) fn opt_ref<'a, T: Sized, Num: ArgNumber>(t: Option<&'a T>) -> ArgReg<'a, Num> { - // This optimizes into the equivalent of `transmute(t)`, and has the - // advantage of not requiring `unsafe`. - match t { - Some(t) => by_ref(t), - None => raw_arg(null_mut()), - } -} - -/// Convert a `c_int` into an `ArgReg`. -/// -/// Be sure to use `raw_fd` to pass `RawFd` values. -#[inline] -pub(super) fn c_int<'a, Num: ArgNumber>(i: c::c_int) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -/// Convert a `c_uint` into an `ArgReg`. -#[inline] -pub(super) fn c_uint<'a, Num: ArgNumber>(i: c::c_uint) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn loff_t<'a, Num: ArgNumber>(i: __kernel_loff_t) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn loff_t_from_u64<'a, Num: ArgNumber>(i: u64) -> ArgReg<'a, Num> { - // `loff_t` is signed, but syscalls which expect `loff_t` return `EINVAL` - // if it's outside the signed `i64` range, so we can silently cast. - pass_usize(i as usize) -} - -#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(i: ClockId) -> Self { - pass_usize(i as __kernel_clockid_t as usize) - } -} - -#[cfg(feature = "time")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(i: TimerfdClockId) -> Self { - pass_usize(i as __kernel_clockid_t as usize) - } -} - -#[cfg(feature = "net")] -#[inline] -pub(super) fn socklen_t<'a, Num: ArgNumber>(i: socklen_t) -> ArgReg<'a, Num> { - pass_usize(i as usize) -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(mode: Mode) -> Self { - pass_usize(mode.bits() 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 for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::AtFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::MemfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::RenameFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::StatxFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::FdFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::PipeFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::DupFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::ReadWriteFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::EventfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io::epoll::CreateFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::ProtFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::MsyncFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::MremapFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::MlockFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::MapFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::MprotectFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::imp::mm::types::UserfaultfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(cmd: crate::imp::process::types::MembarrierCommand) -> Self { - c_uint(cmd as u32) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(cpuid: crate::process::Cpuid) -> Self { - c_uint(cpuid.as_raw()) - } -} - -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> ArgReg<'a, Num> { - pass_usize(dev as usize) -} - -#[cfg(target_pointer_width = "32")] -#[inline] -pub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> io::Result> { - use core::convert::TryInto; - Ok(pass_usize(dev.try_into().map_err(|_err| io::Errno::INVAL)?)) -} - -#[cfg(target_pointer_width = "32")] -#[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")] -#[inline] -const fn oflags_bits(oflags: OFlags) -> c::c_uint { - oflags.bits() -} - -impl<'a, Num: ArgNumber> From 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] -pub(super) fn oflags_for_open_how(oflags: OFlags) -> u64 { - u64::from(oflags_bits(oflags)) -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::fs::FallocateFlags) -> Self { - c_uint(flags.bits()) - } -} - -/// Convert a `Resource` into a syscall argument. -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(resource: Resource) -> Self { - c_uint(resource as c::c_uint) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(pid: Pid) -> Self { - pass_usize(pid.as_raw_nonzero().get() as usize) - } -} - -#[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) -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(sig: Signal) -> Self { - pass_usize(sig as usize) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(advice: crate::fs::Advice) -> Self { - c_uint(advice as c::c_uint) - } -} - -impl<'a, Num: ArgNumber> From 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 for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::io_uring::IoringEnterFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "time")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::time::TimerfdFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "time")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::time::TimerfdTimerFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "rand")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::rand::GetRandomFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::net::RecvFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::net::SendFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(flags: crate::net::AcceptFlags) -> Self { - c_uint(flags.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(family: crate::net::AddressFamily) -> Self { - c_uint(family.0.into()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From<(crate::net::SocketType, crate::net::SocketFlags)> - for ArgReg<'a, Num> -{ - #[inline] - fn from(pair: (crate::net::SocketType, crate::net::SocketFlags)) -> Self { - c_uint(pair.0 .0 | pair.1.bits()) - } -} - -#[cfg(feature = "thread")] -impl<'a, Num: ArgNumber> From<(crate::thread::FutexOperation, crate::thread::FutexFlags)> - for ArgReg<'a, Num> -{ - #[inline] - fn from(pair: (crate::thread::FutexOperation, crate::thread::FutexFlags)) -> Self { - c_uint(pair.0 as u32 | pair.1.bits()) - } -} - -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(access: crate::fs::Access) -> Self { - c_uint(access.bits()) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(type_: crate::net::SocketType) -> Self { - c_uint(type_.0) - } -} - -#[cfg(feature = "net")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { - #[inline] - fn from(protocol: crate::net::Protocol) -> Self { - c_uint(protocol.0) - } -} - -impl<'a, Num: ArgNumber, T> From<&'a mut MaybeUninit> for ArgReg<'a, Num> { - #[inline] - fn from(t: &'a mut MaybeUninit) -> Self { - raw_arg(t.as_mut_ptr().cast()) - } -} - -/// Convert a `usize` returned from a syscall that effectively returns `()` on -/// success. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// just returns 0 on success. -#[inline] -pub(super) unsafe fn ret(raw: RetReg) -> io::Result<()> { - try_decode_void(raw) -} - -/// Convert a `usize` returned from a syscall that doesn't return on success. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// doesn't return on success. -#[cfg(feature = "runtime")] -#[inline] -pub(super) unsafe fn ret_error(raw: RetReg) -> io::Errno { - try_decode_error(raw) -} - -/// Convert a `usize` returned from a syscall that effectively always returns -/// `()`. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// always returns `()`. -#[inline] -pub(super) unsafe fn ret_infallible(raw: RetReg) { - #[cfg(debug_assertions)] - { - try_decode_void(raw).unwrap() - } - #[cfg(not(debug_assertions))] - drop(raw); -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `c_int` on success. -#[inline] -pub(super) fn ret_c_int(raw: RetReg) -> io::Result { - try_decode_c_int(raw) -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `c_uint` on success. -#[inline] -pub(super) fn ret_c_uint(raw: RetReg) -> io::Result { - try_decode_c_uint(raw) -} - -/// Convert a `usize` returned from a syscall that effectively returns a `u64` -/// on success. -#[cfg(target_pointer_width = "64")] -#[inline] -pub(super) fn ret_u64(raw: RetReg) -> io::Result { - try_decode_u64(raw) -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `usize` on success. -#[inline] -pub(super) fn ret_usize(raw: RetReg) -> io::Result { - try_decode_usize(raw) -} - -/// Convert a `usize` returned from a syscall that effectively always -/// returns a `usize`. -/// -/// # Safety -/// -/// This function must only be used with return values from infallible -/// syscalls. -#[inline] -pub(super) unsafe fn ret_usize_infallible(raw: RetReg) -> usize { - #[cfg(debug_assertions)] - { - try_decode_usize(raw).unwrap() - } - #[cfg(not(debug_assertions))] - { - decode_usize_infallible(raw) - } -} - -/// Convert a `usize` returned from a syscall that effectively returns an -/// `OwnedFd` on success. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// returns an owned file descriptor. -#[inline] -pub(super) unsafe fn ret_owned_fd(raw: RetReg) -> io::Result { - let raw_fd = try_decode_raw_fd(raw)?; - Ok(OwnedFd::from(crate::imp::fd::OwnedFd::from_raw_fd(raw_fd))) -} - -/// Convert the return value of `dup2` and `dup3`. -/// -/// When these functions succeed, they return the same value as their second -/// argument, so we don't construct a new `OwnedFd`. -/// -/// # Safety -/// -/// The caller must ensure that this is the return value of a syscall which -/// returns a file descriptor. -#[inline] -pub(super) unsafe fn ret_discarded_fd(raw: RetReg) -> io::Result<()> { - let _raw_fd = try_decode_raw_fd(raw)?; - Ok(()) -} - -/// Convert a `usize` returned from a syscall that effectively returns a -/// `*mut c_void` on success. -#[inline] -pub(super) fn ret_void_star(raw: RetReg) -> io::Result<*mut c::c_void> { - try_decode_void_star(raw) -} diff --git a/vendor/rustix/src/imp/linux_raw/elf.rs b/vendor/rustix/src/imp/linux_raw/elf.rs deleted file mode 100644 index 7b9bb3245..000000000 --- a/vendor/rustix/src/imp/linux_raw/elf.rs +++ /dev/null @@ -1,172 +0,0 @@ -//! The ELF ABI. - -#![allow(non_snake_case)] - -pub(super) const SELFMAG: usize = 4; -pub(super) const ELFMAG: [u8; SELFMAG] = [0x7f, b'E', b'L', b'F']; -pub(super) const EI_CLASS: usize = 4; -pub(super) const EI_DATA: usize = 5; -pub(super) const EI_VERSION: usize = 6; -pub(super) const EI_OSABI: usize = 7; -pub(super) const EI_ABIVERSION: usize = 8; -pub(super) const EV_CURRENT: u8 = 1; -#[cfg(target_pointer_width = "32")] -pub(super) const ELFCLASS: u8 = 1; // ELFCLASS32 -#[cfg(target_pointer_width = "64")] -pub(super) const ELFCLASS: u8 = 2; // ELFCLASS64 -#[cfg(target_endian = "little")] -pub(super) const ELFDATA: u8 = 1; // ELFDATA2LSB -#[cfg(target_endian = "big")] -pub(super) const ELFDATA: u8 = 2; // ELFDATA2MSB -pub(super) const ELFOSABI_SYSV: u8 = 0; -pub(super) const ELFOSABI_LINUX: u8 = 3; -// At present all of our supported platforms use 0. -pub(super) const ELFABIVERSION: u8 = 0; -pub(super) const ET_DYN: u16 = 3; -pub(super) const EI_NIDENT: usize = 16; -pub(super) const SHN_UNDEF: u16 = 0; -pub(super) const SHN_ABS: u16 = 0xfff1; -pub(super) const PN_XNUM: u16 = 0xffff; -pub(super) const PT_LOAD: u32 = 1; -pub(super) const PT_DYNAMIC: u32 = 2; -pub(super) const PT_INTERP: u32 = 3; -pub(super) const PT_PHDR: u32 = 6; -pub(super) const PT_TLS: u32 = 7; -pub(super) const PT_GNU_STACK: u32 = 0x6474_e551; -pub(super) const PT_GNU_RELRO: u32 = 0x6474_e552; -pub(super) const PF_X: u32 = 1; -pub(super) const PF_W: u32 = 2; -pub(super) const PF_R: u32 = 4; -pub(super) const DT_NULL: i32 = 0; -pub(super) const DT_HASH: i32 = 4; -pub(super) const DT_STRTAB: i32 = 5; -pub(super) const DT_SYMTAB: i32 = 6; -pub(super) const DT_SYMENT: i32 = 11; -pub(super) const DT_VERSYM: i32 = 0x6fff_fff0; -pub(super) const DT_VERDEF: i32 = 0x6fff_fffc; -pub(super) const STB_WEAK: u8 = 2; -pub(super) const STB_GLOBAL: u8 = 1; -pub(super) const STT_NOTYPE: u8 = 0; -pub(super) const STT_FUNC: u8 = 2; -pub(super) const STN_UNDEF: u32 = 0; -pub(super) const VER_FLG_BASE: u16 = 0x1; -pub(super) const VER_DEF_CURRENT: u16 = 1; -pub(super) const STV_DEFAULT: u8 = 0; -#[cfg(target_arch = "arm")] -pub(super) const EM_CURRENT: u16 = 40; // EM_ARM -#[cfg(target_arch = "x86")] -pub(super) const EM_CURRENT: u16 = 3; // EM_386 -#[cfg(target_arch = "powerpc64")] -pub(super) const EM_CURRENT: u16 = 21; // EM_PPC64 -#[cfg(any(target_arch = "mips", target_arch = "mips64"))] -pub(super) const EM_CURRENT: u16 = 8; // EM_MIPS -#[cfg(target_arch = "x86_64")] -pub(super) const EM_CURRENT: u16 = 62; // EM_X86_64 -#[cfg(target_arch = "aarch64")] -pub(super) const EM_CURRENT: u16 = 183; // EM_AARCH64 -#[cfg(target_arch = "riscv64")] -pub(super) const EM_CURRENT: u16 = 243; // EM_RISCV - -#[inline] -pub(super) const fn ELF_ST_VISIBILITY(o: u8) -> u8 { - o & 0x03 -} - -#[inline] -pub(super) const fn ELF_ST_BIND(val: u8) -> u8 { - val >> 4 -} - -#[inline] -pub(super) const fn ELF_ST_TYPE(val: u8) -> u8 { - val & 0xf -} - -#[repr(C)] -pub(super) struct Elf_Ehdr { - pub(super) e_ident: [u8; EI_NIDENT], - pub(super) e_type: u16, - pub(super) e_machine: u16, - pub(super) e_version: u32, - pub(super) e_entry: usize, - pub(super) e_phoff: usize, - pub(super) e_shoff: usize, - pub(super) e_flags: u32, - pub(super) e_ehsize: u16, - pub(super) e_phentsize: u16, - pub(super) e_phnum: u16, - pub(super) e_shentsize: u16, - pub(super) e_shnum: u16, - pub(super) e_shstrndx: u16, -} - -#[cfg(target_pointer_width = "32")] -#[repr(C)] -pub(super) struct Elf_Phdr { - pub(super) p_type: u32, - pub(super) p_offset: usize, - pub(super) p_vaddr: usize, - pub(super) p_paddr: usize, - pub(super) p_filesz: usize, - pub(super) p_memsz: usize, - pub(super) p_flags: u32, - pub(super) p_align: usize, -} - -#[cfg(target_pointer_width = "64")] -#[repr(C)] -pub(super) struct Elf_Phdr { - pub(super) p_type: u32, - pub(super) p_flags: u32, - pub(super) p_offset: usize, - pub(super) p_vaddr: usize, - pub(super) p_paddr: usize, - pub(super) p_filesz: usize, - pub(super) p_memsz: usize, - pub(super) p_align: usize, -} - -#[cfg(target_pointer_width = "32")] -#[repr(C)] -pub(super) struct Elf_Sym { - pub(super) st_name: u32, - pub(super) st_value: usize, - pub(super) st_size: usize, - pub(super) st_info: u8, - pub(super) st_other: u8, - pub(super) st_shndx: u16, -} - -#[cfg(target_pointer_width = "64")] -#[repr(C)] -pub(super) struct Elf_Sym { - pub(super) st_name: u32, - pub(super) st_info: u8, - pub(super) st_other: u8, - pub(super) st_shndx: u16, - pub(super) st_value: usize, - pub(super) st_size: usize, -} - -#[repr(C)] -pub(super) struct Elf_Dyn { - pub(super) d_tag: i32, - pub(super) d_val: usize, -} - -#[repr(C)] -pub(super) struct Elf_Verdef { - pub(super) vd_version: u16, - pub(super) vd_flags: u16, - pub(super) vd_ndx: u16, - pub(super) vd_cnt: u16, - pub(super) vd_hash: u32, - pub(super) vd_aux: u32, - pub(super) vd_next: u32, -} - -#[repr(C)] -pub(super) struct Elf_Verdaux { - pub(super) vda_name: u32, - pub(super) _vda_next: u32, -} diff --git a/vendor/rustix/src/imp/linux_raw/fs/dir.rs b/vendor/rustix/src/imp/linux_raw/fs/dir.rs deleted file mode 100644 index 64f5aa652..000000000 --- a/vendor/rustix/src/imp/linux_raw/fs/dir.rs +++ /dev/null @@ -1,213 +0,0 @@ -use crate::fd::{AsFd, BorrowedFd}; -use crate::ffi::{CStr, CString}; -use crate::fs::{fcntl_getfl, fstat, fstatfs, openat, FileType, Mode, OFlags, Stat, StatFs}; -use crate::io::{self, OwnedFd}; -use crate::process::fchdir; -use crate::utils::as_ptr; -use alloc::borrow::ToOwned; -use alloc::vec::Vec; -use core::fmt; -use core::mem::size_of; -use linux_raw_sys::general::{linux_dirent64, SEEK_SET}; - -/// `DIR*` -pub struct Dir { - /// The `OwnedFd` that we read directory entries from. - fd: OwnedFd, - - buf: Vec, - pos: usize, - next: Option, -} - -impl Dir { - /// Construct a `Dir` that reads entries from the given directory - /// file descriptor. - #[inline] - pub fn read_from(fd: Fd) -> io::Result { - Self::_read_from(fd.as_fd()) - } - - #[inline] - fn _read_from(fd: BorrowedFd<'_>) -> io::Result { - let flags = fcntl_getfl(fd)?; - let fd_for_dir = openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty())?; - - Ok(Self { - fd: fd_for_dir, - buf: Vec::new(), - pos: 0, - next: None, - }) - } - - /// `rewinddir(self)` - #[inline] - pub fn rewind(&mut self) { - self.pos = self.buf.len(); - self.next = Some(0); - } - - /// `readdir(self)`, where `None` means the end of the directory. - pub fn read(&mut self) -> Option> { - if let Some(next) = self.next.take() { - match crate::imp::fs::syscalls::_seek(self.fd.as_fd(), next as i64, SEEK_SET) { - Ok(_) => (), - Err(err) => return Some(Err(err)), - } - } - - // Compute linux_dirent64 field offsets. - let z = linux_dirent64 { - d_ino: 0_u64, - d_off: 0_i64, - d_type: 0_u8, - d_reclen: 0_u16, - d_name: Default::default(), - }; - let base = as_ptr(&z) as usize; - let offsetof_d_reclen = (as_ptr(&z.d_reclen) as usize) - base; - let offsetof_d_name = (as_ptr(&z.d_name) as usize) - base; - let offsetof_d_ino = (as_ptr(&z.d_ino) as usize) - base; - let offsetof_d_type = (as_ptr(&z.d_type) as usize) - base; - - // Test if we need more entries, and if so, read more. - if self.buf.len() - self.pos < size_of::() { - match self.read_more()? { - Ok(()) => (), - Err(e) => return Some(Err(e)), - } - } - - // We successfully read an entry. Extract the fields. - let pos = self.pos; - - // Do an unaligned u16 load. - let d_reclen = u16::from_ne_bytes([ - self.buf[pos + offsetof_d_reclen], - self.buf[pos + offsetof_d_reclen + 1], - ]); - assert!(self.buf.len() - pos >= d_reclen as usize); - self.pos += d_reclen as usize; - - // Read the NUL-terminated name from the `d_name` field. Without - // `unsafe`, we need to scan for the NUL twice: once to obtain a size - // for the slice, and then once within `CStr::from_bytes_with_nul`. - let name_start = pos + offsetof_d_name; - let name_len = self.buf[name_start..] - .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 = name.to_owned(); - assert!(name.as_bytes().len() <= self.buf.len() - name_start); - - // Do an unaligned u64 load. - let d_ino = u64::from_ne_bytes([ - self.buf[pos + offsetof_d_ino], - self.buf[pos + offsetof_d_ino + 1], - self.buf[pos + offsetof_d_ino + 2], - self.buf[pos + offsetof_d_ino + 3], - self.buf[pos + offsetof_d_ino + 4], - self.buf[pos + offsetof_d_ino + 5], - self.buf[pos + offsetof_d_ino + 6], - self.buf[pos + offsetof_d_ino + 7], - ]); - - let d_type = self.buf[pos + offsetof_d_type]; - - // Check that our types correspond to the `linux_dirent64` types. - let _ = linux_dirent64 { - d_ino, - d_off: 0, - d_type, - d_reclen, - d_name: Default::default(), - }; - - Some(Ok(DirEntry { - d_ino, - d_type, - name, - })) - } - - fn read_more(&mut self) -> Option> { - // Capacity increment currently chosen by wild guess. - self.buf - .resize(self.buf.capacity() + 32 * size_of::(), 0); - self.pos = 0; - let nread = match crate::imp::fs::syscalls::getdents(self.fd.as_fd(), &mut self.buf) { - Ok(nread) => nread, - Err(err) => return Some(Err(err)), - }; - self.buf.resize(nread, 0); - if nread == 0 { - None - } else { - Some(Ok(())) - } - } - - /// `fstat(self)` - #[inline] - pub fn stat(&self) -> io::Result { - fstat(&self.fd) - } - - /// `fstatfs(self)` - #[inline] - pub fn statfs(&self) -> io::Result { - fstatfs(&self.fd) - } - - /// `fchdir(self)` - #[inline] - pub fn chdir(&self) -> io::Result<()> { - fchdir(&self.fd) - } -} - -impl Iterator for Dir { - type Item = io::Result; - - #[inline] - fn next(&mut self) -> Option { - Self::read(self) - } -} - -impl fmt::Debug for Dir { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Dir").field("fd", &self.fd).finish() - } -} - -/// `struct dirent` -#[derive(Debug)] -pub struct DirEntry { - d_ino: u64, - d_type: u8, - name: CString, -} - -impl DirEntry { - /// Returns the file name of this directory entry. - #[inline] - pub fn file_name(&self) -> &CStr { - &self.name - } - - /// Returns the type of this directory entry. - #[inline] - pub fn file_type(&self) -> FileType { - FileType::from_dirent_d_type(self.d_type) - } - - /// Return the inode number of this directory entry. - #[inline] - pub fn ino(&self) -> u64 { - self.d_ino - } -} diff --git a/vendor/rustix/src/imp/linux_raw/fs/makedev.rs b/vendor/rustix/src/imp/linux_raw/fs/makedev.rs deleted file mode 100644 index 284ba2f10..000000000 --- a/vendor/rustix/src/imp/linux_raw/fs/makedev.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::fs::Dev; - -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { - ((u64::from(maj) & 0xffff_f000_u64) << 32) - | ((u64::from(maj) & 0x0000_0fff_u64) << 8) - | ((u64::from(min) & 0xffff_ff00_u64) << 12) - | (u64::from(min) & 0x0000_00ff_u64) -} - -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { - (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 -} - -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { - (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 -} diff --git a/vendor/rustix/src/imp/linux_raw/fs/mod.rs b/vendor/rustix/src/imp/linux_raw/fs/mod.rs deleted file mode 100644 index 641e65744..000000000 --- a/vendor/rustix/src/imp/linux_raw/fs/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[cfg(any(feature = "fs", feature = "procfs"))] -pub(crate) mod dir; -pub(crate) mod makedev; -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/linux_raw/fs/syscalls.rs b/vendor/rustix/src/imp/linux_raw/fs/syscalls.rs deleted file mode 100644 index db1ecaaf6..000000000 --- a/vendor/rustix/src/imp/linux_raw/fs/syscalls.rs +++ /dev/null @@ -1,1391 +0,0 @@ -//! linux_raw syscalls supporting `rustix::fs`. -//! -//! # Safety -//! -//! See the `rustix::imp` 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_owned_fd, ret_usize, size_of, slice_mut, zero, -}; -#[cfg(target_pointer_width = "64")] -use super::super::conv::{loff_t, loff_t_from_u64, ret_u64}; -#[cfg(any( - target_arch = "aarch64", - target_arch = "riscv64", - target_arch = "mips64", - target_pointer_width = "32", -))] -use crate::fd::AsFd; -use crate::fd::{BorrowedFd, RawFd}; -use crate::ffi::CStr; -use crate::fs::{ - Access, Advice, AtFlags, FallocateFlags, FdFlags, FileType, FlockOperation, MemfdFlags, Mode, - OFlags, RenameFlags, ResolveFlags, SealFlags, Stat, StatFs, StatxFlags, Timestamps, -}; -use crate::io::{self, OwnedFd, SeekFrom}; -use crate::process::{Gid, Uid}; -use core::convert::TryInto; -use core::mem::MaybeUninit; -#[cfg(target_arch = "mips64")] -use linux_raw_sys::general::stat as linux_stat64; -use linux_raw_sys::general::{ - __kernel_timespec, open_how, statx, AT_EACCESS, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_NOFOLLOW, - F_ADD_SEALS, F_DUPFD, F_DUPFD_CLOEXEC, F_GETFD, F_GETFL, F_GETLEASE, F_GETOWN, F_GETPIPE_SZ, - F_GETSIG, F_GET_SEALS, F_SETFD, F_SETFL, F_SETPIPE_SZ, SEEK_CUR, SEEK_END, SEEK_SET, -}; -#[cfg(target_pointer_width = "32")] -use { - super::super::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 { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - { - openat(crate::fs::cwd().as_fd(), filename, flags, mode) - } - #[cfg(all( - target_pointer_width = "32", - 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)) - } -} - -#[inline] -pub(crate) fn openat( - dirfd: BorrowedFd<'_>, - filename: &CStr, - flags: OFlags, - mode: Mode, -) -> io::Result { - #[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)) - } -} - -#[inline] -pub(crate) fn openat2( - dirfd: BorrowedFd<'_>, - pathname: &CStr, - flags: OFlags, - mode: Mode, - resolve: ResolveFlags, -) -> io::Result { - #[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::() - )) - } - #[cfg(target_pointer_width = "64")] - 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::() - )) - } -} - -#[inline] -pub(crate) fn chmod(filename: &CStr, mode: Mode) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_fchmodat, - raw_fd(AT_FDCWD), - filename, - mode - )) - } -} - -#[inline] -pub(crate) fn chmodat(dirfd: BorrowedFd<'_>, filename: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fchmodat, dirfd, filename, mode)) } -} - -#[inline] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fchmod, fd, mode)) } -} - -#[inline] -pub(crate) fn chownat( - dirfd: BorrowedFd<'_>, - filename: &CStr, - owner: Option, - group: Option, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); - ret(syscall_readonly!( - __NR_fchownat, - dirfd, - filename, - c_uint(ow), - c_uint(gr), - flags - )) - } -} - -#[inline] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option, group: Option) -> io::Result<()> { - unsafe { - let (ow, gr) = crate::process::translate_fchown_args(owner, group); - ret(syscall_readonly!(__NR_fchown, fd, c_uint(ow), c_uint(gr))) - } -} - -#[inline] -pub(crate) fn mknodat( - dirfd: BorrowedFd<'_>, - filename: &CStr, - file_type: FileType, - mode: Mode, - dev: u64, -) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_mknodat, - dirfd, - filename, - (mode, file_type), - dev_t(dev)? - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_mknodat, - dirfd, - filename, - (mode, file_type), - dev_t(dev) - )) - } -} - -#[inline] -pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result { - let (whence, offset) = match pos { - SeekFrom::Start(pos) => { - let pos: u64 = pos; - // Silently cast; we'll get `EINVAL` if the value is negative. - (SEEK_SET, pos as i64) - } - SeekFrom::End(offset) => (SEEK_END, offset), - SeekFrom::Current(offset) => (SEEK_CUR, offset), - }; - _seek(fd, offset, whence) -} - -#[inline] -pub(crate) fn _seek(fd: BorrowedFd<'_>, offset: i64, whence: c::c_uint) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!( - __NR__llseek, - fd, - // Don't use the hi/lo functions here because Linux's llseek - // takes its 64-bit argument differently from everything else. - pass_usize((offset >> 32) as usize), - pass_usize(offset as usize), - &mut result, - c_uint(whence) - )) - .map(|()| result.assume_init()) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_u64(syscall_readonly!( - __NR_lseek, - fd, - loff_t(offset), - c_uint(whence) - )) - } -} - -#[inline] -pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result { - _seek(fd, 0, SEEK_CUR).map(|x| x as u64) -} - -#[inline] -pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { - // - #[cfg(all( - target_pointer_width = "32", - any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc"), - ))] - unsafe { - ret(syscall_readonly!( - __NR_ftruncate64, - fd, - zero(), - hi(length), - lo(length) - )) - } - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")), - ))] - unsafe { - ret(syscall_readonly!( - __NR_ftruncate64, - fd, - hi(length), - lo(length) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_ftruncate, - fd, - loff_t_from_u64(length) - )) - } -} - -#[inline] -pub(crate) fn fallocate( - fd: BorrowedFd<'_>, - mode: FallocateFlags, - offset: u64, - len: u64, -) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_fallocate, - fd, - mode, - hi(offset), - lo(offset), - hi(len), - lo(len) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fallocate, - fd, - mode, - loff_t_from_u64(offset), - loff_t_from_u64(len) - )) - } -} - -#[inline] -pub(crate) fn fadvise(fd: BorrowedFd<'_>, pos: u64, len: u64, advice: Advice) -> io::Result<()> { - // On ARM, the arguments are reordered so that the len and pos argument - // pairs are aligned. And ARM has a custom syscall code for this. - #[cfg(target_arch = "arm")] - unsafe { - ret(syscall_readonly!( - __NR_arm_fadvise64_64, - fd, - advice, - hi(pos), - lo(pos), - hi(len), - lo(len) - )) - } - - // On powerpc, the arguments are reordered as on ARM. - #[cfg(target_arch = "powerpc")] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64_64, - fd, - advice, - hi(pos), - lo(pos), - hi(len), - lo(len) - )) - } - // On mips, the arguments are not reordered, and padding is inserted - // instead to ensure alignment. - #[cfg(target_arch = "mips")] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64, - fd, - zero(), - hi(pos), - lo(pos), - hi(len), - lo(len), - advice - )) - } - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "arm", target_arch = "mips", target_arch = "powerpc")), - ))] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64_64, - fd, - hi(pos), - lo(pos), - hi(len), - lo(len), - advice - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fadvise64, - fd, - loff_t_from_u64(pos), - loff_t_from_u64(len), - advice - )) - } -} - -#[inline] -pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fsync, fd)) } -} - -#[inline] -pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fdatasync, fd)) } -} - -#[inline] -pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { - unsafe { ret(syscall!(__NR_flock, fd, c_uint(operation as c::c_uint))) } -} - -#[inline] -pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { - #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] - { - match statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { - Ok(x) => statx_to_stat(x), - Err(io::Errno::NOSYS) => fstat_old(fd), - Err(e) => Err(e), - } - } - - #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!(__NR_fstat, fd, &mut result)).map(|()| result.assume_init()) - } -} - -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn fstat_old(fd: BorrowedFd<'_>) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(target_arch = "mips64")] - unsafe { - ret(syscall!(__NR_fstat, fd, &mut result))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!(__NR_fstat64, fd, &mut result))?; - stat_to_stat(result.assume_init()) - } -} - -#[inline] -pub(crate) fn stat(filename: &CStr) -> io::Result { - #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] - { - match statx( - crate::fs::cwd().as_fd(), - filename, - AtFlags::empty(), - StatxFlags::BASIC_STATS, - ) { - Ok(x) => return statx_to_stat(x), - Err(io::Errno::NOSYS) => stat_old(filename), - Err(e) => return Err(e), - } - } - - #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - filename, - &mut result, - c_uint(0) - )) - .map(|()| result.assume_init()) - } -} - -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn stat_old(filename: &CStr) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(target_arch = "mips64")] - unsafe { - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - filename, - &mut result, - c_uint(0) - ))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_fstatat64, - raw_fd(AT_FDCWD), - filename, - &mut result, - c_uint(0) - ))?; - stat_to_stat(result.assume_init()) - } -} - -#[inline] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result { - #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] - { - match statx(dirfd, filename, flags, StatxFlags::BASIC_STATS) { - Ok(x) => return statx_to_stat(x), - Err(io::Errno::NOSYS) => statat_old(dirfd, filename, flags), - Err(e) => return Err(e), - } - } - - #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!( - __NR_newfstatat, - dirfd, - filename, - &mut result, - flags - )) - .map(|()| result.assume_init()) - } -} - -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn statat_old(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(target_arch = "mips64")] - unsafe { - ret(syscall!( - __NR_newfstatat, - dirfd, - filename, - &mut result, - flags - ))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_fstatat64, - dirfd, - filename, - &mut result, - flags - ))?; - stat_to_stat(result.assume_init()) - } -} - -#[inline] -pub(crate) fn lstat(filename: &CStr) -> io::Result { - #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] - { - match statx( - crate::fs::cwd().as_fd(), - filename, - AtFlags::SYMLINK_NOFOLLOW, - StatxFlags::BASIC_STATS, - ) { - Ok(x) => return statx_to_stat(x), - Err(io::Errno::NOSYS) => lstat_old(filename), - Err(e) => return Err(e), - } - } - - #[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - filename, - &mut result, - c_uint(AT_SYMLINK_NOFOLLOW) - )) - .map(|()| result.assume_init()) - } -} - -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn lstat_old(filename: &CStr) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(target_arch = "mips64")] - unsafe { - ret(syscall!( - __NR_newfstatat, - raw_fd(AT_FDCWD), - filename, - &mut result, - c_uint(AT_SYMLINK_NOFOLLOW) - ))?; - stat_to_stat(result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_fstatat64, - raw_fd(AT_FDCWD), - filename, - &mut result, - c_uint(AT_SYMLINK_NOFOLLOW) - ))?; - stat_to_stat(result.assume_init()) - } -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result { - Ok(Stat { - st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor), - st_mode: x.stx_mode.into(), - st_nlink: x.stx_nlink.into(), - st_uid: x.stx_uid.into(), - st_gid: x.stx_gid.into(), - st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor), - st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: x.stx_blksize.into(), - st_blocks: x.stx_blocks.into(), - st_atime: x - .stx_atime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_atime_nsec: x.stx_atime.tv_nsec.into(), - st_mtime: x - .stx_mtime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime_nsec: x.stx_mtime.tv_nsec.into(), - st_ctime: x - .stx_ctime - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime_nsec: x.stx_ctime.tv_nsec.into(), - st_ino: x.stx_ino.into(), - }) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -#[cfg(target_pointer_width = "32")] -fn stat_to_stat(s64: linux_raw_sys::general::stat64) -> io::Result { - Ok(Stat { - st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime: s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime_nsec: s64 - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime: s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mtime_nsec: s64 - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime: s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_ctime_nsec: s64 - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, - }) -} - -/// Convert from a Linux `stat` value to rustix's `Stat`. -#[cfg(target_arch = "mips64")] -fn stat_to_stat(s: linux_raw_sys::general::stat) -> io::Result { - Ok(Stat { - st_dev: s.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mode: s.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_nlink: s.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_uid: s.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_gid: s.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_rdev: s.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_size: s.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blksize: s.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_blocks: s.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime: s.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_atime_nsec: s - .st_atime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_mtime: s.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_mtime_nsec: s - .st_mtime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ctime: s.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, - st_ctime_nsec: s - .st_ctime_nsec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - st_ino: s.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, - }) -} - -#[inline] -pub(crate) fn statx( - dirfd: BorrowedFd<'_>, - pathname: &CStr, - flags: AtFlags, - mask: StatxFlags, -) -> io::Result { - unsafe { - let mut statx_buf = MaybeUninit::::uninit(); - ret(syscall!( - __NR_statx, - dirfd, - pathname, - flags, - mask, - &mut statx_buf - )) - .map(|()| statx_buf.assume_init()) - } -} - -#[inline] -pub(crate) fn is_statx_available() -> bool { - unsafe { - // Call `statx` with null pointers so that if it fails for any reason - // other than `EFAULT`, we know it's not supported. - matches!( - ret(syscall!( - __NR_statx, - raw_fd(AT_FDCWD), - zero(), - zero(), - zero(), - zero() - )), - Err(io::Errno::FAULT) - ) - } -} - -#[inline] -pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!( - __NR_fstatfs64, - fd, - size_of::(), - &mut result - )) - .map(|()| result.assume_init()) - } - - #[cfg(target_pointer_width = "64")] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!(__NR_fstatfs, fd, &mut result)).map(|()| result.assume_init()) - } -} - -#[inline] -pub(crate) fn statfs(filename: &CStr) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!( - __NR_statfs64, - filename, - size_of::(), - &mut result - )) - .map(|()| result.assume_init()) - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!(__NR_statfs, filename, &mut result)).map(|()| result.assume_init()) - } -} - -#[inline] -pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { - ret_usize(syscall!( - __NR_readlinkat, - raw_fd(AT_FDCWD), - path, - buf_addr_mut, - buf_len - )) - } -} - -#[inline] -pub(crate) fn readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, buf: &mut [u8]) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { - ret_usize(syscall!( - __NR_readlinkat, - dirfd, - path, - buf_addr_mut, - buf_len - )) - } -} - -#[inline] -pub(crate) fn fcntl_dupfd(fd: BorrowedFd<'_>, min: RawFd) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(F_DUPFD), - raw_fd(min) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(F_DUPFD), - raw_fd(min) - )) - } -} - -#[inline] -pub(crate) fn fcntl_dupfd_cloexec(fd: BorrowedFd<'_>, min: RawFd) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(F_DUPFD_CLOEXEC), - raw_fd(min) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(F_DUPFD_CLOEXEC), - raw_fd(min) - )) - } -} - -#[inline] -pub(crate) fn fcntl_getfd(fd: BorrowedFd<'_>) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFD))) - .map(FdFlags::from_bits_truncate) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFD))) - .map(FdFlags::from_bits_truncate) - } -} - -#[inline] -pub(crate) fn fcntl_setfd(fd: BorrowedFd<'_>, flags: FdFlags) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFD), flags)) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!(__NR_fcntl, fd, c_uint(F_SETFD), flags)) - } -} - -#[inline] -pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETFL))) - .map(OFlags::from_bits_truncate) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_c_uint(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETFL))) - .map(OFlags::from_bits_truncate) - } -} - -#[inline] -pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_SETFL), flags)) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!(__NR_fcntl, fd, c_uint(F_SETFL), flags)) - } -} - -#[inline] -pub(crate) fn fcntl_getlease(fd: BorrowedFd<'_>) -> io::Result { - #[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 { - #[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 { - #[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 { - #[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 { - #[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 { - #[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)) - } - #[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)) - } -} - -#[inline] -pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_fcntl64, - fd, - c_uint(F_ADD_SEALS), - seals - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_fcntl, - fd, - c_uint(F_ADD_SEALS), - seals - )) - } -} - -#[inline] -pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { - #[cfg(target_arch = "riscv64")] - unsafe { - ret(syscall_readonly!( - __NR_renameat2, - raw_fd(AT_FDCWD), - oldname, - raw_fd(AT_FDCWD), - newname, - c_uint(0) - )) - } - #[cfg(not(target_arch = "riscv64"))] - unsafe { - ret(syscall_readonly!( - __NR_renameat, - raw_fd(AT_FDCWD), - oldname, - raw_fd(AT_FDCWD), - newname - )) - } -} - -#[inline] -pub(crate) fn renameat( - old_dirfd: BorrowedFd<'_>, - oldname: &CStr, - new_dirfd: BorrowedFd<'_>, - newname: &CStr, -) -> io::Result<()> { - #[cfg(target_arch = "riscv64")] - unsafe { - ret(syscall_readonly!( - __NR_renameat2, - old_dirfd, - oldname, - new_dirfd, - newname, - c_uint(0) - )) - } - #[cfg(not(target_arch = "riscv64"))] - unsafe { - ret(syscall_readonly!( - __NR_renameat, - old_dirfd, - oldname, - new_dirfd, - newname - )) - } -} - -#[inline] -pub(crate) fn renameat2( - old_dirfd: BorrowedFd<'_>, - oldname: &CStr, - new_dirfd: BorrowedFd<'_>, - newname: &CStr, - flags: RenameFlags, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_renameat2, - old_dirfd, - oldname, - new_dirfd, - newname, - flags - )) - } -} - -#[inline] -pub(crate) fn unlink(pathname: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_unlinkat, - raw_fd(AT_FDCWD), - pathname, - 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)) } -} - -#[inline] -pub(crate) fn rmdir(pathname: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_unlinkat, - raw_fd(AT_FDCWD), - pathname, - c_uint(AT_REMOVEDIR) - )) - } -} - -#[inline] -pub(crate) fn link(oldname: &CStr, newname: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_linkat, - raw_fd(AT_FDCWD), - oldname, - raw_fd(AT_FDCWD), - newname, - c_uint(0) - )) - } -} - -#[inline] -pub(crate) fn linkat( - old_dirfd: BorrowedFd<'_>, - oldname: &CStr, - new_dirfd: BorrowedFd<'_>, - newname: &CStr, - flags: AtFlags, -) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_linkat, - old_dirfd, - oldname, - new_dirfd, - newname, - flags - )) - } -} - -#[inline] -pub(crate) fn symlink(oldname: &CStr, newname: &CStr) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_symlinkat, - oldname, - raw_fd(AT_FDCWD), - newname - )) - } -} - -#[inline] -pub(crate) fn symlinkat(oldname: &CStr, dirfd: BorrowedFd<'_>, newname: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_symlinkat, oldname, dirfd, newname)) } -} - -#[inline] -pub(crate) fn mkdir(pathname: &CStr, mode: Mode) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_mkdirat, - raw_fd(AT_FDCWD), - pathname, - mode - )) - } -} - -#[inline] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, pathname: &CStr, mode: Mode) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_mkdirat, dirfd, pathname, mode)) } -} - -#[inline] -pub(crate) fn getdents(fd: BorrowedFd<'_>, dirent: &mut [u8]) -> io::Result { - let (dirent_addr_mut, dirent_len) = slice_mut(dirent); - - unsafe { ret_usize(syscall!(__NR_getdents64, fd, dirent_addr_mut, dirent_len)) } -} - -#[inline] -pub(crate) fn utimensat( - dirfd: BorrowedFd<'_>, - pathname: &CStr, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - _utimensat(dirfd, Some(pathname), times, flags) -} - -#[inline] -fn _utimensat( - dirfd: BorrowedFd<'_>, - pathname: Option<&CStr>, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - // Assert that `Timestamps` has the expected layout. - let _ = unsafe { core::mem::transmute::(times.clone()) }; - - #[cfg(target_pointer_width = "32")] - unsafe { - match ret(syscall_readonly!( - __NR_utimensat_time64, - dirfd, - pathname, - by_ref(times), - flags - )) { - Err(io::Errno::NOSYS) => _utimensat_old(dirfd, pathname, times, flags), - otherwise => otherwise, - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_utimensat, - dirfd, - pathname, - by_ref(times), - flags - )) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn _utimensat_old( - dirfd: BorrowedFd<'_>, - pathname: Option<&CStr>, - times: &Timestamps, - flags: AtFlags, -) -> io::Result<()> { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - let old_times = [ - __kernel_old_timespec { - tv_sec: times - .last_access - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_access - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - __kernel_old_timespec { - tv_sec: times - .last_modification - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: times - .last_modification - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - ]; - // The length of the array is fixed and not passed into the syscall. - let old_times_addr = slice_just_addr(&old_times); - ret(syscall_readonly!( - __NR_utimensat, - dirfd, - pathname, - old_times_addr, - flags - )) -} - -#[inline] -pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { - _utimensat(fd, None, times, AtFlags::empty()) -} - -pub(crate) fn accessat( - dirfd: BorrowedFd<'_>, - path: &CStr, - access: Access, - flags: AtFlags, -) -> io::Result<()> { - // 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()) - { - return unsafe { ret(syscall_readonly!(__NR_faccessat, dirfd, path, access)) }; - } - - if flags.bits() != AT_EACCESS { - return Err(io::Errno::INVAL); - } - - // TODO: Use faccessat2 in newer Linux versions. - Err(io::Errno::NOSYS) -} - -#[inline] -pub(crate) fn copy_file_range( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: u64, -) -> io::Result { - let len: usize = len.try_into().unwrap_or(usize::MAX); - _copy_file_range(fd_in, off_in, fd_out, off_out, len, 0).map(|result| result as u64) -} - -#[inline] -fn _copy_file_range( - fd_in: BorrowedFd<'_>, - off_in: Option<&mut u64>, - fd_out: BorrowedFd<'_>, - off_out: Option<&mut u64>, - len: usize, - flags: c::c_uint, -) -> io::Result { - unsafe { - ret_usize(syscall!( - __NR_copy_file_range, - fd_in, - opt_mut(off_in), - fd_out, - opt_mut(off_out), - pass_usize(len), - c_uint(flags) - )) - } -} - -#[inline] -pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result { - unsafe { ret_owned_fd(syscall_readonly!(__NR_memfd_create, name, flags)) } -} - -#[inline] -pub(crate) fn sendfile( - out_fd: BorrowedFd<'_>, - in_fd: BorrowedFd<'_>, - offset: Option<&mut u64>, - count: usize, -) -> io::Result { - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall!( - __NR_sendfile64, - out_fd, - in_fd, - opt_mut(offset), - pass_usize(count) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_sendfile, - out_fd, - in_fd, - opt_mut(offset), - pass_usize(count) - )) - } -} diff --git a/vendor/rustix/src/imp/linux_raw/fs/types.rs b/vendor/rustix/src/imp/linux_raw/fs/types.rs deleted file mode 100644 index 959a5ee27..000000000 --- a/vendor/rustix/src/imp/linux_raw/fs/types.rs +++ /dev/null @@ -1,613 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `FD_*` constants for use with [`fcntl_getfd`] and [`fcntl_setfd`]. - /// - /// [`fcntl_getfd`]: crate::fs::fcntl_getfd - /// [`fcntl_setfd`]: crate::fs::fcntl_setfd - pub struct FdFlags: c::c_uint { - /// `FD_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::FD_CLOEXEC; - } -} - -bitflags! { - /// `*_OK` constants for use with [`accessat`]. - /// - /// [`accessat`]: fn.accessat.html - pub struct Access: c::c_uint { - /// `R_OK` - const READ_OK = linux_raw_sys::general::R_OK; - - /// `W_OK` - const WRITE_OK = linux_raw_sys::general::W_OK; - - /// `X_OK` - const EXEC_OK = linux_raw_sys::general::X_OK; - - /// `F_OK` - const EXISTS = linux_raw_sys::general::F_OK; - } -} - -bitflags! { - /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` - /// functions. - /// - /// [`openat`]: crate::fs::openat - /// [`statat`]: crate::fs::statat - pub struct AtFlags: c::c_uint { - /// `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_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; - - /// `AT_STATX_FORCE_SYNC` - const STATX_FORCE_SYNC = linux_raw_sys::general::AT_STATX_FORCE_SYNC; - - /// `AT_STATX_DONT_SYNC` - const STATX_DONT_SYNC = linux_raw_sys::general::AT_STATX_DONT_SYNC; - } -} - -bitflags! { - /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. - /// - /// [`openat`]: crate::fs::openat - /// [`chmodat`]: crate::fs::chmodat - /// [`fchmod`]: crate::fs::fchmod - pub struct Mode: RawMode { - /// `S_IRWXU` - const RWXU = linux_raw_sys::general::S_IRWXU; - - /// `S_IRUSR` - const RUSR = linux_raw_sys::general::S_IRUSR; - - /// `S_IWUSR` - const WUSR = linux_raw_sys::general::S_IWUSR; - - /// `S_IXUSR` - const XUSR = linux_raw_sys::general::S_IXUSR; - - /// `S_IRWXG` - const RWXG = linux_raw_sys::general::S_IRWXG; - - /// `S_IRGRP` - const RGRP = linux_raw_sys::general::S_IRGRP; - - /// `S_IWGRP` - const WGRP = linux_raw_sys::general::S_IWGRP; - - /// `S_IXGRP` - const XGRP = linux_raw_sys::general::S_IXGRP; - - /// `S_IRWXO` - const RWXO = linux_raw_sys::general::S_IRWXO; - - /// `S_IROTH` - const ROTH = linux_raw_sys::general::S_IROTH; - - /// `S_IWOTH` - const WOTH = linux_raw_sys::general::S_IWOTH; - - /// `S_IXOTH` - const XOTH = linux_raw_sys::general::S_IXOTH; - - /// `S_ISUID` - const SUID = linux_raw_sys::general::S_ISUID; - - /// `S_ISGID` - const SGID = linux_raw_sys::general::S_ISGID; - - /// `S_ISVTX` - const SVTX = linux_raw_sys::general::S_ISVTX; - } -} - -impl Mode { - /// Construct a `Mode` from the mode bits of the `st_mode` field of a - /// `Stat`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - Self::from_bits_truncate(st_mode) - } - - /// Construct an `st_mode` value from `Stat`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - self.bits() - } -} - -bitflags! { - /// `O_*` constants for use with [`openat`]. - /// - /// [`openat`]: crate::fs::openat - pub struct OFlags: c::c_uint { - /// `O_ACCMODE` - const ACCMODE = linux_raw_sys::general::O_ACCMODE; - - /// Similar to `ACCMODE`, but just includes the read/write flags, and - /// no other flags. - /// - /// Some implementations include `O_PATH` in `O_ACCMODE`, when - /// sometimes we really just want the read/write bits. Caution is - /// indicated, as the presence of `O_PATH` may mean that the read/write - /// bits don't have their usual meaning. - const RWMODE = linux_raw_sys::general::O_RDONLY | - linux_raw_sys::general::O_WRONLY | - linux_raw_sys::general::O_RDWR; - - /// `O_APPEND` - const APPEND = linux_raw_sys::general::O_APPEND; - - /// `O_CREAT` - #[doc(alias = "CREAT")] - const CREATE = linux_raw_sys::general::O_CREAT; - - /// `O_DIRECTORY` - const DIRECTORY = linux_raw_sys::general::O_DIRECTORY; - - /// `O_DSYNC`. Linux 2.6.32 only supports `O_SYNC`. - const DSYNC = linux_raw_sys::general::O_SYNC; - - /// `O_EXCL` - const EXCL = linux_raw_sys::general::O_EXCL; - - /// `O_FSYNC`. Linux 2.6.32 only supports `O_SYNC`. - const FSYNC = linux_raw_sys::general::O_SYNC; - - /// `O_NOFOLLOW` - const NOFOLLOW = linux_raw_sys::general::O_NOFOLLOW; - - /// `O_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - - /// `O_RDONLY` - const RDONLY = linux_raw_sys::general::O_RDONLY; - - /// `O_WRONLY` - const WRONLY = linux_raw_sys::general::O_WRONLY; - - /// `O_RDWR` - const RDWR = linux_raw_sys::general::O_RDWR; - - /// `O_NOCTTY` - const NOCTTY = linux_raw_sys::general::O_NOCTTY; - - /// `O_RSYNC`. Linux 2.6.32 only supports `O_SYNC`. - const RSYNC = linux_raw_sys::general::O_SYNC; - - /// `O_SYNC` - const SYNC = linux_raw_sys::general::O_SYNC; - - /// `O_TRUNC` - const TRUNC = linux_raw_sys::general::O_TRUNC; - - /// `O_PATH` - const PATH = linux_raw_sys::general::O_PATH; - - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - - /// `O_TMPFILE` - const TMPFILE = linux_raw_sys::general::O_TMPFILE; - - /// `O_NOATIME` - const NOATIME = linux_raw_sys::general::O_NOATIME; - } -} - -bitflags! { - /// `RESOLVE_*` constants for use with [`openat2`]. - /// - /// [`openat2`]: crate::fs::openat2 - #[derive(Default)] - pub struct ResolveFlags: u64 { - /// `RESOLVE_NO_XDEV` - const NO_XDEV = linux_raw_sys::general::RESOLVE_NO_XDEV as u64; - - /// `RESOLVE_NO_MAGICLINKS` - const NO_MAGICLINKS = linux_raw_sys::general::RESOLVE_NO_MAGICLINKS as u64; - - /// `RESOLVE_NO_SYMLINKS` - const NO_SYMLINKS = linux_raw_sys::general::RESOLVE_NO_SYMLINKS as u64; - - /// `RESOLVE_BENEATH` - const BENEATH = linux_raw_sys::general::RESOLVE_BENEATH as u64; - - /// `RESOLVE_IN_ROOT` - const IN_ROOT = linux_raw_sys::general::RESOLVE_IN_ROOT as u64; - - /// `RESOLVE_CACHED` (since Linux 5.12) - const CACHED = linux_raw_sys::general::RESOLVE_CACHED as u64; - } -} - -bitflags! { - /// `RENAME_*` constants for use with [`renameat_with`]. - /// - /// [`renameat_with`]: crate::fs::renameat_with - pub struct RenameFlags: c::c_uint { - /// `RENAME_EXCHANGE` - const EXCHANGE = linux_raw_sys::general::RENAME_EXCHANGE; - - /// `RENAME_NOREPLACE` - const NOREPLACE = linux_raw_sys::general::RENAME_NOREPLACE; - - /// `RENAME_WHITEOUT` - const WHITEOUT = linux_raw_sys::general::RENAME_WHITEOUT; - } -} - -/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. -/// -/// [`mknodat`]: crate::fs::mknodat -/// [`Stat`]: crate::fs::Stat -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum FileType { - /// `S_IFREG` - RegularFile = linux_raw_sys::general::S_IFREG as isize, - - /// `S_IFDIR` - Directory = linux_raw_sys::general::S_IFDIR as isize, - - /// `S_IFLNK` - Symlink = linux_raw_sys::general::S_IFLNK as isize, - - /// `S_IFIFO` - Fifo = linux_raw_sys::general::S_IFIFO as isize, - - /// `S_IFSOCK` - Socket = linux_raw_sys::general::S_IFSOCK as isize, - - /// `S_IFCHR` - CharacterDevice = linux_raw_sys::general::S_IFCHR as isize, - - /// `S_IFBLK` - BlockDevice = linux_raw_sys::general::S_IFBLK as isize, - - /// An unknown filesystem object. - Unknown, -} - -impl FileType { - /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of - /// a `Stat`. - #[inline] - pub const fn from_raw_mode(st_mode: RawMode) -> Self { - match st_mode & linux_raw_sys::general::S_IFMT { - linux_raw_sys::general::S_IFREG => Self::RegularFile, - linux_raw_sys::general::S_IFDIR => Self::Directory, - linux_raw_sys::general::S_IFLNK => Self::Symlink, - linux_raw_sys::general::S_IFIFO => Self::Fifo, - linux_raw_sys::general::S_IFSOCK => Self::Socket, - linux_raw_sys::general::S_IFCHR => Self::CharacterDevice, - linux_raw_sys::general::S_IFBLK => Self::BlockDevice, - _ => Self::Unknown, - } - } - - /// Construct an `st_mode` value from `Stat`. - #[inline] - pub const fn as_raw_mode(self) -> RawMode { - match self { - Self::RegularFile => linux_raw_sys::general::S_IFREG, - Self::Directory => linux_raw_sys::general::S_IFDIR, - Self::Symlink => linux_raw_sys::general::S_IFLNK, - Self::Fifo => linux_raw_sys::general::S_IFIFO, - Self::Socket => linux_raw_sys::general::S_IFSOCK, - Self::CharacterDevice => linux_raw_sys::general::S_IFCHR, - Self::BlockDevice => linux_raw_sys::general::S_IFBLK, - Self::Unknown => linux_raw_sys::general::S_IFMT, - } - } - - /// Construct a `FileType` from the `d_type` field of a `dirent`. - #[inline] - pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { - match d_type as u32 { - linux_raw_sys::general::DT_REG => Self::RegularFile, - linux_raw_sys::general::DT_DIR => Self::Directory, - linux_raw_sys::general::DT_LNK => Self::Symlink, - linux_raw_sys::general::DT_SOCK => Self::Socket, - linux_raw_sys::general::DT_FIFO => Self::Fifo, - linux_raw_sys::general::DT_CHR => Self::CharacterDevice, - linux_raw_sys::general::DT_BLK => Self::BlockDevice, - // linux_raw_sys::general::DT_UNKNOWN | - _ => Self::Unknown, - } - } -} - -/// `POSIX_FADV_*` constants for use with [`fadvise`]. -/// -/// [`fadvise`]: crate::fs::fadvise -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum Advice { - /// `POSIX_FADV_NORMAL` - Normal = linux_raw_sys::general::POSIX_FADV_NORMAL, - - /// `POSIX_FADV_SEQUENTIAL` - Sequential = linux_raw_sys::general::POSIX_FADV_SEQUENTIAL, - - /// `POSIX_FADV_RANDOM` - Random = linux_raw_sys::general::POSIX_FADV_RANDOM, - - /// `POSIX_FADV_NOREUSE` - NoReuse = linux_raw_sys::general::POSIX_FADV_NOREUSE, - - /// `POSIX_FADV_WILLNEED` - WillNeed = linux_raw_sys::general::POSIX_FADV_WILLNEED, - - /// `POSIX_FADV_DONTNEED` - DontNeed = linux_raw_sys::general::POSIX_FADV_DONTNEED, -} - -bitflags! { - /// `MFD_*` constants for use with [`memfd_create`]. - /// - /// [`memfd_create`]: crate::fs::memfd_create - pub struct MemfdFlags: c::c_uint { - /// `MFD_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::MFD_CLOEXEC; - - /// `MFD_ALLOW_SEALING` - const ALLOW_SEALING = linux_raw_sys::general::MFD_ALLOW_SEALING; - - /// `MFD_HUGETLB` (since Linux 4.14) - const HUGETLB = linux_raw_sys::general::MFD_HUGETLB; - - /// `MFD_HUGE_64KB` - const HUGE_64KB = linux_raw_sys::general::MFD_HUGE_64KB; - /// `MFD_HUGE_512JB` - const HUGE_512KB = linux_raw_sys::general::MFD_HUGE_512KB; - /// `MFD_HUGE_1MB` - const HUGE_1MB = linux_raw_sys::general::MFD_HUGE_1MB; - /// `MFD_HUGE_2MB` - const HUGE_2MB = linux_raw_sys::general::MFD_HUGE_2MB; - /// `MFD_HUGE_8MB` - const HUGE_8MB = linux_raw_sys::general::MFD_HUGE_8MB; - /// `MFD_HUGE_16MB` - const HUGE_16MB = linux_raw_sys::general::MFD_HUGE_16MB; - /// `MFD_HUGE_32MB` - const HUGE_32MB = linux_raw_sys::general::MFD_HUGE_32MB; - /// `MFD_HUGE_256MB` - const HUGE_256MB = linux_raw_sys::general::MFD_HUGE_256MB; - /// `MFD_HUGE_512MB` - const HUGE_512MB = linux_raw_sys::general::MFD_HUGE_512MB; - /// `MFD_HUGE_1GB` - const HUGE_1GB = linux_raw_sys::general::MFD_HUGE_1GB; - /// `MFD_HUGE_2GB` - const HUGE_2GB = linux_raw_sys::general::MFD_HUGE_2GB; - /// `MFD_HUGE_16GB` - const HUGE_16GB = linux_raw_sys::general::MFD_HUGE_16GB; - } -} - -bitflags! { - /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and - /// [`fcntl_get_seals`]. - /// - /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals - /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals - pub struct SealFlags: u32 { - /// `F_SEAL_SEAL`. - const SEAL = linux_raw_sys::general::F_SEAL_SEAL; - /// `F_SEAL_SHRINK`. - const SHRINK = linux_raw_sys::general::F_SEAL_SHRINK; - /// `F_SEAL_GROW`. - const GROW = linux_raw_sys::general::F_SEAL_GROW; - /// `F_SEAL_WRITE`. - const WRITE = linux_raw_sys::general::F_SEAL_WRITE; - /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) - const FUTURE_WRITE = linux_raw_sys::general::F_SEAL_FUTURE_WRITE; - } -} - -bitflags! { - /// `STATX_*` constants for use with [`statx`]. - /// - /// [`statx`]: crate::fs::statx - pub struct StatxFlags: u32 { - /// `STATX_TYPE` - const TYPE = linux_raw_sys::general::STATX_TYPE; - - /// `STATX_MODE` - const MODE = linux_raw_sys::general::STATX_MODE; - - /// `STATX_NLINK` - const NLINK = linux_raw_sys::general::STATX_NLINK; - - /// `STATX_UID` - const UID = linux_raw_sys::general::STATX_UID; - - /// `STATX_GID` - const GID = linux_raw_sys::general::STATX_GID; - - /// `STATX_ATIME` - const ATIME = linux_raw_sys::general::STATX_ATIME; - - /// `STATX_MTIME` - const MTIME = linux_raw_sys::general::STATX_MTIME; - - /// `STATX_CTIME` - const CTIME = linux_raw_sys::general::STATX_CTIME; - - /// `STATX_INO` - const INO = linux_raw_sys::general::STATX_INO; - - /// `STATX_SIZE` - const SIZE = linux_raw_sys::general::STATX_SIZE; - - /// `STATX_BLOCKS` - const BLOCKS = linux_raw_sys::general::STATX_BLOCKS; - - /// `STATX_BASIC_STATS` - const BASIC_STATS = linux_raw_sys::general::STATX_BASIC_STATS; - - /// `STATX_BTIME` - const BTIME = linux_raw_sys::general::STATX_BTIME; - - /// `STATX_MNT_ID` (since Linux 5.8) - const MNT_ID = linux_raw_sys::general::STATX_MNT_ID; - - /// `STATX_ALL` - const ALL = linux_raw_sys::general::STATX_ALL; - } -} - -bitflags! { - /// `FALLOC_FL_*` constants for use with [`fallocate`]. - /// - /// [`fallocate`]: crate::fs::fallocate - pub struct FallocateFlags: u32 { - /// `FALLOC_FL_KEEP_SIZE` - const KEEP_SIZE = linux_raw_sys::general::FALLOC_FL_KEEP_SIZE; - /// `FALLOC_FL_PUNCH_HOLE` - const PUNCH_HOLE = linux_raw_sys::general::FALLOC_FL_PUNCH_HOLE; - /// `FALLOC_FL_NO_HIDE_STALE` - const NO_HIDE_STALE = linux_raw_sys::general::FALLOC_FL_NO_HIDE_STALE; - /// `FALLOC_FL_COLLAPSE_RANGE` - const COLLAPSE_RANGE = linux_raw_sys::general::FALLOC_FL_COLLAPSE_RANGE; - /// `FALLOC_FL_ZERO_RANGE` - const ZERO_RANGE = linux_raw_sys::general::FALLOC_FL_ZERO_RANGE; - /// `FALLOC_FL_INSERT_RANGE` - const INSERT_RANGE = linux_raw_sys::general::FALLOC_FL_INSERT_RANGE; - /// `FALLOC_FL_UNSHARE_RANGE` - const UNSHARE_RANGE = linux_raw_sys::general::FALLOC_FL_UNSHARE_RANGE; - } -} - -/// `LOCK_*` constants for use with [`flock`] -/// -/// [`flock`]: crate::fs::flock -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(u32)] -pub enum FlockOperation { - /// `LOCK_SH` - LockShared = linux_raw_sys::general::LOCK_SH, - /// `LOCK_EX` - LockExclusive = linux_raw_sys::general::LOCK_EX, - /// `LOCK_UN` - Unlock = linux_raw_sys::general::LOCK_UN, - /// `LOCK_SH | LOCK_NB` - NonBlockingLockShared = linux_raw_sys::general::LOCK_SH | linux_raw_sys::general::LOCK_NB, - /// `LOCK_EX | LOCK_NB` - NonBlockingLockExclusive = linux_raw_sys::general::LOCK_EX | linux_raw_sys::general::LOCK_NB, - /// `LOCK_UN | LOCK_NB` - NonBlockingUnlock = linux_raw_sys::general::LOCK_UN | linux_raw_sys::general::LOCK_NB, -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -// On 32-bit, and mips64, Linux's `struct stat64` has a 32-bit `st_mtime` and -// friends, so we use our own struct, populated from `statx` where possible, to -// avoid the y2038 bug. -#[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -pub struct Stat { - pub st_dev: u64, - pub st_mode: u32, - pub st_nlink: u32, - pub st_uid: u32, - pub st_gid: u32, - pub st_rdev: u64, - pub st_size: i64, - pub st_blksize: u32, - pub st_blocks: u64, - pub st_atime: u64, - pub st_atime_nsec: u32, - pub st_mtime: u64, - pub st_mtime_nsec: u32, - pub st_ctime: u64, - pub st_ctime_nsec: u32, - pub st_ino: u64, -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] -pub type Stat = linux_raw_sys::general::stat; - -/// `struct statfs` for use with [`fstatfs`]. -/// -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(target_pointer_width = "32")] -#[allow(clippy::module_name_repetitions)] -pub type StatFs = linux_raw_sys::general::statfs64; - -/// `struct statfs` for use with [`fstatfs`]. -/// -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(target_pointer_width = "64")] -#[allow(clippy::module_name_repetitions)] -pub type StatFs = linux_raw_sys::general::statfs64; - -/// `struct statx` for use with [`statx`]. -/// -/// [`statx`]: crate::fs::statx -pub type Statx = linux_raw_sys::general::statx; - -/// `struct statx_timestamp` for use with [`Statx`]. -pub type StatxTimestamp = linux_raw_sys::general::statx_timestamp; - -/// `mode_t` -#[cfg(not(any( - target_arch = "x86", - target_arch = "sparc", - target_arch = "avr", - target_arch = "arm", -)))] -pub type RawMode = linux_raw_sys::general::__kernel_mode_t; - -/// `mode_t -#[cfg(any( - target_arch = "x86", - target_arch = "sparc", - target_arch = "avr", - target_arch = "arm", -))] -// Don't use `__kernel_mode_t` since it's `u16` which differs from `st_size`. -pub type RawMode = c::c_uint; - -/// `dev_t` -// Within the kernel the dev_t is 32-bit, but userspace uses a 64-bit field. -pub type Dev = u64; - -/// `__fsword_t` -#[cfg(not(target_arch = "mips64"))] -pub type FsWord = linux_raw_sys::general::__fsword_t; - -/// `__fsword_t` -#[cfg(target_arch = "mips64")] -pub type FsWord = i64; - -pub use linux_raw_sys::general::{UTIME_NOW, UTIME_OMIT}; - -/// `PROC_SUPER_MAGIC`—The magic number for the procfs filesystem. -pub const PROC_SUPER_MAGIC: FsWord = linux_raw_sys::general::PROC_SUPER_MAGIC as FsWord; - -/// `NFS_SUPER_MAGIC`—The magic number for the NFS filesystem. -pub const NFS_SUPER_MAGIC: FsWord = linux_raw_sys::general::NFS_SUPER_MAGIC as FsWord; diff --git a/vendor/rustix/src/imp/linux_raw/io/epoll.rs b/vendor/rustix/src/imp/linux_raw/io/epoll.rs deleted file mode 100644 index 4362e40fb..000000000 --- a/vendor/rustix/src/imp/linux_raw/io/epoll.rs +++ /dev/null @@ -1,551 +0,0 @@ -//! epoll support. -//! -//! This is an experiment, and it isn't yet clear whether epoll is the right -//! level of abstraction at which to introduce safety. But it works fairly well -//! in simple examples 🙂. -//! -//! # Examples -//! -//! ```rust,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::{self, Epoll}; -//! use rustix::io::{ioctl_fionbio, read, write}; -//! use rustix::net::{ -//! accept, bind_v4, listen, socket, AddressFamily, Ipv4Addr, Protocol, SocketAddrV4, -//! SocketType, -//! }; -//! use std::os::unix::io::AsRawFd; -//! -//! // Create a socket and listen on it. -//! let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; -//! 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::new(epoll::CreateFlags::CLOEXEC, epoll::Owning::new())?; -//! -//! // Remember the socket raw fd, which we use for comparisons only. -//! let raw_listen_sock = listen_sock.as_fd().as_raw_fd(); -//! -//! // Register the socket with the epoll object. -//! epoll.add(listen_sock, epoll::EventFlags::IN)?; -//! -//! // Process events. -//! let mut event_list = epoll::EventVec::with_capacity(4); -//! loop { -//! epoll.wait(&mut event_list, -1)?; -//! for (_event_flags, target) in &event_list { -//! if target.as_raw_fd() == raw_listen_sock { -//! // 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(&*target)?; -//! ioctl_fionbio(&conn_sock, true)?; -//! epoll.add(conn_sock, epoll::EventFlags::OUT | epoll::EventFlags::ET)?; -//! } else { -//! // Write a message to the stream and then unregister it. -//! write(&*target, b"hello\n")?; -//! let _ = epoll.del(target)?; -//! } -//! } -//! } -//! # } -//! # #[cfg(not(feature = "net"))] -//! # fn main() {} -//! ``` - -#![allow(unsafe_code)] - -use super::super::c; -use crate::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}; -#[cfg(feature = "std")] -use crate::fd::{FromFd, FromRawFd, IntoFd, IntoRawFd}; -use crate::imp::io::syscalls::{epoll_add, epoll_create, epoll_del, epoll_mod, epoll_wait}; -use crate::io::{self, OwnedFd}; -use alloc::vec::Vec; -use bitflags::bitflags; -use core::fmt; -use core::marker::PhantomData; -use core::ops::Deref; -use core::ptr::null; - -bitflags! { - /// `EPOLL_*` for use with [`Epoll::new`]. - pub struct CreateFlags: c::c_uint { - /// `EPOLL_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::EPOLL_CLOEXEC; - } -} - -bitflags! { - /// `EPOLL*` for use with [`Epoll::add`]. - #[derive(Default)] - pub struct EventFlags: u32 { - /// `EPOLLIN` - const IN = linux_raw_sys::general::EPOLLIN as u32; - - /// `EPOLLOUT` - const OUT = linux_raw_sys::general::EPOLLOUT as u32; - - /// `EPOLLPRI` - const PRI = linux_raw_sys::general::EPOLLPRI as u32; - - /// `EPOLLERR` - const ERR = linux_raw_sys::general::EPOLLERR as u32; - - /// `EPOLLHUP` - const HUP = linux_raw_sys::general::EPOLLHUP as u32; - - /// `EPOLLET` - const ET = linux_raw_sys::general::EPOLLET as u32; - - /// `EPOLLONESHOT` - const ONESHOT = linux_raw_sys::general::EPOLLONESHOT as u32; - - /// `EPOLLWAKEUP` - const WAKEUP = linux_raw_sys::general::EPOLLWAKEUP as u32; - - /// `EPOLLEXCLUSIVE` - const EXCLUSIVE = linux_raw_sys::general::EPOLLEXCLUSIVE as u32; - } -} - -/// A reference to a `T`. -pub struct Ref<'a, T> { - t: T, - _phantom: PhantomData<&'a T>, -} - -impl<'a, T> Ref<'a, T> { - #[inline] - fn new(t: T) -> Self { - Self { - t, - _phantom: PhantomData, - } - } - - #[inline] - fn consume(self) -> T { - self.t - } -} - -impl<'a, T> Deref for Ref<'a, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - &self.t - } -} - -impl<'a, T: fmt::Debug> fmt::Debug for Ref<'a, T> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - self.t.fmt(fmt) - } -} - -/// A trait for data stored within an [`Epoll`] instance. -pub trait Context { - /// The type of an element owned by this context. - type Data; - - /// The type of a value used to refer to an element owned by this context. - type Target: AsFd; - - /// Assume ownership of `data`, and returning a `Target`. - fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target>; - - /// Encode `target` as a `u64`. The only requirement on this value is that - /// it be decodable by `decode`. - fn encode(&self, target: Ref<'_, Self::Target>) -> u64; - - /// Decode `raw`, which is a value encoded by `encode`, into a `Target`. - /// - /// # Safety - /// - /// `raw` must be a `u64` value returned from `encode`, from the same - /// context, and within the context's lifetime. - unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target>; - - /// Release ownership of the value referred to by `target` and return it. - fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data; -} - -/// A type implementing [`Context`] where the `Data` type is `BorrowedFd<'a>`. -pub struct Borrowing<'a> { - _phantom: PhantomData>, -} - -impl<'a> Context for Borrowing<'a> { - type Data = BorrowedFd<'a>; - type Target = BorrowedFd<'a>; - - #[inline] - fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { - Ref::new(data) - } - - #[inline] - fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { - target.as_raw_fd() as u64 - } - - #[inline] - unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { - Ref::new(BorrowedFd::<'a>::borrow_raw(raw as RawFd)) - } - - #[inline] - fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { - target.consume() - } -} - -/// A type implementing [`Context`] where the `Data` type is `T`, a type -/// implementing `IntoFd` and `FromFd`. -/// -/// This may be used with [`OwnedFd`], or higher-level types like -/// [`std::fs::File`] or [`std::net::TcpStream`]. -#[cfg(feature = "std")] -pub struct Owning<'context, T: IntoFd + FromFd> { - _phantom: PhantomData<&'context T>, -} - -#[cfg(feature = "std")] -impl<'context, T: IntoFd + FromFd> Owning<'context, T> { - /// Creates a new empty `Owning`. - #[allow(clippy::new_without_default)] // This is a specialized type that doesn't need to be generically constructible. - #[inline] - pub fn new() -> Self { - Self { - _phantom: PhantomData, - } - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> Context for Owning<'context, T> { - type Data = T; - type Target = BorrowedFd<'context>; - - #[inline] - fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> { - let raw_fd = data.into_fd().into_raw_fd(); - // Safety: `epoll` will assign ownership of the file descriptor to the - // kernel epoll object. We use `IntoFd`+`IntoRawFd` to consume the - // `Data` and extract the raw file descriptor and then "borrow" it - // with `borrow_raw` knowing that the borrow won't outlive the - // kernel epoll object. - unsafe { Ref::new(BorrowedFd::<'context>::borrow_raw(raw_fd)) } - } - - #[inline] - fn encode(&self, target: Ref<'_, Self::Target>) -> u64 { - target.as_fd().as_raw_fd() as u64 - } - - #[inline] - unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> { - Ref::new(BorrowedFd::<'context>::borrow_raw(raw as RawFd)) - } - - #[inline] - fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data { - let raw_fd = target.consume().as_raw_fd(); - - // Safety: The file descriptor was held by the kernel epoll object and - // is now being released, so we can create a new `OwnedFd` that assumes - // ownership. - unsafe { T::from_fd(io_lifetimes::OwnedFd::from_raw_fd(raw_fd)) } - } -} - -/// An "epoll", an interface to an OS object allowing one to repeatedly wait -/// for events from a set of file descriptors efficiently. -pub struct Epoll { - epoll_fd: OwnedFd, - context: Context, -} - -impl Epoll { - /// `epoll_create1(flags)`—Creates a new `Epoll`. - /// - /// 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 new(flags: CreateFlags, context: Context) -> io::Result { - // Safety: We're calling `epoll_create1` via FFI and we know how it - // behaves. - Ok(Self { - epoll_fd: epoll_create(flags)?, - context, - }) - } - - /// `epoll_ctl(self, EPOLL_CTL_ADD, data, event)`—Adds an element to an - /// `Epoll`. - /// - /// This registers interest in any of the events set in `events` occurring - /// on the file descriptor associated with `data`. - #[doc(alias = "epoll_ctl")] - pub fn add( - &self, - data: Context::Data, - event_flags: EventFlags, - ) -> io::Result> { - // Safety: We're calling `epoll_ctl` via FFI and we know how it - // behaves. - unsafe { - let target = self.context.acquire(data); - let raw_fd = target.as_fd().as_raw_fd(); - let encoded = self.context.encode(target); - epoll_add( - self.epoll_fd.as_fd(), - raw_fd, - &linux_raw_sys::general::epoll_event { - events: event_flags.bits(), - data: encoded, - }, - )?; - Ok(self.context.decode(encoded)) - } - } - - /// `epoll_ctl(self, EPOLL_CTL_MOD, target, event)`—Modifies an element in - /// this `Epoll`. - /// - /// This sets the events of interest with `target` to `events`. - #[doc(alias = "epoll_ctl")] - pub fn mod_( - &self, - target: Ref<'_, Context::Target>, - event_flags: EventFlags, - ) -> io::Result<()> { - let raw_fd = target.as_fd().as_raw_fd(); - let encoded = self.context.encode(target); - // Safety: We're calling `epoll_ctl` via FFI and we know how it - // behaves. - unsafe { - epoll_mod( - self.epoll_fd.as_fd(), - raw_fd, - &linux_raw_sys::general::epoll_event { - events: event_flags.bits(), - data: encoded, - }, - ) - } - } - - /// `epoll_ctl(self, EPOLL_CTL_DEL, target, NULL)`—Removes an element in - /// this `Epoll`. - /// - /// This also returns the owning `Data`. - #[doc(alias = "epoll_ctl")] - pub fn del(&self, target: Ref<'_, Context::Target>) -> io::Result { - // Safety: We're calling `epoll_ctl` via FFI and we know how it - // behaves. - unsafe { - let raw_fd = target.as_fd().as_raw_fd(); - epoll_del(self.epoll_fd.as_fd(), raw_fd)?; - } - Ok(self.context.release(target)) - } - - /// `epoll_wait(self, events, timeout)`—Waits for registered events of - /// interest. - /// - /// For each event of interest, an element is written to `events`. On - /// success, this returns the number of written elements. - #[doc(alias = "epoll_wait")] - pub fn wait<'context>( - &'context self, - event_list: &mut EventVec<'context, Context>, - timeout: c::c_int, - ) -> io::Result<()> { - // Safety: We're calling `epoll_wait` via FFI and we know how it - // behaves. - unsafe { - event_list.events.set_len(0); - let nfds = epoll_wait( - self.epoll_fd.as_fd(), - event_list.events[..].as_mut_ptr().cast(), - event_list.events.capacity(), - timeout, - )?; - event_list.events.set_len(nfds); - event_list.context = &self.context; - } - - Ok(()) - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> AsRawFd for Epoll> { - fn as_raw_fd(&self) -> RawFd { - self.epoll_fd.as_raw_fd() - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> IntoRawFd for Epoll> { - fn into_raw_fd(self) -> RawFd { - self.epoll_fd.into_raw_fd() - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> FromRawFd for Epoll> { - unsafe fn from_raw_fd(fd: RawFd) -> Self { - Self { - epoll_fd: OwnedFd::from_raw_fd(fd), - context: Owning::new(), - } - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> AsFd for Epoll> { - fn as_fd(&self) -> BorrowedFd<'_> { - self.epoll_fd.as_fd() - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> From>> for OwnedFd { - fn from(epoll: Epoll>) -> Self { - epoll.epoll_fd - } -} - -#[cfg(feature = "std")] -impl<'context, T: AsFd + IntoFd + FromFd> From for Epoll> { - fn from(fd: OwnedFd) -> Self { - Self { - epoll_fd: fd, - context: Owning::new(), - } - } -} - -/// An iterator over the `Event`s in an `EventVec`. -pub struct Iter<'context, Context: self::Context> { - iter: core::slice::Iter<'context, Event>, - context: *const Context, - _phantom: PhantomData<&'context Context>, -} - -impl<'context, Context: self::Context> Iterator for Iter<'context, Context> { - type Item = (EventFlags, Ref<'context, Context::Target>); - - fn next(&mut self) -> Option { - self.iter.next().map(|event| { - // Safety: `self.context` is guaranteed to be valid because we hold - // `'context` for it. And we know this event is associated with this - // context because `wait` sets both. - let decoded = unsafe { (*self.context).decode(event.encoded) }; - - (event.event_flags, decoded) - }) - } -} - -/// 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; `Context` implementations will simply - // need to deal with casting the value into and out of the `u64` - // themselves. - event_flags: EventFlags, - encoded: u64, -} - -/// A vector of `Event`s, plus context for interpreting them. -pub struct EventVec<'context, Context: self::Context> { - events: Vec, - context: *const Context, - _phantom: PhantomData<&'context Context>, -} - -impl<'context, Context: self::Context> EventVec<'context, Context> { - /// Constructs an `EventVec` with memory for `capacity` `Event`s. - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - Self { - events: Vec::with_capacity(capacity), - context: null(), - _phantom: PhantomData, - } - } - - /// Returns the current `Event` capacity of this `EventVec`. - #[inline] - pub fn capacity(&self) -> usize { - self.events.capacity() - } - - /// Reserves enough memory for at least `additional` more `Event`s. - #[inline] - pub fn reserve(&mut self, additional: usize) { - self.events.reserve(additional); - } - - /// Reserves enough memory for exactly `additional` more `Event`s. - #[inline] - pub fn reserve_exact(&mut self, additional: usize) { - self.events.reserve_exact(additional); - } - - /// Clears all the `Events` out of this `EventVec`. - #[inline] - pub fn clear(&mut self) { - self.events.clear(); - } - - /// Shrinks the capacity of this `EventVec` as much as possible. - #[inline] - pub fn shrink_to_fit(&mut self) { - self.events.shrink_to_fit(); - } - - /// Returns an iterator over the `Event`s in this `EventVec`. - #[inline] - pub fn iter(&self) -> Iter<'_, Context> { - Iter { - iter: self.events.iter(), - context: self.context, - _phantom: PhantomData, - } - } - - /// Returns the number of `Event`s logically contained in this `EventVec`. - #[inline] - pub fn len(&mut self) -> usize { - self.events.len() - } - - /// Tests whether this `EventVec` is logically empty. - #[inline] - pub fn is_empty(&mut self) -> bool { - self.events.is_empty() - } -} - -impl<'context, Context: self::Context> IntoIterator for &'context EventVec<'context, Context> { - type IntoIter = Iter<'context, Context>; - type Item = (EventFlags, Ref<'context, Context::Target>); - - #[inline] - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} diff --git a/vendor/rustix/src/imp/linux_raw/io/errno.rs b/vendor/rustix/src/imp/linux_raw/io/errno.rs deleted file mode 100644 index 2637ae02e..000000000 --- a/vendor/rustix/src/imp/linux_raw/io/errno.rs +++ /dev/null @@ -1,511 +0,0 @@ -//! The `rustix` `Errno` type. -//! -//! This type holds an OS error code, which conceptually corresponds to an -//! `errno` value. -//! -//! # Safety -//! -//! Linux uses error codes in `-4095..0`; we use rustc attributes to describe -//! this restricted range of values. -#![allow(unsafe_code)] -#![cfg_attr(not(rustc_attrs), allow(unused_unsafe))] - -use super::super::c; -use crate::imp::fd::RawFd; -use crate::imp::reg::{RetNumber, RetReg}; -use crate::io; -use linux_raw_sys::errno; - -/// The error type for `rustix` APIs. -/// -/// This is similar to `std::io::Error`, but only holds an OS error code, -/// and no extra error value. -#[repr(transparent)] -#[doc(alias = "errno")] -#[derive(Eq, PartialEq, Hash, Copy, Clone)] -// Linux returns negated error codes, and we leave them in negated form, so -// error codes are in `-4095..0`. -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_start(0xf001))] -#[cfg_attr(rustc_attrs, rustc_layout_scalar_valid_range_end(0xffff))] -pub struct Errno(u16); - -impl Errno { - /// Extract an `Errno` value from a `std::io::Error`. - /// - /// This isn't a `From` conversion because it's expected to be relatively - /// uncommon. - #[cfg(feature = "std")] - #[inline] - pub fn from_io_error(io_err: &std::io::Error) -> Option { - io_err.raw_os_error().and_then(|raw| { - // `std::io::Error` could theoretically have arbitrary "OS error" - // values, so check that they're in Linux's range. - if (1..4096).contains(&raw) { - Some(Self::from_errno(raw as u32)) - } else { - None - } - }) - } - - /// Extract the raw OS error number from this error. - #[inline] - pub const fn raw_os_error(self) -> i32 { - (self.0 as i16 as i32).wrapping_neg() - } - - /// Construct an `Errno` from a raw OS error number. - #[inline] - pub const fn from_raw_os_error(raw: i32) -> Self { - Self::from_errno(raw as u32) - } - - /// 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. - let encoded = raw.wrapping_neg() as u16; - - // TODO: Use Range::contains, once that's `const`. - const_assert!(encoded >= 0xf001); - - // Safety: Linux syscalls return negated error values in the range - // `-4095..0`, which we just asserted. - unsafe { Self(encoded) } - } -} - -/// Check for an error from the result of a syscall which encodes a -/// `c::c_int` on success. -#[inline] -pub(in crate::imp) fn try_decode_c_int(raw: RetReg) -> io::Result { - if raw.is_in_range(-4095..0) { - // Safety: `raw` must be in `-4095..0`, and we just checked that raw is - // in that range. - return Err(unsafe { Errno(raw.decode_error_code()) }); - } - - Ok(raw.decode_c_int()) -} - -/// Check for an error from the result of a syscall which encodes a -/// `c::c_uint` on success. -#[inline] -pub(in crate::imp) fn try_decode_c_uint(raw: RetReg) -> io::Result { - if raw.is_in_range(-4095..0) { - // Safety: `raw` must be in `-4095..0`, and we just checked that raw is - // in that range. - return Err(unsafe { Errno(raw.decode_error_code()) }); - } - - Ok(raw.decode_c_uint()) -} - -/// Check for an error from the result of a syscall which encodes a `usize` on -/// success. -#[inline] -pub(in crate::imp) fn try_decode_usize(raw: RetReg) -> io::Result { - if raw.is_in_range(-4095..0) { - // Safety: `raw` must be in `-4095..0`, and we just checked that raw is - // in that range. - return Err(unsafe { Errno(raw.decode_error_code()) }); - } - - Ok(raw.decode_usize()) -} - -/// Check for an error from the result of a syscall which encodes a -/// `*mut c_void` on success. -#[inline] -pub(in crate::imp) fn try_decode_void_star( - raw: RetReg, -) -> io::Result<*mut c::c_void> { - if raw.is_in_range(-4095..0) { - // Safety: `raw` must be in `-4095..0`, and we just checked that raw is - // in that range. - return Err(unsafe { Errno(raw.decode_error_code()) }); - } - - Ok(raw.decode_void_star()) -} - -/// Check for an error from the result of a syscall which encodes a -/// `u64` on success. -#[cfg(target_pointer_width = "64")] -#[inline] -pub(in crate::imp) fn try_decode_u64(raw: RetReg) -> io::Result { - if raw.is_in_range(-4095..0) { - // Safety: `raw` must be in `-4095..0`, and we just checked that raw is - // in that range. - return Err(unsafe { Errno(raw.decode_error_code()) }); - } - - Ok(raw.decode_u64()) -} - -/// Check for an error from the result of a syscall which encodes a file -/// descriptor on success. -/// -/// # Safety -/// -/// This must only be used with syscalls which return file descriptors on -/// success. -#[inline] -pub(in crate::imp) unsafe fn try_decode_raw_fd( - raw: RetReg, -) -> io::Result { - // Instead of using `check_result` here, we just check for negative, since - // this function is only used for system calls which return file - // descriptors, and this produces smaller code. - if raw.is_negative() { - debug_assert!(raw.is_in_range(-4095..0)); - - // Tell the optimizer that we know the value is in the error range. - // This helps it avoid unnecessary integer conversions. - #[cfg(core_intrinsics)] - { - core::intrinsics::assume(raw.is_in_range(-4095..0)); - } - - return Err(Errno(raw.decode_error_code())); - } - - Ok(raw.decode_raw_fd()) -} - -/// Check for an error from the result of a syscall which encodes no value on -/// success. On success, return the unconsumed `raw` value. -/// -/// # Safety -/// -/// This must only be used with syscalls which return no value on success. -#[inline] -pub(in crate::imp) unsafe fn try_decode_void(raw: RetReg) -> io::Result<()> { - // Instead of using `check_result` here, we just check for zero, since this - // function is only used for system calls which have no other return value, - // and this produces smaller code. - if raw.is_nonzero() { - debug_assert!(raw.is_in_range(-4095..0)); - - // Tell the optimizer that we know the value is in the error range. - // This helps it avoid unnecessary integer conversions. - #[cfg(core_intrinsics)] - { - core::intrinsics::assume(raw.is_in_range(-4095..0)); - } - - return Err(Errno(raw.decode_error_code())); - } - - raw.decode_void(); - - Ok(()) -} - -/// Check for an error from the result of a syscall which does not return on -/// success. On success, return the unconsumed `raw` value. -/// -/// # Safety -/// -/// This must only be used with syscalls which do not return on success. -#[cfg(feature = "runtime")] -#[inline] -pub(in crate::imp) unsafe fn try_decode_error(raw: RetReg) -> io::Errno { - debug_assert!(raw.is_in_range(-4095..0)); - - // Tell the optimizer that we know the value is in the error range. - // This helps it avoid unnecessary integer conversions. - #[cfg(core_intrinsics)] - { - core::intrinsics::assume(raw.is_in_range(-4095..0)); - } - - Errno(raw.decode_error_code()) -} - -/// Return the contained `usize` value. -#[cfg(not(debug_assertions))] -#[inline] -pub(in crate::imp) fn decode_usize_infallible(raw: RetReg) -> usize { - raw.decode_usize() -} - -impl Errno { - /// `EACCES` - #[doc(alias = "ACCES")] - pub const ACCESS: Self = Self::from_errno(errno::EACCES); - /// `EADDRINUSE` - pub const ADDRINUSE: Self = Self::from_errno(errno::EADDRINUSE); - /// `EADDRNOTAVAIL` - pub const ADDRNOTAVAIL: Self = Self::from_errno(errno::EADDRNOTAVAIL); - /// `EADV` - pub const ADV: Self = Self::from_errno(errno::EADV); - /// `EAFNOSUPPORT` - pub const AFNOSUPPORT: Self = Self::from_errno(errno::EAFNOSUPPORT); - /// `EAGAIN` - pub const AGAIN: Self = Self::from_errno(errno::EAGAIN); - /// `EALREADY` - pub const ALREADY: Self = Self::from_errno(errno::EALREADY); - /// `EBADE` - pub const BADE: Self = Self::from_errno(errno::EBADE); - /// `EBADF` - pub const BADF: Self = Self::from_errno(errno::EBADF); - /// `EBADFD` - pub const BADFD: Self = Self::from_errno(errno::EBADFD); - /// `EBADMSG` - pub const BADMSG: Self = Self::from_errno(errno::EBADMSG); - /// `EBADR` - pub const BADR: Self = Self::from_errno(errno::EBADR); - /// `EBADRQC` - pub const BADRQC: Self = Self::from_errno(errno::EBADRQC); - /// `EBADSLT` - pub const BADSLT: Self = Self::from_errno(errno::EBADSLT); - /// `EBFONT` - pub const BFONT: Self = Self::from_errno(errno::EBFONT); - /// `EBUSY` - pub const BUSY: Self = Self::from_errno(errno::EBUSY); - /// `ECANCELED` - pub const CANCELED: Self = Self::from_errno(errno::ECANCELED); - /// `ECHILD` - pub const CHILD: Self = Self::from_errno(errno::ECHILD); - /// `ECHRNG` - pub const CHRNG: Self = Self::from_errno(errno::ECHRNG); - /// `ECOMM` - pub const COMM: Self = Self::from_errno(errno::ECOMM); - /// `ECONNABORTED` - pub const CONNABORTED: Self = Self::from_errno(errno::ECONNABORTED); - /// `ECONNREFUSED` - pub const CONNREFUSED: Self = Self::from_errno(errno::ECONNREFUSED); - /// `ECONNRESET` - pub const CONNRESET: Self = Self::from_errno(errno::ECONNRESET); - /// `EDEADLK` - pub const DEADLK: Self = Self::from_errno(errno::EDEADLK); - /// `EDEADLOCK` - pub const DEADLOCK: Self = Self::from_errno(errno::EDEADLOCK); - /// `EDESTADDRREQ` - pub const DESTADDRREQ: Self = Self::from_errno(errno::EDESTADDRREQ); - /// `EDOM` - pub const DOM: Self = Self::from_errno(errno::EDOM); - /// `EDOTDOT` - pub const DOTDOT: Self = Self::from_errno(errno::EDOTDOT); - /// `EDQUOT` - pub const DQUOT: Self = Self::from_errno(errno::EDQUOT); - /// `EEXIST` - pub const EXIST: Self = Self::from_errno(errno::EEXIST); - /// `EFAULT` - pub const FAULT: Self = Self::from_errno(errno::EFAULT); - /// `EFBIG` - pub const FBIG: Self = Self::from_errno(errno::EFBIG); - /// `EHOSTDOWN` - pub const HOSTDOWN: Self = Self::from_errno(errno::EHOSTDOWN); - /// `EHOSTUNREACH` - pub const HOSTUNREACH: Self = Self::from_errno(errno::EHOSTUNREACH); - /// `EHWPOISON` - pub const HWPOISON: Self = Self::from_errno(errno::EHWPOISON); - /// `EIDRM` - pub const IDRM: Self = Self::from_errno(errno::EIDRM); - /// `EILSEQ` - pub const ILSEQ: Self = Self::from_errno(errno::EILSEQ); - /// `EINPROGRESS` - pub const INPROGRESS: Self = Self::from_errno(errno::EINPROGRESS); - /// `EINTR`. - /// - /// For a convenient way to retry system calls that exit with `INTR`, use - /// [`retry_on_intr`]. - /// - /// [`retry_on_intr`]: io::retry_on_intr - pub const INTR: Self = Self::from_errno(errno::EINTR); - /// `EINVAL` - pub const INVAL: Self = Self::from_errno(errno::EINVAL); - /// `EIO` - pub const IO: Self = Self::from_errno(errno::EIO); - /// `EISCONN` - pub const ISCONN: Self = Self::from_errno(errno::EISCONN); - /// `EISDIR` - pub const ISDIR: Self = Self::from_errno(errno::EISDIR); - /// `EISNAM` - pub const ISNAM: Self = Self::from_errno(errno::EISNAM); - /// `EKEYEXPIRED` - pub const KEYEXPIRED: Self = Self::from_errno(errno::EKEYEXPIRED); - /// `EKEYREJECTED` - pub const KEYREJECTED: Self = Self::from_errno(errno::EKEYREJECTED); - /// `EKEYREVOKED` - pub const KEYREVOKED: Self = Self::from_errno(errno::EKEYREVOKED); - /// `EL2HLT` - pub const L2HLT: Self = Self::from_errno(errno::EL2HLT); - /// `EL2NSYNC` - pub const L2NSYNC: Self = Self::from_errno(errno::EL2NSYNC); - /// `EL3HLT` - pub const L3HLT: Self = Self::from_errno(errno::EL3HLT); - /// `EL3RST` - pub const L3RST: Self = Self::from_errno(errno::EL3RST); - /// `ELIBACC` - pub const LIBACC: Self = Self::from_errno(errno::ELIBACC); - /// `ELIBBAD` - pub const LIBBAD: Self = Self::from_errno(errno::ELIBBAD); - /// `ELIBEXEC` - pub const LIBEXEC: Self = Self::from_errno(errno::ELIBEXEC); - /// `ELIBMAX` - pub const LIBMAX: Self = Self::from_errno(errno::ELIBMAX); - /// `ELIBSCN` - pub const LIBSCN: Self = Self::from_errno(errno::ELIBSCN); - /// `ELNRNG` - pub const LNRNG: Self = Self::from_errno(errno::ELNRNG); - /// `ELOOP` - pub const LOOP: Self = Self::from_errno(errno::ELOOP); - /// `EMEDIUMTYPE` - pub const MEDIUMTYPE: Self = Self::from_errno(errno::EMEDIUMTYPE); - /// `EMFILE` - pub const MFILE: Self = Self::from_errno(errno::EMFILE); - /// `EMLINK` - pub const MLINK: Self = Self::from_errno(errno::EMLINK); - /// `EMSGSIZE` - pub const MSGSIZE: Self = Self::from_errno(errno::EMSGSIZE); - /// `EMULTIHOP` - pub const MULTIHOP: Self = Self::from_errno(errno::EMULTIHOP); - /// `ENAMETOOLONG` - pub const NAMETOOLONG: Self = Self::from_errno(errno::ENAMETOOLONG); - /// `ENAVAIL` - pub const NAVAIL: Self = Self::from_errno(errno::ENAVAIL); - /// `ENETDOWN` - pub const NETDOWN: Self = Self::from_errno(errno::ENETDOWN); - /// `ENETRESET` - pub const NETRESET: Self = Self::from_errno(errno::ENETRESET); - /// `ENETUNREACH` - pub const NETUNREACH: Self = Self::from_errno(errno::ENETUNREACH); - /// `ENFILE` - pub const NFILE: Self = Self::from_errno(errno::ENFILE); - /// `ENOANO` - pub const NOANO: Self = Self::from_errno(errno::ENOANO); - /// `ENOBUFS` - pub const NOBUFS: Self = Self::from_errno(errno::ENOBUFS); - /// `ENOCSI` - pub const NOCSI: Self = Self::from_errno(errno::ENOCSI); - /// `ENODATA` - #[doc(alias = "NOATTR")] - pub const NODATA: Self = Self::from_errno(errno::ENODATA); - /// `ENODEV` - pub const NODEV: Self = Self::from_errno(errno::ENODEV); - /// `ENOENT` - pub const NOENT: Self = Self::from_errno(errno::ENOENT); - /// `ENOEXEC` - pub const NOEXEC: Self = Self::from_errno(errno::ENOEXEC); - /// `ENOKEY` - pub const NOKEY: Self = Self::from_errno(errno::ENOKEY); - /// `ENOLCK` - pub const NOLCK: Self = Self::from_errno(errno::ENOLCK); - /// `ENOLINK` - pub const NOLINK: Self = Self::from_errno(errno::ENOLINK); - /// `ENOMEDIUM` - pub const NOMEDIUM: Self = Self::from_errno(errno::ENOMEDIUM); - /// `ENOMEM` - pub const NOMEM: Self = Self::from_errno(errno::ENOMEM); - /// `ENOMSG` - pub const NOMSG: Self = Self::from_errno(errno::ENOMSG); - /// `ENONET` - pub const NONET: Self = Self::from_errno(errno::ENONET); - /// `ENOPKG` - pub const NOPKG: Self = Self::from_errno(errno::ENOPKG); - /// `ENOPROTOOPT` - pub const NOPROTOOPT: Self = Self::from_errno(errno::ENOPROTOOPT); - /// `ENOSPC` - pub const NOSPC: Self = Self::from_errno(errno::ENOSPC); - /// `ENOSR` - pub const NOSR: Self = Self::from_errno(errno::ENOSR); - /// `ENOSTR` - pub const NOSTR: Self = Self::from_errno(errno::ENOSTR); - /// `ENOSYS` - pub const NOSYS: Self = Self::from_errno(errno::ENOSYS); - /// `ENOTBLK` - pub const NOTBLK: Self = Self::from_errno(errno::ENOTBLK); - /// `ENOTCONN` - pub const NOTCONN: Self = Self::from_errno(errno::ENOTCONN); - /// `ENOTDIR` - pub const NOTDIR: Self = Self::from_errno(errno::ENOTDIR); - /// `ENOTEMPTY` - pub const NOTEMPTY: Self = Self::from_errno(errno::ENOTEMPTY); - /// `ENOTNAM` - pub const NOTNAM: Self = Self::from_errno(errno::ENOTNAM); - /// `ENOTRECOVERABLE` - pub const NOTRECOVERABLE: Self = Self::from_errno(errno::ENOTRECOVERABLE); - /// `ENOTSOCK` - pub const NOTSOCK: Self = Self::from_errno(errno::ENOTSOCK); - /// `ENOTSUP` - // On Linux, `ENOTSUP` has the same value as `EOPNOTSUPP`. - pub const NOTSUP: Self = Self::from_errno(errno::EOPNOTSUPP); - /// `ENOTTY` - pub const NOTTY: Self = Self::from_errno(errno::ENOTTY); - /// `ENOTUNIQ` - pub const NOTUNIQ: Self = Self::from_errno(errno::ENOTUNIQ); - /// `ENXIO` - pub const NXIO: Self = Self::from_errno(errno::ENXIO); - /// `EOPNOTSUPP` - pub const OPNOTSUPP: Self = Self::from_errno(errno::EOPNOTSUPP); - /// `EOVERFLOW` - pub const OVERFLOW: Self = Self::from_errno(errno::EOVERFLOW); - /// `EOWNERDEAD` - pub const OWNERDEAD: Self = Self::from_errno(errno::EOWNERDEAD); - /// `EPERM` - pub const PERM: Self = Self::from_errno(errno::EPERM); - /// `EPFNOSUPPORT` - pub const PFNOSUPPORT: Self = Self::from_errno(errno::EPFNOSUPPORT); - /// `EPIPE` - pub const PIPE: Self = Self::from_errno(errno::EPIPE); - /// `EPROTO` - pub const PROTO: Self = Self::from_errno(errno::EPROTO); - /// `EPROTONOSUPPORT` - pub const PROTONOSUPPORT: Self = Self::from_errno(errno::EPROTONOSUPPORT); - /// `EPROTOTYPE` - pub const PROTOTYPE: Self = Self::from_errno(errno::EPROTOTYPE); - /// `ERANGE` - pub const RANGE: Self = Self::from_errno(errno::ERANGE); - /// `EREMCHG` - pub const REMCHG: Self = Self::from_errno(errno::EREMCHG); - /// `EREMOTE` - pub const REMOTE: Self = Self::from_errno(errno::EREMOTE); - /// `EREMOTEIO` - pub const REMOTEIO: Self = Self::from_errno(errno::EREMOTEIO); - /// `ERESTART` - pub const RESTART: Self = Self::from_errno(errno::ERESTART); - /// `ERFKILL` - pub const RFKILL: Self = Self::from_errno(errno::ERFKILL); - /// `EROFS` - pub const ROFS: Self = Self::from_errno(errno::EROFS); - /// `ESHUTDOWN` - pub const SHUTDOWN: Self = Self::from_errno(errno::ESHUTDOWN); - /// `ESOCKTNOSUPPORT` - pub const SOCKTNOSUPPORT: Self = Self::from_errno(errno::ESOCKTNOSUPPORT); - /// `ESPIPE` - pub const SPIPE: Self = Self::from_errno(errno::ESPIPE); - /// `ESRCH` - pub const SRCH: Self = Self::from_errno(errno::ESRCH); - /// `ESRMNT` - pub const SRMNT: Self = Self::from_errno(errno::ESRMNT); - /// `ESTALE` - pub const STALE: Self = Self::from_errno(errno::ESTALE); - /// `ESTRPIPE` - pub const STRPIPE: Self = Self::from_errno(errno::ESTRPIPE); - /// `ETIME` - pub const TIME: Self = Self::from_errno(errno::ETIME); - /// `ETIMEDOUT` - pub const TIMEDOUT: Self = Self::from_errno(errno::ETIMEDOUT); - /// `E2BIG` - #[doc(alias = "2BIG")] - pub const TOOBIG: Self = Self::from_errno(errno::E2BIG); - /// `ETOOMANYREFS` - pub const TOOMANYREFS: Self = Self::from_errno(errno::ETOOMANYREFS); - /// `ETXTBSY` - pub const TXTBSY: Self = Self::from_errno(errno::ETXTBSY); - /// `EUCLEAN` - pub const UCLEAN: Self = Self::from_errno(errno::EUCLEAN); - /// `EUNATCH` - pub const UNATCH: Self = Self::from_errno(errno::EUNATCH); - /// `EUSERS` - pub const USERS: Self = Self::from_errno(errno::EUSERS); - /// `EWOULDBLOCK` - pub const WOULDBLOCK: Self = Self::from_errno(errno::EWOULDBLOCK); - /// `EXDEV` - pub const XDEV: Self = Self::from_errno(errno::EXDEV); - /// `EXFULL` - pub const XFULL: Self = Self::from_errno(errno::EXFULL); -} diff --git a/vendor/rustix/src/imp/linux_raw/io/io_slice.rs b/vendor/rustix/src/imp/linux_raw/io/io_slice.rs deleted file mode 100644 index fc8e64698..000000000 --- a/vendor/rustix/src/imp/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; - -/// -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: c::iovec, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - /// - #[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, - } - } - - /// - #[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); - } - } - - /// - #[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) } - } -} - -/// -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: c::iovec, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - /// - #[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, - } - } - - /// - #[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); - } - } - - /// - #[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) } - } - - /// - #[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/imp/linux_raw/io/mod.rs b/vendor/rustix/src/imp/linux_raw/io/mod.rs deleted file mode 100644 index f5c2bf3c0..000000000 --- a/vendor/rustix/src/imp/linux_raw/io/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -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/imp/linux_raw/io/poll_fd.rs b/vendor/rustix/src/imp/linux_raw/io/poll_fd.rs deleted file mode 100644 index 252358331..000000000 --- a/vendor/rustix/src/imp/linux_raw/io/poll_fd.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::fd::{AsFd, BorrowedFd}; -use bitflags::bitflags; - -bitflags! { - /// `POLL*` flags for use with [`poll`]. - /// - /// [`poll`]: crate::io::poll - pub struct PollFlags: u16 { - /// `POLLIN` - const IN = linux_raw_sys::general::POLLIN as u16; - /// `POLLPRI` - const PRI = linux_raw_sys::general::POLLPRI as u16; - /// `POLLOUT` - const OUT = linux_raw_sys::general::POLLOUT as u16; - /// `POLLRDNORM` - const RDNORM = linux_raw_sys::general::POLLRDNORM as u16; - /// `POLLWRNORM` - const WRNORM = linux_raw_sys::general::POLLWRNORM as u16; - /// `POLLRDBAND` - const RDBAND = linux_raw_sys::general::POLLRDBAND as u16; - /// `POLLWRBAND` - const WRBAND = linux_raw_sys::general::POLLWRBAND as u16; - /// `POLLERR` - const ERR = linux_raw_sys::general::POLLERR as u16; - /// `POLLHUP` - const HUP = linux_raw_sys::general::POLLHUP as u16; - /// `POLLNVAL` - const NVAL = linux_raw_sys::general::POLLNVAL as u16; - /// `POLLRDHUP` - const RDHUP = linux_raw_sys::general::POLLRDHUP as u16; - } -} - -/// `struct pollfd`—File descriptor and flags for use with [`poll`]. -/// -/// [`poll`]: crate::io::poll -#[doc(alias = "pollfd")] -#[repr(C)] -#[derive(Debug, Clone)] -pub struct PollFd<'fd> { - pub(crate) fd: BorrowedFd<'fd>, - pub(crate) events: u16, - pub(crate) revents: u16, -} - -impl<'fd> PollFd<'fd> { - /// Constructs a new `PollFd` holding `fd` and `events`. - #[inline] - pub fn new(fd: &'fd Fd, events: PollFlags) -> Self { - Self::from_borrowed_fd(fd.as_fd(), events) - } - - /// Sets the contained file descriptor to `fd`. - #[inline] - pub fn set_fd(&mut self, fd: &'fd Fd) { - self.fd = fd.as_fd(); - } - - /// Clears the ready events. - #[inline] - pub fn clear_revents(&mut self) { - self.revents = 0; - } - - /// Constructs a new `PollFd` holding `fd` and `events`. - /// - /// This is the same as `new`, but can be used to avoid borrowing the - /// `BorrowedFd`, which can be tricky in situations where the `BorrowedFd` - /// is a temporary. - #[inline] - pub fn from_borrowed_fd(fd: BorrowedFd<'fd>, events: PollFlags) -> Self { - Self { - fd, - events: events.bits(), - revents: 0, - } - } - - /// Returns the ready events. - #[inline] - pub fn revents(&self) -> PollFlags { - // Use `unwrap()` here because in theory we know we know all the bits - // the OS might set here, but OS's have added extensions in the past. - PollFlags::from_bits(self.revents).unwrap() - } -} - -impl<'fd> AsFd for PollFd<'fd> { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.fd.as_fd() - } -} diff --git a/vendor/rustix/src/imp/linux_raw/io/syscalls.rs b/vendor/rustix/src/imp/linux_raw/io/syscalls.rs deleted file mode 100644 index 7857859de..000000000 --- a/vendor/rustix/src/imp/linux_raw/io/syscalls.rs +++ /dev/null @@ -1,560 +0,0 @@ -//! linux_raw syscalls supporting `rustix::io`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![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, pass_usize, raw_fd, ret, ret_discarded_fd, ret_owned_fd, ret_usize, - slice, slice_mut, zero, -}; -#[cfg(target_pointer_width = "32")] -use super::super::conv::{hi, lo}; -use crate::fd::{AsFd, BorrowedFd, RawFd}; -use crate::io::{ - self, epoll, DupFlags, EventfdFlags, IoSlice, IoSliceMut, OwnedFd, PipeFlags, PollFd, - ReadWriteFlags, -}; -#[cfg(feature = "net")] -use crate::net::{RecvFlags, SendFlags}; -use core::cmp; -use core::mem::MaybeUninit; -use linux_raw_sys::general::{ - epoll_event, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, UIO_MAXIOV, -}; -use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, 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, sigset_t}, -}; - -#[inline] -pub(crate) fn read(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - - unsafe { ret_usize(syscall!(__NR_read, fd, buf_addr_mut, buf_len)) } -} - -#[inline] -pub(crate) fn pread(fd: BorrowedFd<'_>, buf: &mut [u8], pos: u64) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - - // - #[cfg(all( - target_pointer_width = "32", - any(target_arch = "arm", target_arch = "mips", target_arch = "power"), - ))] - unsafe { - ret_usize(syscall!( - __NR_pread64, - fd, - buf_addr_mut, - buf_len, - zero(), - hi(pos), - lo(pos) - )) - } - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "arm", target_arch = "mips", target_arch = "power")), - ))] - unsafe { - ret_usize(syscall!( - __NR_pread64, - fd, - buf_addr_mut, - buf_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_pread64, - fd, - buf_addr_mut, - buf_len, - loff_t_from_u64(pos) - )) - } -} - -#[inline] -pub(crate) fn readv(fd: BorrowedFd<'_>, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); - - unsafe { ret_usize(syscall!(__NR_readv, fd, bufs_addr, bufs_len)) } -} - -#[inline] -pub(crate) fn preadv( - fd: BorrowedFd<'_>, - bufs: &mut [IoSliceMut<'_>], - pos: u64, -) -> io::Result { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); - - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall!( - __NR_preadv, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_preadv, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos) - )) - } -} - -#[inline] -pub(crate) fn preadv2( - fd: BorrowedFd<'_>, - bufs: &mut [IoSliceMut<'_>], - pos: u64, - flags: ReadWriteFlags, -) -> io::Result { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); - - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall!( - __NR_preadv2, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos), - flags - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall!( - __NR_preadv2, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos), - flags - )) - } -} - -#[inline] -pub(crate) fn write(fd: BorrowedFd<'_>, buf: &[u8]) -> io::Result { - let (buf_addr, buf_len) = slice(buf); - - unsafe { ret_usize(syscall_readonly!(__NR_write, fd, buf_addr, buf_len)) } -} - -#[inline] -pub(crate) fn pwrite(fd: BorrowedFd<'_>, buf: &[u8], pos: u64) -> io::Result { - let (buf_addr, buf_len) = slice(buf); - - // - #[cfg(all( - target_pointer_width = "32", - any(target_arch = "arm", target_arch = "mips", target_arch = "power"), - ))] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwrite64, - fd, - buf_addr, - buf_len, - zero(), - hi(pos), - lo(pos) - )) - } - #[cfg(all( - target_pointer_width = "32", - not(any(target_arch = "arm", target_arch = "mips", target_arch = "power")), - ))] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwrite64, - fd, - buf_addr, - buf_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwrite64, - fd, - buf_addr, - buf_len, - loff_t_from_u64(pos) - )) - } -} - -#[inline] -pub(crate) fn writev(fd: BorrowedFd<'_>, bufs: &[IoSlice<'_>]) -> io::Result { - 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 { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); - - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos) - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos) - )) - } -} - -#[inline] -pub(crate) fn pwritev2( - fd: BorrowedFd<'_>, - bufs: &[IoSlice<'_>], - pos: u64, - flags: ReadWriteFlags, -) -> io::Result { - let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), max_iov())]); - - #[cfg(target_pointer_width = "32")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev2, - fd, - bufs_addr, - bufs_len, - hi(pos), - lo(pos), - flags - )) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret_usize(syscall_readonly!( - __NR_pwritev2, - fd, - bufs_addr, - bufs_len, - loff_t_from_u64(pos), - flags - )) - } -} - -/// 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. - syscall_readonly!(__NR_close, raw_fd(fd)).decode_void(); -} - -#[inline] -pub(crate) fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result { - unsafe { ret_owned_fd(syscall_readonly!(__NR_eventfd2, c_uint(initval), flags)) } -} - -#[inline] -pub(crate) fn ioctl_fionread(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(FIONREAD), &mut result)) - .map(|()| result.assume_init() as u64) - } -} - -#[inline] -pub(crate) fn ioctl_fionbio(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { - unsafe { - let data = c::c_int::from(value); - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(FIONBIO), - by_ref(&data) - )) - } -} - -#[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 { - let mut result = MaybeUninit::::uninit(); - unsafe { - ret(syscall!(__NR_ioctl, fd, c_uint(BLKSSZGET), &mut result)) - .map(|()| result.assume_init() as u32) - } -} - -#[inline] -pub(crate) fn ioctl_blkpbszget(fd: BorrowedFd) -> io::Result { - let mut result = MaybeUninit::::uninit(); - unsafe { - ret(syscall!(__NR_ioctl, fd, c_uint(BLKPBSZGET), &mut result)) - .map(|()| result.assume_init() as u32) - } -} - -#[cfg(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)?; - let mut not_socket = false; - if read { - // Do a `recv` with `PEEK` and `DONTWAIT` for 1 byte. A 0 indicates - // the read side is shut down; an `EWOULDBLOCK` indicates the read - // side is still open. - // - // 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) - { - Ok(0) => read = false, - Err(err) => { - #[allow(unreachable_patterns)] // `EAGAIN` may equal `EWOULDBLOCK` - match err { - io::Errno::AGAIN | io::Errno::WOULDBLOCK => (), - io::Errno::NOTSOCK => not_socket = true, - _ => return Err(err), - } - } - Ok(_) => (), - } - } - if write && !not_socket { - // 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) { - // TODO or-patterns when we don't need 1.51 - Err(io::Errno::AGAIN) => (), - Err(io::Errno::WOULDBLOCK) => (), - Err(io::Errno::NOTSOCK) => (), - Err(io::Errno::PIPE) => write = false, - Err(err) => return Err(err), - Ok(_) => (), - } - } - Ok((read, write)) -} - -#[inline] -pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result { - unsafe { ret_owned_fd(syscall_readonly!(__NR_dup, fd)) } -} - -#[inline] -pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - { - // We don't need to worry about the difference between `dup2` and - // `dup3` when the file descriptors are equal because we have an - // `&mut OwnedFd` which means `fd` doesn't alias it. - dup3(fd, new, DupFlags::empty()) - } - - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - ret_discarded_fd(syscall_readonly!(__NR_dup2, fd, new.as_fd())) - } -} - -#[inline] -pub(crate) fn dup3(fd: BorrowedFd<'_>, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { - unsafe { ret_discarded_fd(syscall_readonly!(__NR_dup3, fd, new.as_fd(), flags)) } -} - -#[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 { - 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::() - )) - } - #[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 { - 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 { - #[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() - )) - } -} diff --git a/vendor/rustix/src/imp/linux_raw/io/types.rs b/vendor/rustix/src/imp/linux_raw/io/types.rs deleted file mode 100644 index 282a23aa1..000000000 --- a/vendor/rustix/src/imp/linux_raw/io/types.rs +++ /dev/null @@ -1,67 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`]. - /// - /// [`preadv2`]: crate::io::preadv2 - /// [`pwritev2`]: crate::io::pwritev - pub struct ReadWriteFlags: c::c_uint { - /// `RWF_DSYNC` (since Linux 4.7) - const DSYNC = linux_raw_sys::general::RWF_DSYNC; - /// `RWF_HIPRI` (since Linux 4.6) - const HIPRI = linux_raw_sys::general::RWF_HIPRI; - /// `RWF_SYNC` (since Linux 4.7) - const SYNC = linux_raw_sys::general::RWF_SYNC; - /// `RWF_NOWAIT` (since Linux 4.14) - const NOWAIT = linux_raw_sys::general::RWF_NOWAIT; - /// `RWF_APPEND` (since Linux 4.16) - const APPEND = linux_raw_sys::general::RWF_APPEND; - } -} - -bitflags! { - /// `O_*` constants for use with [`dup2`]. - /// - /// [`dup2`]: crate::io::dup2 - 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; diff --git a/vendor/rustix/src/imp/linux_raw/io_uring/mod.rs b/vendor/rustix/src/imp/linux_raw/io_uring/mod.rs deleted file mode 100644 index ef944f04d..000000000 --- a/vendor/rustix/src/imp/linux_raw/io_uring/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod syscalls; diff --git a/vendor/rustix/src/imp/linux_raw/io_uring/syscalls.rs b/vendor/rustix/src/imp/linux_raw/io_uring/syscalls.rs deleted file mode 100644 index 812568efc..000000000 --- a/vendor/rustix/src/imp/linux_raw/io_uring/syscalls.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! linux_raw syscalls supporting `rustix::io_uring`. -//! -//! # Safety -//! -//! See the `rustix::imp::syscalls` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::super::conv::{by_mut, c_uint, pass_usize, ret, ret_c_uint, ret_owned_fd}; -use crate::fd::BorrowedFd; -use crate::io; -use crate::io::OwnedFd; -use crate::io_uring::{io_uring_params, IoringEnterFlags, IoringRegisterOp}; -use core::ffi::c_void; - -#[inline] -pub(crate) fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result { - unsafe { - ret_owned_fd(syscall!( - __NR_io_uring_setup, - c_uint(entries), - by_mut(params) - )) - } -} - -#[inline] -pub(crate) unsafe fn io_uring_register( - fd: BorrowedFd<'_>, - opcode: IoringRegisterOp, - arg: *const c_void, - nr_args: u32, -) -> io::Result<()> { - ret(syscall_readonly!( - __NR_io_uring_register, - fd, - c_uint(opcode as u32), - arg, - c_uint(nr_args) - )) -} - -#[inline] -pub(crate) unsafe fn io_uring_enter( - fd: BorrowedFd<'_>, - to_submit: u32, - min_complete: u32, - flags: IoringEnterFlags, - arg: *const c_void, - size: usize, -) -> io::Result { - // This is not `_readonly` because `io_uring_enter` waits for I/O to - // complete, and I/O could involve writing to memory buffers, which - // could be a side effect depended on by the caller. - ret_c_uint(syscall!( - __NR_io_uring_enter, - fd, - c_uint(to_submit), - c_uint(min_complete), - flags, - arg, - pass_usize(size) - )) -} diff --git a/vendor/rustix/src/imp/linux_raw/mm/mod.rs b/vendor/rustix/src/imp/linux_raw/mm/mod.rs deleted file mode 100644 index 1e0181a99..000000000 --- a/vendor/rustix/src/imp/linux_raw/mm/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/linux_raw/mm/syscalls.rs b/vendor/rustix/src/imp/linux_raw/mm/syscalls.rs deleted file mode 100644 index 8b230be3d..000000000 --- a/vendor/rustix/src/imp/linux_raw/mm/syscalls.rs +++ /dev/null @@ -1,214 +0,0 @@ -//! linux_raw syscalls supporting `rustix::io`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![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::fd::BorrowedFd; -use crate::io::{self, OwnedFd}; -#[cfg(target_pointer_width = "32")] -use core::convert::TryInto; -use linux_raw_sys::general::MAP_ANONYMOUS; - -#[inline] -pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_madvise, - addr, - pass_usize(len), - c_uint(advice as c::c_uint) - )) - } -} - -#[inline] -pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - ret(syscall!(__NR_msync, addr, pass_usize(len), flags)) -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn mmap( - addr: *mut c::c_void, - length: usize, - prot: ProtFlags, - flags: MapFlags, - fd: BorrowedFd<'_>, - offset: u64, -) -> io::Result<*mut c::c_void> { - #[cfg(target_pointer_width = "32")] - { - ret_void_star(syscall!( - __NR_mmap2, - addr, - pass_usize(length), - prot, - flags, - fd, - (offset / 4096) - .try_into() - .map(|scaled_offset| pass_usize(scaled_offset)) - .map_err(|_| io::Errno::INVAL)? - )) - } - #[cfg(target_pointer_width = "64")] - { - ret_void_star(syscall!( - __NR_mmap, - addr, - pass_usize(length), - prot, - flags, - fd, - loff_t_from_u64(offset) - )) - } -} - -/// # Safety -/// -/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working -/// with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn mmap_anonymous( - addr: *mut c::c_void, - length: usize, - prot: ProtFlags, - flags: MapFlags, -) -> io::Result<*mut c::c_void> { - #[cfg(target_pointer_width = "32")] - { - ret_void_star(syscall!( - __NR_mmap2, - addr, - pass_usize(length), - prot, - c_uint(flags.bits() | MAP_ANONYMOUS), - no_fd(), - pass_usize(0) - )) - } - #[cfg(target_pointer_width = "64")] - { - ret_void_star(syscall!( - __NR_mmap, - addr, - pass_usize(length), - prot, - c_uint(flags.bits() | MAP_ANONYMOUS), - no_fd(), - loff_t_from_u64(0) - )) - } -} - -#[inline] -pub(crate) unsafe fn mprotect( - ptr: *mut c::c_void, - len: usize, - flags: MprotectFlags, -) -> io::Result<()> { - ret(syscall!(__NR_mprotect, ptr, pass_usize(len), flags)) -} - -/// # Safety -/// -/// `munmap` is primarily unsafe due to the `addr` parameter, as anything -/// working with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn munmap(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(syscall!(__NR_munmap, addr, pass_usize(length))) -} - -/// # Safety -/// -/// `mremap` is primarily unsafe due to the `old_address` parameter, as -/// anything working with memory pointed to by raw pointers is unsafe. -#[inline] -pub(crate) unsafe fn mremap( - old_address: *mut c::c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, -) -> io::Result<*mut c::c_void> { - ret_void_star(syscall!( - __NR_mremap, - old_address, - pass_usize(old_size), - pass_usize(new_size), - flags - )) -} - -/// # Safety -/// -/// `mremap_fixed` is primarily unsafe due to the `old_address` and -/// `new_address` parameters, as anything working with memory pointed to by raw -/// pointers is unsafe. -#[inline] -pub(crate) unsafe fn mremap_fixed( - old_address: *mut c::c_void, - old_size: usize, - new_size: usize, - flags: MremapFlags, - new_address: *mut c::c_void, -) -> io::Result<*mut c::c_void> { - ret_void_star(syscall!( - __NR_mremap, - old_address, - pass_usize(old_size), - pass_usize(new_size), - flags, - new_address - )) -} - -/// # Safety -/// -/// `mlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(syscall!(__NR_mlock, addr, pass_usize(length))) -} - -/// # Safety -/// -/// `mlock_with` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn mlock_with( - addr: *mut c::c_void, - length: usize, - flags: MlockFlags, -) -> io::Result<()> { - ret(syscall!(__NR_mlock2, addr, pass_usize(length), flags)) -} - -/// # Safety -/// -/// `munlock` operates on raw pointers and may round out to the nearest page -/// boundaries. -#[inline] -pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> { - ret(syscall!(__NR_munlock, addr, pass_usize(length))) -} - -#[inline] -pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result { - ret_owned_fd(syscall_readonly!(__NR_userfaultfd, flags)) -} diff --git a/vendor/rustix/src/imp/linux_raw/mm/types.rs b/vendor/rustix/src/imp/linux_raw/mm/types.rs deleted file mode 100644 index a58dd76be..000000000 --- a/vendor/rustix/src/imp/linux_raw/mm/types.rs +++ /dev/null @@ -1,208 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `PROT_*` flags for use with [`mmap`]. - /// - /// For `PROT_NONE`, use `ProtFlags::empty()`. - /// - /// [`mmap`]: crate::io::mmap - pub struct ProtFlags: u32 { - /// `PROT_READ` - const READ = linux_raw_sys::general::PROT_READ; - /// `PROT_WRITE` - const WRITE = linux_raw_sys::general::PROT_WRITE; - /// `PROT_EXEC` - const EXEC = linux_raw_sys::general::PROT_EXEC; - } -} - -bitflags! { - /// `PROT_*` flags for use with [`mprotect`]. - /// - /// For `PROT_NONE`, use `MprotectFlags::empty()`. - /// - /// [`mprotect`]: crate::io::mprotect - pub struct MprotectFlags: u32 { - /// `PROT_READ` - const READ = linux_raw_sys::general::PROT_READ; - /// `PROT_WRITE` - const WRITE = linux_raw_sys::general::PROT_WRITE; - /// `PROT_EXEC` - const EXEC = linux_raw_sys::general::PROT_EXEC; - /// `PROT_GROWSUP` - const GROWSUP = linux_raw_sys::general::PROT_GROWSUP; - /// `PROT_GROWSDOWN` - const GROWSDOWN = linux_raw_sys::general::PROT_GROWSDOWN; - } -} - -bitflags! { - /// `MAP_*` flags for use with [`mmap`]. - /// - /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`]. - /// - /// [`mmap`]: crate::io::mmap - /// [`mmap_anonymous`]: crates::io::mmap_anonymous - pub struct MapFlags: u32 { - /// `MAP_SHARED` - const SHARED = linux_raw_sys::general::MAP_SHARED; - /// `MAP_SHARED_VALIDATE` (since Linux 4.15) - const SHARED_VALIDATE = linux_raw_sys::general::MAP_SHARED_VALIDATE; - /// `MAP_PRIVATE` - const PRIVATE = linux_raw_sys::general::MAP_PRIVATE; - /// `MAP_DENYWRITE` - const DENYWRITE = linux_raw_sys::general::MAP_DENYWRITE; - /// `MAP_FIXED` - const FIXED = linux_raw_sys::general::MAP_FIXED; - /// `MAP_FIXED_NOREPLACE` (since Linux 4.17) - const FIXED_NOREPLACE = linux_raw_sys::general::MAP_FIXED_NOREPLACE; - /// `MAP_GROWSDOWN` - const GROWSDOWN = linux_raw_sys::general::MAP_GROWSDOWN; - /// `MAP_HUGETLB` - const HUGETLB = linux_raw_sys::general::MAP_HUGETLB; - /// `MAP_HUGE_2MB` (since Linux 3.8) - const HUGE_2MB = linux_raw_sys::general::MAP_HUGE_2MB; - /// `MAP_HUGE_1GB` (since Linux 3.8) - const HUGE_1GB = linux_raw_sys::general::MAP_HUGE_1GB; - /// `MAP_LOCKED` - const LOCKED = linux_raw_sys::general::MAP_LOCKED; - /// `MAP_NORESERVE` - const NORESERVE = linux_raw_sys::general::MAP_NORESERVE; - /// `MAP_POPULATE` - const POPULATE = linux_raw_sys::general::MAP_POPULATE; - /// `MAP_STACK` - const STACK = linux_raw_sys::general::MAP_STACK; - /// `MAP_SYNC` (since Linux 4.15) - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] - const SYNC = linux_raw_sys::general::MAP_SYNC; - /// `MAP_UNINITIALIZED` - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] - const UNINITIALIZED = linux_raw_sys::general::MAP_UNINITIALIZED; - } -} - -bitflags! { - /// `MREMAP_*` flags for use with [`mremap`]. - /// - /// For `MREMAP_FIXED`, see [`mremap_fixed`]. - /// - /// [`mremap`]: crate::io::mremap - /// [`mremap_fixed`]: crate::io::mremap_fixed - pub struct MremapFlags: u32 { - /// `MREMAP_MAYMOVE` - const MAYMOVE = linux_raw_sys::general::MREMAP_MAYMOVE; - /// `MREMAP_DONTUNMAP` (since Linux 5.7) - const DONTUNMAP = linux_raw_sys::general::MREMAP_DONTUNMAP; - } -} - -bitflags! { - /// `MLOCK_*` flags for use with [`mlock_with`]. - /// - /// [`mlock_with`]: crate::io::mlock_with - pub struct MlockFlags: u32 { - /// `MLOCK_ONFAULT` - const ONFAULT = linux_raw_sys::general::MLOCK_ONFAULT; - } -} - -bitflags! { - /// `MS_*` flags for use with [`msync`]. - /// - /// [`msync`]: crate::io::msync - pub struct MsyncFlags: u32 { - /// `MS_SYNC`—Requests an update and waits for it to complete. - const SYNC = linux_raw_sys::general::MS_SYNC; - /// `MS_ASYNC`—Specifies that an update be scheduled, but the call - /// returns immediately. - const ASYNC = linux_raw_sys::general::MS_ASYNC; - /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same - /// file (so that they can be updated with the fresh values just - /// written). - const INVALIDATE = linux_raw_sys::general::MS_INVALIDATE; - } -} - -bitflags! { - /// `O_*` flags for use with [`userfaultfd`]. - /// - /// [`userfaultfd`]: crate::io::userfaultfd - pub struct UserfaultfdFlags: c::c_uint { - /// `O_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::O_CLOEXEC; - /// `O_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::O_NONBLOCK; - } -} - -/// `POSIX_MADV_*` constants for use with [`madvise`]. -/// -/// [`madvise`]: crate::mm::madvise -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -#[non_exhaustive] -pub enum Advice { - /// `POSIX_MADV_NORMAL` - Normal = linux_raw_sys::general::MADV_NORMAL, - - /// `POSIX_MADV_SEQUENTIAL` - Sequential = linux_raw_sys::general::MADV_SEQUENTIAL, - - /// `POSIX_MADV_RANDOM` - Random = linux_raw_sys::general::MADV_RANDOM, - - /// `POSIX_MADV_WILLNEED` - WillNeed = linux_raw_sys::general::MADV_WILLNEED, - - /// `MADV_DONTNEED` - LinuxDontNeed = linux_raw_sys::general::MADV_DONTNEED, - - /// `MADV_FREE` (since Linux 4.5) - LinuxFree = linux_raw_sys::general::MADV_FREE, - /// `MADV_REMOVE` - LinuxRemove = linux_raw_sys::general::MADV_REMOVE, - /// `MADV_DONTFORK` - LinuxDontFork = linux_raw_sys::general::MADV_DONTFORK, - /// `MADV_DOFORK` - LinuxDoFork = linux_raw_sys::general::MADV_DOFORK, - /// `MADV_HWPOISON` - LinuxHwPoison = linux_raw_sys::general::MADV_HWPOISON, - /// `MADV_SOFT_OFFLINE` - #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] - LinuxSoftOffline = linux_raw_sys::general::MADV_SOFT_OFFLINE, - /// `MADV_MERGEABLE` - LinuxMergeable = linux_raw_sys::general::MADV_MERGEABLE, - /// `MADV_UNMERGEABLE` - LinuxUnmergeable = linux_raw_sys::general::MADV_UNMERGEABLE, - /// `MADV_HUGEPAGE` (since Linux 2.6.38) - LinuxHugepage = linux_raw_sys::general::MADV_HUGEPAGE, - /// `MADV_NOHUGEPAGE` (since Linux 2.6.38) - LinuxNoHugepage = linux_raw_sys::general::MADV_NOHUGEPAGE, - /// `MADV_DONTDUMP` (since Linux 3.4) - LinuxDontDump = linux_raw_sys::general::MADV_DONTDUMP, - /// `MADV_DODUMP` (since Linux 3.4) - LinuxDoDump = linux_raw_sys::general::MADV_DODUMP, - /// `MADV_WIPEONFORK` (since Linux 4.14) - LinuxWipeOnFork = linux_raw_sys::general::MADV_WIPEONFORK, - /// `MADV_KEEPONFORK` (since Linux 4.14) - LinuxKeepOnFork = linux_raw_sys::general::MADV_KEEPONFORK, - /// `MADV_COLD` (since Linux 5.4) - LinuxCold = linux_raw_sys::general::MADV_COLD, - /// `MADV_PAGEOUT` (since Linux 5.4) - LinuxPageOut = linux_raw_sys::general::MADV_PAGEOUT, - /// `MADV_POPULATE_READ` (since Linux 5.14) - LinuxPopulateRead = linux_raw_sys::general::MADV_POPULATE_READ, - /// `MADV_POPULATE_WRITE` (since Linux 5.14) - LinuxPopulateWrite = linux_raw_sys::general::MADV_POPULATE_WRITE, -} - -impl Advice { - /// `POSIX_MADV_DONTNEED` - /// - /// On Linux, this is mapped to `POSIX_MADV_NORMAL` because - /// Linux's `MADV_DONTNEED` differs from `POSIX_MADV_DONTNEED`. See - /// `LinuxDontNeed` for the Linux behavior. - #[allow(non_upper_case_globals)] - pub const DontNeed: Self = Self::Normal; -} diff --git a/vendor/rustix/src/imp/linux_raw/mod.rs b/vendor/rustix/src/imp/linux_raw/mod.rs deleted file mode 100644 index ed46eaad1..000000000 --- a/vendor/rustix/src/imp/linux_raw/mod.rs +++ /dev/null @@ -1,68 +0,0 @@ -//! The linux_raw backend. -//! -//! This makes Linux syscalls directly, without going through libc. -//! -//! # Safety -//! -//! These files performs raw system calls, and sometimes passes them -//! uninitialized memory buffers. The signatures in this file are currently -//! manually maintained and must correspond with the signatures of the actual -//! Linux syscalls. -//! -//! Some of this could be auto-generated from the Linux header file -//! , but we often need more information than it provides, -//! such as which pointers are array slices, out parameters, or in-out -//! parameters, which integers are owned or borrowed file descriptors, etc. - -#[macro_use] -mod arch; -mod conv; -mod elf; -mod reg; -#[cfg(any(feature = "time", target_arch = "x86"))] -mod vdso; -#[cfg(any(feature = "time", target_arch = "x86"))] -mod vdso_wrappers; - -#[cfg(any( - feature = "param", - feature = "runtime", - feature = "time", - target_arch = "x86", -))] -pub(crate) mod param; -// #[cfg(feature = "fs")] // TODO: Enable once `OwnedFd` moves out of the tree. -pub(crate) mod fs; -pub(crate) mod io; -#[cfg(feature = "io_uring")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "io_uring")))] -pub(crate) mod io_uring; -#[cfg(any(feature = "mm", feature = "time", target_arch = "x86"))] // vdso.rs uses `madvise` -pub(crate) mod mm; -#[cfg(feature = "net")] -pub(crate) mod net; -pub(crate) mod process; -#[cfg(feature = "rand")] -pub(crate) mod rand; -#[cfg(feature = "runtime")] -pub(crate) mod runtime; -#[cfg(feature = "termios")] -pub(crate) mod termios; -#[cfg(feature = "thread")] -pub(crate) mod thread; -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}; -} - -#[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; diff --git a/vendor/rustix/src/imp/linux_raw/net/addr.rs b/vendor/rustix/src/imp/linux_raw/net/addr.rs deleted file mode 100644 index d5683f34e..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/addr.rs +++ /dev/null @@ -1,172 +0,0 @@ -//! IPv4, IPv6, and Socket addresses. -//! -//! # Safety -//! -//! Linux's IPv6 type contains a union. -#![allow(unsafe_code)] - -use super::super::c; -use crate::ffi::CStr; -use crate::{io, path}; -use core::convert::TryInto; -use core::{fmt, slice}; - -/// `struct sockaddr_un` -#[derive(Clone)] -#[doc(alias = "sockaddr_un")] -pub struct SocketAddrUnix { - pub(crate) unix: c::sockaddr_un, - len: c::socklen_t, -} - -impl SocketAddrUnix { - /// Construct a new Unix-domain address from a filesystem path. - #[inline] - pub fn new(path: P) -> io::Result { - path.into_with_c_str(Self::_new) - } - - #[inline] - fn _new(path: &CStr) -> io::Result { - let mut unix = Self::init(); - let bytes = path.to_bytes_with_nul(); - if bytes.len() > unix.sun_path.len() { - return Err(io::Errno::NAMETOOLONG); - } - for (i, b) in bytes.iter().enumerate() { - unix.sun_path[i] = *b as c::c_char; - } - let len = offsetof_sun_path() + bytes.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) - } - - /// Construct a new abstract Unix-domain address from a byte slice. - #[inline] - pub fn new_abstract_name(name: &[u8]) -> io::Result { - 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 len = offsetof_sun_path() + 1 + name.len(); - let len = len.try_into().unwrap(); - Ok(Self { unix, len }) - } - - fn init() -> c::sockaddr_un { - c::sockaddr_un { - sun_family: c::AF_UNIX as _, - sun_path: [0; 108], - } - } - - /// For a filesystem path address, return the path. - #[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 { - 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(), - ))) - } - } else { - None - } - } - - /// For an abstract address, return the identifier. - #[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 { - 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())) } - } else { - None - } - } - - #[inline] - pub(crate) fn addr_len(&self) -> c::socklen_t { - self.len - } - - #[inline] - pub(crate) fn len(&self) -> usize { - self.addr_len() as usize - } -} - -impl PartialEq for SocketAddrUnix { - #[inline] - fn eq(&self, other: &Self) -> bool { - let self_len = self.len() - offsetof_sun_path(); - let other_len = other.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].eq(&other.unix.sun_path[..other_len]) - } -} - -impl Eq for SocketAddrUnix {} - -impl PartialOrd for SocketAddrUnix { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - 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]) - } -} - -impl Ord for SocketAddrUnix { - #[inline] - fn cmp(&self, other: &Self) -> core::cmp::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 { - #[inline] - fn hash(&self, state: &mut H) { - let self_len = self.len() - offsetof_sun_path(); - self.unix.sun_path[..self_len].hash(state) - } -} - -impl fmt::Debug for SocketAddrUnix { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(path) = self.path() { - path.fmt(fmt) - } else if let Some(name) = self.abstract_name() { - name.fmt(fmt) - } else { - "(unnamed)".fmt(fmt) - } - } -} - -/// `struct sockaddr_storage` as a raw struct. -pub type SocketAddrStorage = c::sockaddr; - -/// Return the offset of the `sun_path` field of `sockaddr_un`. -#[inline] -pub(crate) fn offsetof_sun_path() -> usize { - let z = c::sockaddr_un { - sun_family: 0_u16, - sun_path: [0; 108], - }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) -} diff --git a/vendor/rustix/src/imp/linux_raw/net/ext.rs b/vendor/rustix/src/imp/linux_raw/net/ext.rs deleted file mode 100644 index 8556c9d90..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/ext.rs +++ /dev/null @@ -1,64 +0,0 @@ -#![allow(unsafe_code)] - -use super::super::c; - -#[inline] -pub(crate) const fn in_addr_s_addr(addr: c::in_addr) -> u32 { - addr.s_addr -} - -#[inline] -pub(crate) const fn in_addr_new(s_addr: u32) -> c::in_addr { - c::in_addr { s_addr } -} - -#[cfg(not(feature = "std"))] -#[inline] -pub(crate) const fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - // Safety: `in6_addr` is `repr(C)` and contains plain integer data. - unsafe { addr.in6_u.u6_addr8 } -} - -// TODO: With Rust 1.55, we can use the above `in6_addr_s6_addr` definition -// that uses a const-fn union access instead of doing a transmute. -#[cfg(not(not(feature = "std")))] -#[inline] -pub(crate) fn in6_addr_s6_addr(addr: c::in6_addr) -> [u8; 16] { - // Safety: `in6_addr` is `repr(C)` and contains plain integer data. - unsafe { core::mem::transmute(addr) } -} - -#[inline] -pub(crate) const fn in6_addr_new(s6_addr: [u8; 16]) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { u6_addr8: s6_addr }, - } -} - -#[inline] -pub(crate) const fn sockaddr_in6_sin6_scope_id(addr: c::sockaddr_in6) -> u32 { - addr.sin6_scope_id -} - -#[cfg(not(feature = "std"))] -#[inline] -pub(crate) fn sockaddr_in6_sin6_scope_id_mut(addr: &mut c::sockaddr_in6) -> &mut u32 { - &mut addr.sin6_scope_id -} - -#[inline] -pub(crate) const fn sockaddr_in6_new( - sin6_family: c::sa_family_t, - sin6_port: u16, - sin6_flowinfo: u32, - sin6_addr: c::in6_addr, - sin6_scope_id: u32, -) -> c::sockaddr_in6 { - c::sockaddr_in6 { - sin6_family, - sin6_port, - sin6_flowinfo, - sin6_addr, - sin6_scope_id, - } -} diff --git a/vendor/rustix/src/imp/linux_raw/net/mod.rs b/vendor/rustix/src/imp/linux_raw/net/mod.rs deleted file mode 100644 index 5e67dfd21..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub(crate) mod addr; -#[cfg(not(feature = "std"))] -pub(crate) mod ext; -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/imp/linux_raw/net/read_sockaddr.rs b/vendor/rustix/src/imp/linux_raw/net/read_sockaddr.rs deleted file mode 100644 index b9bc09b96..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/read_sockaddr.rs +++ /dev/null @@ -1,175 +0,0 @@ -//! The BSD sockets API requires us to read the `ss_family` field before -//! we can interpret the rest of a `sockaddr` produced by the kernel. -#![allow(unsafe_code)] - -use super::super::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`. -#[repr(C)] -struct sockaddr_header { - ss_family: u16, -} - -/// Read the `ss_family` field from a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -#[inline] -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::general::__kernel_sockaddr_storage__bindgen_ty_1__bindgen_ty_1 { - ss_family: 0_u16, - __data: [0; 126_usize], - }, - }, - }, - }; - - (*storage.cast::()).ss_family -} - -/// Set the `ss_family` field of a socket address to `AF_UNSPEC`, so that we -/// can test for `AF_UNSPEC` to test whether it was stored to. -#[inline] -pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) { - (*storage.cast::()).ss_family = c::AF_UNSPEC as _; -} - -/// Read a socket address encoded in a platform-specific format. -/// -/// # Safety -/// -/// `storage` must point to valid socket address storage. -pub(crate) unsafe fn read_sockaddr( - storage: *const c::sockaddr, - len: usize, -) -> io::Result { - let offsetof_sun_path = super::addr::offsetof_sun_path(); - - if len < size_of::() { - return Err(io::Errno::INVAL); - } - match read_ss_family(storage).into() { - c::AF_INET => { - if len < size_of::() { - return Err(io::Errno::INVAL); - } - let decode = *storage.cast::(); - Ok(SocketAddrAny::V4(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), - u16::from_be(decode.sin_port), - ))) - } - c::AF_INET6 => { - if len < size_of::() { - return Err(io::Errno::INVAL); - } - let decode = *storage.cast::(); - Ok(SocketAddrAny::V6(SocketAddrV6::new( - Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - decode.sin6_scope_id, - ))) - } - c::AF_UNIX => { - if len < offsetof_sun_path { - return Err(io::Errno::INVAL); - } - if len == offsetof_sun_path { - Ok(SocketAddrAny::Unix(SocketAddrUnix::new(&[][..])?)) - } else { - let decode = *storage.cast::(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); - Ok(SocketAddrAny::Unix(SocketAddrUnix::new( - decode.sun_path[..len - 1 - offsetof_sun_path] - .iter() - .map(|c| *c as u8) - .collect::>(), - )?)) - } - } - _ => Err(io::Errno::NOTSUP), - } -} - -/// Read a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -pub(crate) unsafe fn maybe_read_sockaddr_os( - storage: *const c::sockaddr, - len: usize, -) -> Option { - if len == 0 { - None - } else { - Some(read_sockaddr_os(storage, len)) - } -} - -/// Read a socket address returned from the OS. -/// -/// # Safety -/// -/// `storage` must point to a valid socket address returned from the OS. -pub(crate) unsafe fn read_sockaddr_os(storage: *const c::sockaddr, len: usize) -> SocketAddrAny { - let offsetof_sun_path = super::addr::offsetof_sun_path(); - - assert!(len >= size_of::()); - match read_ss_family(storage).into() { - c::AF_INET => { - assert!(len >= size_of::()); - let decode = *storage.cast::(); - SocketAddrAny::V4(SocketAddrV4::new( - Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)), - u16::from_be(decode.sin_port), - )) - } - c::AF_INET6 => { - assert!(len >= size_of::()); - let decode = *storage.cast::(); - SocketAddrAny::V6(SocketAddrV6::new( - Ipv6Addr::from(decode.sin6_addr.in6_u.u6_addr8), - u16::from_be(decode.sin6_port), - u32::from_be(decode.sin6_flowinfo), - decode.sin6_scope_id, - )) - } - c::AF_UNIX => { - assert!(len >= offsetof_sun_path); - if len == offsetof_sun_path { - SocketAddrAny::Unix(SocketAddrUnix::new(&[][..]).unwrap()) - } else { - let decode = *storage.cast::(); - assert_eq!( - decode.sun_path[len - 1 - offsetof_sun_path], - b'\0' as c::c_char - ); - SocketAddrAny::Unix( - SocketAddrUnix::new( - decode.sun_path[..len - 1 - offsetof_sun_path] - .iter() - .map(|c| *c as u8) - .collect::>(), - ) - .unwrap(), - ) - } - } - other => unimplemented!("{:?}", other), - } -} diff --git a/vendor/rustix/src/imp/linux_raw/net/send_recv.rs b/vendor/rustix/src/imp/linux_raw/net/send_recv.rs deleted file mode 100644 index 888e81e2b..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/send_recv.rs +++ /dev/null @@ -1,42 +0,0 @@ -use super::super::c; -use bitflags::bitflags; - -bitflags! { - /// `MSG_*` - pub struct SendFlags: u32 { - /// `MSG_CONFIRM` - const CONFIRM = c::MSG_CONFIRM; - /// `MSG_DONTROUTE` - const DONTROUTE = c::MSG_DONTROUTE; - /// `MSG_DONTWAIT` - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_EOT` - const EOT = c::MSG_EOR; - /// `MSG_MORE` - const MORE = c::MSG_MORE; - /// `MSG_NOSIGNAL` - const NOSIGNAL = c::MSG_NOSIGNAL; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - } -} - -bitflags! { - /// `MSG_*` - pub struct RecvFlags: u32 { - /// `MSG_CMSG_CLOEXEC` - const CMSG_CLOEXEC = c::MSG_CMSG_CLOEXEC; - /// `MSG_DONTWAIT` - const DONTWAIT = c::MSG_DONTWAIT; - /// `MSG_ERRQUEUE` - const ERRQUEUE = c::MSG_ERRQUEUE; - /// `MSG_OOB` - const OOB = c::MSG_OOB; - /// `MSG_PEEK` - const PEEK = c::MSG_PEEK; - /// `MSG_TRUNC` - const TRUNC = c::MSG_TRUNC; - /// `MSG_WAITALL` - const WAITALL = c::MSG_WAITALL; - } -} diff --git a/vendor/rustix/src/imp/linux_raw/net/syscalls.rs b/vendor/rustix/src/imp/linux_raw/net/syscalls.rs deleted file mode 100644 index 18a0f130d..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/syscalls.rs +++ /dev/null @@ -1,1234 +0,0 @@ -//! linux_raw syscalls supporting `rustix::net`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![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::read_sockaddr::{initialize_family_to_unspec, maybe_read_sockaddr_os, read_sockaddr_os}; -use super::send_recv::{RecvFlags, SendFlags}; -use super::types::{AcceptFlags, AddressFamily, Protocol, Shutdown, SocketFlags, SocketType}; -use super::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6}; -use crate::fd::BorrowedFd; -use crate::io::{self, OwnedFd}; -use crate::net::{SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; -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::{ - 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, - }, -}; - -#[inline] -pub(crate) fn socket( - family: AddressFamily, - type_: SocketType, - protocol: Protocol, -) -> io::Result { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_owned_fd(syscall_readonly!(__NR_socket, family, type_, protocol)) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SOCKET), - slice_just_addr::, _>(&[ - family.into(), - type_.into(), - protocol.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn socket_with( - family: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Protocol, -) -> io::Result { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socket, - family, - (type_, flags), - protocol - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SOCKET), - slice_just_addr::, _>(&[ - family.into(), - (type_, flags).into(), - protocol.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn socketpair( - family: AddressFamily, - type_: SocketType, - flags: SocketFlags, - protocol: Protocol, -) -> io::Result<(OwnedFd, OwnedFd)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!( - __NR_socketpair, - family, - (type_, flags), - protocol, - &mut result - )) - .map(|()| { - let [fd0, fd1] = result.assume_init(); - (fd0, fd1) - }) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_SOCKETPAIR), - slice_just_addr::, _>(&[ - family.into(), - (type_, flags).into(), - protocol.into(), - (&mut result).into(), - ]) - )) - .map(|()| { - let [fd0, fd1] = result.assume_init(); - (fd0, fd1) - }) - } -} - -#[inline] -pub(crate) fn accept(fd: BorrowedFd<'_>) -> io::Result { - #[cfg(not(target_arch = "x86"))] - unsafe { - let fd = ret_owned_fd(syscall_readonly!(__NR_accept, fd, zero(), zero()))?; - Ok(fd) - } - #[cfg(target_arch = "x86")] - unsafe { - let fd = ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_ACCEPT), - slice_just_addr::, _>(&[fd.into(), zero(), zero()]) - ))?; - Ok(fd) - } -} - -#[inline] -pub(crate) fn accept_with(fd: BorrowedFd<'_>, flags: AcceptFlags) -> io::Result { - #[cfg(not(target_arch = "x86"))] - unsafe { - let fd = ret_owned_fd(syscall_readonly!(__NR_accept4, fd, zero(), zero(), flags))?; - Ok(fd) - } - #[cfg(target_arch = "x86")] - unsafe { - let fd = ret_owned_fd(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_ACCEPT4), - slice_just_addr::, _>(&[fd.into(), zero(), zero(), flags.into()]) - ))?; - Ok(fd) - } -} - -#[inline] -pub(crate) fn acceptfrom(fd: BorrowedFd<'_>) -> io::Result<(OwnedFd, Option)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_accept, - fd, - &mut storage, - by_mut(&mut addrlen) - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_socketcall, - x86_sys(SYS_ACCEPT), - slice_just_addr::, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } -} - -#[inline] -pub(crate) fn acceptfrom_with( - fd: BorrowedFd<'_>, - flags: AcceptFlags, -) -> io::Result<(OwnedFd, Option)> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_accept4, - fd, - &mut storage, - by_mut(&mut addrlen), - flags - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - let fd = ret_owned_fd(syscall!( - __NR_socketcall, - x86_sys(SYS_ACCEPT4), - slice_just_addr::, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - flags.into(), - ]) - ))?; - Ok(( - fd, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } -} - -#[inline] -pub(crate) fn shutdown(fd: BorrowedFd<'_>, how: Shutdown) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_shutdown, - fd, - c_uint(how as c::c_uint) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SHUTDOWN), - slice_just_addr::, _>(&[fd.into(), c_uint(how as c::c_uint)]) - )) - } -} - -#[inline] -pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Result { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "riscv64", - target_arch = "x86", - target_arch = "x86_64", - )))] - unsafe { - ret_usize(syscall_readonly!(__NR_send, fd, buf_addr, buf_len, flags)) - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "riscv64", - target_arch = "x86_64", - ))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - zero(), - zero() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SEND), - slice_just_addr::, _>(&[fd.into(), buf_addr, buf_len, flags.into()]) - )) - } -} - -#[inline] -pub(crate) fn sendto_v4( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrV4, -) -> io::Result { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - by_ref(&encode_sockaddr_v4(addr)), - size_of::() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - by_ref(&encode_sockaddr_v4(addr)), - size_of::(), - ]) - )) - } -} - -#[inline] -pub(crate) fn sendto_v6( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrV6, -) -> io::Result { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - by_ref(&encode_sockaddr_v6(addr)), - size_of::() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - by_ref(&encode_sockaddr_v6(addr)), - size_of::(), - ]) - )) - } -} - -#[inline] -pub(crate) fn sendto_unix( - fd: BorrowedFd<'_>, - buf: &[u8], - flags: SendFlags, - addr: &SocketAddrUnix, -) -> io::Result { - let (buf_addr, buf_len) = slice(buf); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret_usize(syscall_readonly!( - __NR_sendto, - fd, - buf_addr, - buf_len, - flags, - by_ref(&addr.unix), - socklen_t(addr.addr_len()) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SENDTO), - slice_just_addr::, _>(&[ - fd.into(), - buf_addr, - buf_len, - flags.into(), - by_ref(&addr.unix), - socklen_t(addr.addr_len()), - ]) - )) - } -} - -#[inline] -pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "riscv64", - target_arch = "x86", - target_arch = "x86_64", - )))] - unsafe { - ret_usize(syscall!(__NR_recv, fd, buf_addr_mut, buf_len, flags)) - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "mips64", - target_arch = "riscv64", - target_arch = "x86_64", - ))] - unsafe { - ret_usize(syscall!( - __NR_recvfrom, - fd, - buf_addr_mut, - buf_len, - flags, - zero(), - zero() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECV), - slice_just_addr::, _>(&[ - fd.into(), - buf_addr_mut, - buf_len, - flags.into(), - ]) - )) - } -} - -#[inline] -pub(crate) fn recvfrom( - fd: BorrowedFd<'_>, - buf: &mut [u8], - flags: RecvFlags, -) -> io::Result<(usize, Option)> { - let (buf_addr_mut, buf_len) = slice_mut(buf); - - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - - unsafe { - // `recvfrom` does not write to the storage if the socket is - // connection-oriented sockets, so we initialize the family field to - // `AF_UNSPEC` so that we can detect this case. - initialize_family_to_unspec(storage.as_mut_ptr()); - - #[cfg(not(target_arch = "x86"))] - let nread = ret_usize(syscall!( - __NR_recvfrom, - fd, - buf_addr_mut, - buf_len, - flags, - &mut storage, - by_mut(&mut addrlen) - ))?; - #[cfg(target_arch = "x86")] - let nread = ret_usize(syscall!( - __NR_socketcall, - x86_sys(SYS_RECVFROM), - slice_just_addr::, _>(&[ - fd.into(), - buf_addr_mut, - buf_len, - flags.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - - Ok(( - nread, - maybe_read_sockaddr_os(&storage.assume_init(), addrlen.try_into().unwrap()), - )) - } -} - -#[inline] -pub(crate) fn getpeername(fd: BorrowedFd<'_>) -> io::Result> { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - ret(syscall!( - __NR_getpeername, - fd, - &mut storage, - by_mut(&mut addrlen) - ))?; - Ok(maybe_read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETPEERNAME), - slice_just_addr::, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - Ok(maybe_read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } -} - -#[inline] -pub(crate) fn getsockname(fd: BorrowedFd<'_>) -> io::Result { - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - ret(syscall!( - __NR_getsockname, - fd, - &mut storage, - by_mut(&mut addrlen) - ))?; - Ok(read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut addrlen = core::mem::size_of::() as socklen_t; - let mut storage = MaybeUninit::::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKNAME), - slice_just_addr::, _>(&[ - fd.into(), - (&mut storage).into(), - by_mut(&mut addrlen), - ]) - ))?; - Ok(read_sockaddr_os( - &storage.assume_init(), - addrlen.try_into().unwrap(), - )) - } -} - -#[inline] -pub(crate) fn bind_v4(fd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_bind, - fd, - by_ref(&encode_sockaddr_v4(addr)), - size_of::() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v4(addr)), - size_of::(), - ]) - )) - } -} - -#[inline] -pub(crate) fn bind_v6(fd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_bind, - fd, - by_ref(&encode_sockaddr_v6(addr)), - size_of::() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v6(addr)), - size_of::(), - ]) - )) - } -} - -#[inline] -pub(crate) fn bind_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_bind, - fd, - by_ref(&addr.unix), - socklen_t(addr.addr_len()) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_BIND), - slice_just_addr::, _>(&[ - fd.into(), - by_ref(&addr.unix), - socklen_t(addr.addr_len()), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_v4(fd: BorrowedFd<'_>, addr: &SocketAddrV4) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&encode_sockaddr_v4(addr)), - size_of::() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v4(addr)), - size_of::(), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_v6(fd: BorrowedFd<'_>, addr: &SocketAddrV6) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&encode_sockaddr_v6(addr)), - size_of::() - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::, _>(&[ - fd.into(), - by_ref(&encode_sockaddr_v6(addr)), - size_of::(), - ]) - )) - } -} - -#[inline] -pub(crate) fn connect_unix(fd: BorrowedFd<'_>, addr: &SocketAddrUnix) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_connect, - fd, - by_ref(&addr.unix), - socklen_t(addr.addr_len()) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_CONNECT), - slice_just_addr::, _>(&[ - fd.into(), - by_ref(&addr.unix), - socklen_t(addr.addr_len()), - ]) - )) - } -} - -#[inline] -pub(crate) fn listen(fd: BorrowedFd<'_>, backlog: c::c_int) -> io::Result<()> { - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!(__NR_listen, fd, c_int(backlog))) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_LISTEN), - slice_just_addr::, _>(&[fd.into(), c_int(backlog)]) - )) - } -} - -pub(crate) mod sockopt { - use super::{c, BorrowedFd}; - use crate::io; - 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(fd: BorrowedFd<'_>, level: u32, optname: u32) -> io::Result { - use super::*; - - let mut optlen = core::mem::size_of::(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - let mut value = MaybeUninit::::uninit(); - ret(syscall!( - __NR_getsockopt, - fd, - c_uint(level), - c_uint(optname), - &mut value, - by_mut(&mut optlen) - ))?; - - assert_eq!( - optlen as usize, - core::mem::size_of::(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - #[cfg(target_arch = "x86")] - unsafe { - let mut value = MaybeUninit::::uninit(); - ret(syscall!( - __NR_socketcall, - x86_sys(SYS_GETSOCKOPT), - slice_just_addr::, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - (&mut value).into(), - by_mut(&mut optlen), - ]) - ))?; - assert_eq!( - optlen as usize, - core::mem::size_of::(), - "unexpected getsockopt size" - ); - Ok(value.assume_init()) - } - } - - #[inline] - fn setsockopt( - fd: BorrowedFd<'_>, - level: u32, - optname: u32, - value: T, - ) -> io::Result<()> { - use super::*; - - let optlen = core::mem::size_of::().try_into().unwrap(); - debug_assert!( - optlen as usize >= core::mem::size_of::(), - "Socket APIs don't ever use `bool` directly" - ); - - #[cfg(not(target_arch = "x86"))] - unsafe { - ret(syscall_readonly!( - __NR_setsockopt, - fd, - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen) - )) - } - #[cfg(target_arch = "x86")] - unsafe { - ret(syscall_readonly!( - __NR_socketcall, - x86_sys(SYS_SETSOCKOPT), - slice_just_addr::, _>(&[ - fd.into(), - c_uint(level), - c_uint(optname), - by_ref(&value), - socklen_t(optlen), - ]) - )) - } - } - - #[inline] - pub(crate) fn get_socket_type(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_TYPE) - } - - #[inline] - pub(crate) fn set_socket_reuseaddr(fd: BorrowedFd<'_>, reuseaddr: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_REUSEADDR, - from_bool(reuseaddr), - ) - } - - #[inline] - pub(crate) fn set_socket_broadcast(fd: BorrowedFd<'_>, broadcast: bool) -> io::Result<()> { - setsockopt( - fd, - c::SOL_SOCKET as _, - c::SO_BROADCAST, - from_bool(broadcast), - ) - } - - #[inline] - pub(crate) fn get_socket_broadcast(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_BROADCAST).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_linger( - fd: BorrowedFd<'_>, - linger: Option, - ) -> io::Result<()> { - // Convert `linger` to seconds, rounding up. - let l_linger = if let Some(linger) = linger { - let mut l_linger = linger.as_secs(); - if linger.subsec_nanos() != 0 { - l_linger = l_linger.checked_add(1).ok_or(io::Errno::INVAL)?; - } - l_linger.try_into().map_err(|_e| io::Errno::INVAL)? - } else { - 0 - }; - let linger = c::linger { - l_onoff: c::c_int::from(linger.is_some()), - l_linger, - }; - setsockopt(fd, c::SOL_SOCKET as _, c::SO_LINGER, linger) - } - - #[inline] - pub(crate) fn get_socket_linger(fd: BorrowedFd<'_>) -> io::Result> { - 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 - }) - } - - #[inline] - pub(crate) fn set_socket_passcred(fd: BorrowedFd<'_>, passcred: bool) -> io::Result<()> { - setsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED, from_bool(passcred)) - } - - #[inline] - pub(crate) fn get_socket_passcred(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::SOL_SOCKET as _, c::SO_PASSCRED).map(to_bool) - } - - #[inline] - pub(crate) fn set_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let time = duration_to_linux(timeout)?; - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, - }; - match setsockopt(fd, c::SOL_SOCKET, optname, time) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { - set_socket_timeout_old(fd, id, timeout) - } - otherwise => otherwise, - } - } - - /// Same as `set_socket_timeout` but uses `timeval` instead of - /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. - fn set_socket_timeout_old( - fd: BorrowedFd<'_>, - id: Timeout, - timeout: Option, - ) -> io::Result<()> { - let time = duration_to_linux_old(timeout)?; - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, - }; - setsockopt(fd, c::SOL_SOCKET, optname, time) - } - - #[inline] - pub(crate) fn get_socket_timeout( - fd: BorrowedFd<'_>, - id: Timeout, - ) -> io::Result> { - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_NEW, - Timeout::Send => SO_SNDTIMEO_NEW, - }; - let time: __kernel_timespec = match getsockopt(fd, c::SOL_SOCKET, optname) { - Err(io::Errno::NOPROTOOPT) if SO_RCVTIMEO_NEW != SO_RCVTIMEO_OLD => { - return get_socket_timeout_old(fd, id) - } - otherwise => otherwise?, - }; - Ok(duration_from_linux(time)) - } - - /// Same as `get_socket_timeout` but uses `timeval` instead of - /// `__kernel_timespec` and `_OLD` constants instead of `_NEW`. - fn get_socket_timeout_old(fd: BorrowedFd<'_>, id: Timeout) -> io::Result> { - let optname = match id { - Timeout::Recv => SO_RCVTIMEO_OLD, - Timeout::Send => SO_SNDTIMEO_OLD, - }; - let time: timeval = getsockopt(fd, c::SOL_SOCKET, optname)?; - Ok(duration_from_linux_old(time)) - } - - /// Convert a C `timespec` to a Rust `Option`. - #[inline] - fn duration_from_linux(time: __kernel_timespec) -> Option { - if time.tv_sec == 0 && time.tv_nsec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) + Duration::from_nanos(time.tv_nsec as u64), - ) - } - } - - /// Like `duration_from_linux` but uses Linux's old 32-bit `timeval`. - fn duration_from_linux_old(time: timeval) -> Option { - if time.tv_sec == 0 && time.tv_usec == 0 { - None - } else { - Some( - Duration::from_secs(time.tv_sec as u64) - + Duration::from_micros(time.tv_usec as u64), - ) - } - } - - /// Convert a Rust `Option` to a C `timespec`. - #[inline] - fn duration_to_linux(timeout: Option) -> io::Result<__kernel_timespec> { - Ok(match timeout { - Some(timeout) => { - if timeout == DURATION_ZERO { - return Err(io::Errno::INVAL); - } - let mut timeout = __kernel_timespec { - tv_sec: timeout.as_secs().try_into().unwrap_or(i64::MAX), - tv_nsec: timeout.subsec_nanos().into(), - }; - if timeout.tv_sec == 0 && timeout.tv_nsec == 0 { - timeout.tv_nsec = 1; - } - timeout - } - None => __kernel_timespec { - tv_sec: 0, - tv_nsec: 0, - }, - }) - } - - /// Like `duration_to_linux` but uses Linux's old 32-bit `timeval`. - fn duration_to_linux_old(timeout: Option) -> io::Result { - Ok(match timeout { - Some(timeout) => { - if timeout == DURATION_ZERO { - return Err(io::Errno::INVAL); - } - - // `subsec_micros` rounds down, so we use `subsec_nanos` and - // manually round up. - let mut timeout = timeval { - tv_sec: timeout.as_secs().try_into().unwrap_or(c::c_long::MAX), - tv_usec: ((timeout.subsec_nanos() + 999) / 1000) as _, - }; - if timeout.tv_sec == 0 && timeout.tv_usec == 0 { - timeout.tv_usec = 1; - } - timeout - } - None => timeval { - tv_sec: 0, - tv_usec: 0, - }, - }) - } - - #[inline] - pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl) - } - - #[inline] - pub(crate) fn get_ip_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_v6only(fd: BorrowedFd<'_>, only_v6: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY, from_bool(only_v6)) - } - - #[inline] - pub(crate) fn get_ipv6_v6only(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_V6ONLY).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IP as _, - c::IP_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ip_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_multicast_ttl(fd: BorrowedFd<'_>, multicast_ttl: u32) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL, multicast_ttl) - } - - #[inline] - pub(crate) fn get_ip_multicast_ttl(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IP as _, c::IP_MULTICAST_TTL) - } - - #[inline] - pub(crate) fn set_ipv6_multicast_loop( - fd: BorrowedFd<'_>, - multicast_loop: bool, - ) -> io::Result<()> { - setsockopt( - fd, - c::IPPROTO_IPV6 as _, - c::IPV6_MULTICAST_LOOP, - from_bool(multicast_loop), - ) - } - - #[inline] - pub(crate) fn get_ipv6_multicast_loop(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_MULTICAST_LOOP).map(to_bool) - } - - #[inline] - pub(crate) fn set_ip_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_add_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_ADD_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ip_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv4Addr, - interface: &Ipv4Addr, - ) -> io::Result<()> { - let mreq = to_imr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IP as _, c::IP_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_ipv6_drop_membership( - fd: BorrowedFd<'_>, - multiaddr: &Ipv6Addr, - interface: u32, - ) -> io::Result<()> { - let mreq = to_ipv6mr(multiaddr, interface); - setsockopt(fd, c::IPPROTO_IPV6 as _, c::IPV6_DROP_MEMBERSHIP, mreq) - } - - #[inline] - pub(crate) fn set_tcp_nodelay(fd: BorrowedFd<'_>, nodelay: bool) -> io::Result<()> { - setsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY, from_bool(nodelay)) - } - - #[inline] - pub(crate) fn get_tcp_nodelay(fd: BorrowedFd<'_>) -> io::Result { - getsockopt(fd, c::IPPROTO_TCP as _, c::TCP_NODELAY).map(to_bool) - } - - #[inline] - fn to_imr(multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> c::ip_mreq { - c::ip_mreq { - imr_multiaddr: to_imr_addr(multiaddr), - imr_interface: to_imr_addr(interface), - } - } - - #[inline] - fn to_imr_addr(addr: &Ipv4Addr) -> c::in_addr { - c::in_addr { - s_addr: u32::from_ne_bytes(addr.octets()), - } - } - - #[inline] - fn to_ipv6mr(multiaddr: &Ipv6Addr, interface: u32) -> c::ipv6_mreq { - c::ipv6_mreq { - ipv6mr_multiaddr: to_ipv6mr_multiaddr(multiaddr), - ipv6mr_ifindex: to_ipv6mr_interface(interface), - } - } - - #[inline] - fn to_ipv6mr_multiaddr(multiaddr: &Ipv6Addr) -> c::in6_addr { - c::in6_addr { - in6_u: linux_raw_sys::general::in6_addr__bindgen_ty_1 { - u6_addr8: multiaddr.octets(), - }, - } - } - - #[inline] - fn to_ipv6mr_interface(interface: u32) -> c::c_int { - interface as c::c_int - } - - #[inline] - fn from_bool(value: bool) -> c::c_uint { - c::c_uint::from(value) - } - - #[inline] - fn to_bool(value: c::c_uint) -> bool { - value != 0 - } -} diff --git a/vendor/rustix/src/imp/linux_raw/net/types.rs b/vendor/rustix/src/imp/linux_raw/net/types.rs deleted file mode 100644 index b8f786b3f..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/types.rs +++ /dev/null @@ -1,282 +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] -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` - #[allow(non_upper_case_globals)] - 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_*` -#[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_WR`—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 [`accept_with`] and [`acceptfrom_with`]. - /// - /// [`accept_with`]: crate::net::accept_with - /// [`acceptfrom_with`]: crate::net::acceptfrom_with - pub struct AcceptFlags: c::c_uint { - /// `SOCK_NONBLOCK` - const NONBLOCK = c::O_NONBLOCK; - /// `SOCK_CLOEXEC` - const CLOEXEC = c::O_CLOEXEC; - } -} - -bitflags! { - /// `SOCK_*` constants for use with [`socket`]. - /// - /// [`socket`]: crate::net::socket - 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/imp/linux_raw/net/write_sockaddr.rs b/vendor/rustix/src/imp/linux_raw/net/write_sockaddr.rs deleted file mode 100644 index 17abd96a0..000000000 --- a/vendor/rustix/src/imp/linux_raw/net/write_sockaddr.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! The BSD sockets API requires us to read the `ss_family` field before -//! we can interpret the rest of a `sockaddr` produced by the kernel. -#![allow(unsafe_code)] - -use super::super::c; -use crate::net::{SocketAddrAny, SocketAddrStorage, SocketAddrUnix, SocketAddrV4, SocketAddrV6}; -use core::mem::size_of; - -pub(crate) unsafe fn write_sockaddr( - addr: &SocketAddrAny, - storage: *mut SocketAddrStorage, -) -> usize { - match addr { - SocketAddrAny::V4(v4) => write_sockaddr_v4(v4, storage), - SocketAddrAny::V6(v6) => write_sockaddr_v6(v6, storage), - SocketAddrAny::Unix(unix) => write_sockaddr_unix(unix, storage), - } -} - -pub(crate) unsafe fn encode_sockaddr_v4(v4: &SocketAddrV4) -> c::sockaddr_in { - c::sockaddr_in { - sin_family: c::AF_INET as _, - sin_port: u16::to_be(v4.port()), - sin_addr: c::in_addr { - s_addr: u32::from_ne_bytes(v4.ip().octets()), - }, - __pad: [0_u8; 8], - } -} - -unsafe fn write_sockaddr_v4(v4: &SocketAddrV4, storage: *mut SocketAddrStorage) -> usize { - let encoded = encode_sockaddr_v4(v4); - core::ptr::write(storage.cast(), encoded); - size_of::() -} - -pub(crate) unsafe fn encode_sockaddr_v6(v6: &SocketAddrV6) -> c::sockaddr_in6 { - c::sockaddr_in6 { - sin6_family: c::AF_INET6 as _, - 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 { - u6_addr8: v6.ip().octets(), - }, - }, - sin6_scope_id: v6.scope_id(), - } -} - -unsafe fn write_sockaddr_v6(v6: &SocketAddrV6, storage: *mut SocketAddrStorage) -> usize { - let encoded = encode_sockaddr_v6(v6); - core::ptr::write(storage.cast(), encoded); - size_of::() -} - -unsafe fn write_sockaddr_unix(unix: &SocketAddrUnix, storage: *mut SocketAddrStorage) -> usize { - core::ptr::write(storage.cast(), unix.unix); - unix.len() -} diff --git a/vendor/rustix/src/imp/linux_raw/param/auxv.rs b/vendor/rustix/src/imp/linux_raw/param/auxv.rs deleted file mode 100644 index beed8613c..000000000 --- a/vendor/rustix/src/imp/linux_raw/param/auxv.rs +++ /dev/null @@ -1,203 +0,0 @@ -//! Linux auxv support. -//! -//! # Safety -//! -//! This uses raw pointers to locate and read the kernel-provided auxv array. -#![allow(unsafe_code)] - -use super::super::c; -use super::super::elf::{Elf_Ehdr, Elf_Phdr}; -#[cfg(feature = "param")] -use crate::ffi::CStr; -use core::mem::size_of; -use core::ptr::null; -#[cfg(feature = "runtime")] -use core::slice; -use linux_raw_sys::general::{ - AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_PHDR, AT_PHENT, AT_PHNUM, - AT_SYSINFO_EHDR, -}; - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn page_size() -> usize { - auxv().page_size -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn clock_ticks_per_second() -> u64 { - auxv().clock_ticks_per_second as u64 -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_hwcap() -> (usize, usize) { - let auxv = auxv(); - (auxv.hwcap, auxv.hwcap2) -} - -#[cfg(feature = "param")] -#[inline] -pub(crate) fn linux_execfn() -> &'static CStr { - let execfn = auxv().execfn; - - // Safety: We assume the `AT_EXECFN` value provided by the kernel is a - // valid pointer to a valid NUL-terminated array of bytes. - unsafe { CStr::from_ptr(execfn.cast()) } -} - -#[cfg(feature = "runtime")] -#[inline] -pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) { - let auxv = auxv(); - (auxv.phdr.cast(), auxv.phnum) -} - -#[cfg(feature = "runtime")] -#[inline] -pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] { - let auxv = auxv(); - - // Safety: We assume the `AT_PHDR` and `AT_PHNUM` values provided by the - // kernel form a valid slice. - unsafe { slice::from_raw_parts(auxv.phdr, auxv.phnum) } -} - -#[inline] -pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { - auxv().sysinfo_ehdr -} - -#[inline] -fn auxv() -> &'static Auxv { - // Safety: `AUXV` is initialized from the `.init_array`, and we never - // mutate it thereafter, so it's effectively initialized read-only in all - // other code. - unsafe { - // Assert that the initialization has happened. On glibc and musl, this - // is handled automatically by `.init_array` functions. Otherwise, - // `rustix::process::init` must be called explicitly. - debug_assert_ne!(AUXV.page_size, 0); - - &AUXV - } -} - -/// A struct for holding fields obtained from the kernel-provided auxv array. -struct Auxv { - page_size: usize, - clock_ticks_per_second: usize, - hwcap: usize, - hwcap2: usize, - sysinfo_ehdr: *const Elf_Ehdr, - phdr: *const Elf_Phdr, - phnum: usize, - execfn: *const c::c_char, -} - -/// Data obtained from the kernel-provided auxv array. This is initialized at -/// program startup below. -static mut AUXV: Auxv = Auxv { - page_size: 0, - clock_ticks_per_second: 0, - hwcap: 0, - hwcap2: 0, - sysinfo_ehdr: null(), - phdr: null(), - phnum: 0, - execfn: null(), -}; - -/// GLIBC passes argc, argv, and envp to functions in .init_array, as a -/// non-standard extension. Use priority 99 so that we run before any -/// normal user-defined constructor functions. -#[cfg(all(target_env = "gnu", not(target_vendor = "mustang")))] -#[used] -#[link_section = ".init_array.00099"] -static INIT_ARRAY: unsafe extern "C" fn(c::c_int, *mut *mut u8, *mut *mut u8) = { - unsafe extern "C" fn function(_argc: c::c_int, _argv: *mut *mut u8, envp: *mut *mut u8) { - init_from_envp(envp); - } - function -}; - -/// For musl, assume that `__environ` is available and points to the original -/// environment from the kernel, so we can find the auxv array in memory after -/// it. Use priority 99 so that we run before any normal user-defined -/// constructor functions. -/// -/// -#[cfg(all(target_env = "musl", not(target_vendor = "mustang")))] -#[used] -#[link_section = ".init_array.00099"] -static INIT_ARRAY: unsafe extern "C" fn() = { - unsafe extern "C" fn function() { - extern "C" { - static __environ: *mut *mut u8; - } - - init_from_envp(__environ) - } - function -}; - -/// On mustang or any non-musl non-glibic platform where we don't know that we -/// have `.init_array`, we export a function to be called during -/// initialization, and passed a pointer to the original environment variable -/// block set up by the OS. -#[cfg(any( - target_vendor = "mustang", - not(any(target_env = "gnu", target_env = "musl")), -))] -#[inline] -pub(crate) unsafe fn init(envp: *mut *mut u8) { - init_from_envp(envp); -} - -/// # Safety -/// -/// This must be passed a pointer to the environment variable buffer -/// provided by the kernel, which is followed in memory by the auxv array. -unsafe fn init_from_envp(mut envp: *mut *mut u8) { - while !(*envp).is_null() { - envp = envp.add(1); - } - init_from_auxp(envp.add(1).cast()) -} - -/// # Safety -/// -/// This must be passed a pointer to the auxv array provided by the kernel. -unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { - loop { - let Elf_auxv_t { a_type, a_val } = *auxp; - match a_type as _ { - AT_PAGESZ => AUXV.page_size = a_val as usize, - AT_CLKTCK => AUXV.clock_ticks_per_second = a_val as usize, - AT_HWCAP => AUXV.hwcap = a_val as usize, - AT_HWCAP2 => AUXV.hwcap2 = a_val as usize, - AT_SYSINFO_EHDR => AUXV.sysinfo_ehdr = a_val.cast(), - AT_PHDR => AUXV.phdr = a_val.cast(), - AT_PHNUM => AUXV.phnum = a_val as usize, - AT_PHENT => assert_eq!(a_val as usize, size_of::()), - AT_EXECFN => AUXV.execfn = a_val.cast(), - AT_NULL => break, - _ => (), - } - auxp = auxp.add(1); - } -} - -// ELF ABI - -#[repr(C)] -#[derive(Copy, Clone)] -struct Elf_auxv_t { - a_type: usize, - - // Some of the values in the auxv array are pointers, so we make `a_val` a - // pointer, in order to preserve their provenance. For the values which are - // integers, we cast this to `usize`. - a_val: *const (), -} diff --git a/vendor/rustix/src/imp/linux_raw/param/mod.rs b/vendor/rustix/src/imp/linux_raw/param/mod.rs deleted file mode 100644 index 2cb2fe78a..000000000 --- a/vendor/rustix/src/imp/linux_raw/param/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod auxv; diff --git a/vendor/rustix/src/imp/linux_raw/process/cpu_set.rs b/vendor/rustix/src/imp/linux_raw/process/cpu_set.rs deleted file mode 100644 index 10c5f478e..000000000 --- a/vendor/rustix/src/imp/linux_raw/process/cpu_set.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![allow(non_snake_case)] - -use super::types::RawCpuSet; -use core::mem::size_of_val; - -#[inline] -pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { - let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); // 32, 64 etc - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - cpuset.bits[idx] |= 1 << offset -} - -#[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; - } -} - -#[inline] -pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { - let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); // 32, 64 etc - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - cpuset.bits[idx] &= !(1 << offset) -} - -#[inline] -pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { - let size_in_bits = 8 * size_of_val(&cpuset.bits[0]); - let (idx, offset) = (cpu / size_in_bits, cpu % size_in_bits); - (cpuset.bits[idx] & (1 << offset)) != 0 -} - -#[inline] -pub(crate) fn CPU_COUNT_S(size_in_bytes: usize, cpuset: &RawCpuSet) -> u32 { - let size_of_mask = size_of_val(&cpuset.bits[0]); - let idx = size_in_bytes / size_of_mask; - cpuset.bits[..idx] - .iter() - .fold(0, |acc, i| acc + i.count_ones()) -} - -#[inline] -pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { - CPU_COUNT_S(core::mem::size_of::(), cpuset) -} diff --git a/vendor/rustix/src/imp/linux_raw/process/mod.rs b/vendor/rustix/src/imp/linux_raw/process/mod.rs deleted file mode 100644 index 9b2c25f91..000000000 --- a/vendor/rustix/src/imp/linux_raw/process/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub(crate) mod cpu_set; -pub(crate) mod syscalls; -pub(crate) mod types; -pub(crate) mod wait; diff --git a/vendor/rustix/src/imp/linux_raw/process/syscalls.rs b/vendor/rustix/src/imp/linux_raw/process/syscalls.rs deleted file mode 100644 index 3c833ede7..000000000 --- a/vendor/rustix/src/imp/linux_raw/process/syscalls.rs +++ /dev/null @@ -1,517 +0,0 @@ -//! linux_raw syscalls supporting `rustix::process`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![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_just_addr, slice_mut, zero, -}; -use super::types::{RawCpuSet, RawUname}; -use crate::fd::BorrowedFd; -use crate::ffi::CStr; -use crate::io; -use crate::process::{ - Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, RawNonZeroPid, RawPid, Resource, Rlimit, - Signal, Uid, WaitOptions, WaitStatus, -}; -use core::convert::TryInto; -use core::mem::MaybeUninit; -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, -}; - -#[inline] -pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_chdir, filename)) } -} - -#[inline] -pub(crate) fn fchdir(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fchdir, fd)) } -} - -#[inline] -pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { ret_usize(syscall!(__NR_getcwd, buf_addr_mut, buf_len)) } -} - -#[inline] -pub(crate) fn membarrier_query() -> MembarrierQuery { - unsafe { - match ret_c_uint(syscall!( - __NR_membarrier, - 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) - } - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[inline] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { ret(syscall!(__NR_membarrier, cmd, c_uint(0))) } -} - -#[inline] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_membarrier, - cmd, - c_uint(membarrier_cmd_flag::MEMBARRIER_CMD_FLAG_CPU as _), - cpu - )) - } -} - -#[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 { - unsafe { - let ppid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getppid)) as __kernel_pid_t; - Pid::from_raw(ppid 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) - } -} - -#[inline] -pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - // The raw linux syscall returns the size (in bytes) of the `cpumask_t` - // data type that is used internally by the kernel to represent the CPU - // set bit mask. - let size = ret_usize(syscall!( - __NR_sched_getaffinity, - c_uint(Pid::as_raw(pid)), - size_of::(), - by_mut(&mut cpuset.bits) - ))?; - let bytes = (cpuset as *mut RawCpuSet).cast::(); - 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::() - size); - Ok(()) - } -} - -#[inline] -pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_sched_setaffinity, - c_uint(Pid::as_raw(pid)), - size_of::(), - slice_just_addr(&cpuset.bits) - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - // See the documentation for [`crate::process::sched_yield`] for why - // errors are ignored. - syscall_readonly!(__NR_sched_yield).decode_void(); - } -} - -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::::uninit(); - unsafe { - ret(syscall!(__NR_uname, &mut uname)).unwrap(); - uname.assume_init() - } -} - -#[inline] -pub(crate) fn nice(inc: i32) -> io::Result { - 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); - setpriority_process(None, priority)?; - Ok(priority) -} - -#[inline] -pub(crate) fn getpriority_user(uid: Uid) -> io::Result { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_USER), - c_uint(uid.as_raw()) - ))?) - } -} - -#[inline] -pub(crate) fn getpriority_pgrp(pgid: Option) -> io::Result { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_PGRP), - c_uint(Pid::as_raw(pgid)) - ))?) - } -} - -#[inline] -pub(crate) fn getpriority_process(pid: Option) -> io::Result { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_PROCESS), - c_uint(Pid::as_raw(pid)) - ))?) - } -} - -#[inline] -pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_USER), - c_uint(uid.as_raw()), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_PGRP), - c_uint(Pid::as_raw(pgid)), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_PROCESS), - c_uint(Pid::as_raw(pid)), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn getrlimit(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::::uninit(); - unsafe { - match ret(syscall!( - __NR_prlimit64, - c_uint(0), - limit, - null::(), - &mut result - )) { - Ok(()) => rlimit_from_linux(result.assume_init()), - Err(e) => { - debug_assert_eq!(e, io::Errno::NOSYS); - getrlimit_old(limit) - } - } - } -} - -/// The old 32-bit-only `getrlimit` syscall, for when we lack the new -/// `prlimit64`. -unsafe fn getrlimit_old(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::::uninit(); - - // On these platforms, `__NR_getrlimit` is called `__NR_ugetrlimit`. - #[cfg(any( - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "x86", - ))] - { - ret_infallible(syscall!(__NR_ugetrlimit, limit, &mut result)); - } - - // On these platforms, it's just `__NR_getrlimit`. - #[cfg(not(any( - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "x86", - )))] - { - ret_infallible(syscall!(__NR_getrlimit, limit, &mut result)); - } - - rlimit_from_linux_old(result.assume_init()) -} - -#[inline] -pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { - unsafe { - let lim = rlimit_to_linux(new.clone())?; - match ret(syscall_readonly!( - __NR_prlimit64, - c_uint(0), - limit, - by_ref(&lim), - null_mut::() - )) { - Ok(()) => Ok(()), - Err(io::Errno::NOSYS) => setrlimit_old(limit, new), - Err(e) => Err(e), - } - } -} - -/// The old 32-bit-only `setrlimit` syscall, for when we lack the new -/// `prlimit64`. -unsafe fn setrlimit_old(limit: Resource, new: Rlimit) -> io::Result<()> { - let lim = rlimit_to_linux_old(new)?; - ret(syscall_readonly!(__NR_setrlimit, limit, by_ref(&lim))) -} - -#[inline] -pub(crate) fn prlimit(pid: Option, limit: Resource, new: Rlimit) -> io::Result { - let lim = rlimit_to_linux(new)?; - let mut result = MaybeUninit::::uninit(); - unsafe { - match ret(syscall!( - __NR_prlimit64, - c_uint(Pid::as_raw(pid)), - limit, - by_ref(&lim), - &mut result - )) { - Ok(()) => Ok(rlimit_from_linux(result.assume_init())), - Err(e) => Err(e), - } - } -} - -/// Convert a Rust [`Rlimit`] to a C `rlimit64`. -#[inline] -fn rlimit_from_linux(lim: rlimit64) -> Rlimit { - let current = if lim.rlim_cur == RLIM64_INFINITY as _ { - None - } else { - Some(lim.rlim_cur) - }; - let maximum = if lim.rlim_max == RLIM64_INFINITY as _ { - None - } else { - Some(lim.rlim_max) - }; - Rlimit { current, maximum } -} - -/// Convert a C `rlimit64` to a Rust `Rlimit`. -#[inline] -fn rlimit_to_linux(lim: Rlimit) -> io::Result { - let rlim_cur = match lim.current { - Some(r) => r, - None => RLIM64_INFINITY as _, - }; - let rlim_max = match lim.maximum { - Some(r) => r, - None => RLIM64_INFINITY as _, - }; - Ok(rlimit64 { rlim_cur, rlim_max }) -} - -/// Like `rlimit_from_linux` but uses Linux's old 32-bit `rlimit`. -#[allow(clippy::useless_conversion)] -fn rlimit_from_linux_old(lim: rlimit) -> Rlimit { - let current = if lim.rlim_cur == RLIM_INFINITY as _ { - None - } else { - Some(lim.rlim_cur.into()) - }; - let maximum = if lim.rlim_max == RLIM_INFINITY as _ { - None - } else { - Some(lim.rlim_max.into()) - }; - Rlimit { current, maximum } -} - -/// Like `rlimit_to_linux` but uses Linux's old 32-bit `rlimit`. -#[allow(clippy::useless_conversion)] -fn rlimit_to_linux_old(lim: Rlimit) -> io::Result { - let rlim_cur = match lim.current { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => RLIM_INFINITY as _, - }; - let rlim_max = match lim.maximum { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => RLIM_INFINITY as _, - }; - Ok(rlimit { rlim_cur, rlim_max }) -} - -#[inline] -pub(crate) fn wait(waitopts: WaitOptions) -> io::Result> { - _waitpid(!0, waitopts) -} - -#[inline] -pub(crate) fn waitpid( - pid: Option, - waitopts: WaitOptions, -) -> io::Result> { - _waitpid(Pid::as_raw(pid), waitopts) -} - -#[inline] -pub(crate) fn _waitpid( - pid: RawPid, - waitopts: WaitOptions, -) -> io::Result> { - unsafe { - let mut status = MaybeUninit::::uninit(); - let pid = ret_c_uint(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()), - ) - })) - } -} - -#[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 setsid() -> io::Result { - unsafe { - let pid = ret_usize(syscall_readonly!(__NR_setsid))?; - debug_assert!(pid > 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( - pid as u32, - ))) - } -} - -#[inline] -pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pid, sig)) } -} - -#[inline] -pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, negative_pid(pid), sig)) } -} - -#[inline] -pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pass_usize(0), sig)) } -} diff --git a/vendor/rustix/src/imp/linux_raw/process/types.rs b/vendor/rustix/src/imp/linux_raw/process/types.rs deleted file mode 100644 index 53e2c7db1..000000000 --- a/vendor/rustix/src/imp/linux_raw/process/types.rs +++ /dev/null @@ -1,246 +0,0 @@ -use super::super::c; -use linux_raw_sys::general::membarrier_cmd; - -/// A command for use with [`membarrier`] and [`membarrier_cpu`]. -/// -/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. -/// -/// [`membarrier`]: crate::process::membarrier -/// [`membarrier_cpu`]: crate::process::membarrier_cpu -/// [`membarrier_query`]: crate::process::membarrier_query -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[repr(u32)] -pub enum MembarrierCommand { - /// `MEMBARRIER_CMD_GLOBAL` - #[doc(alias = "Shared")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - Global = membarrier_cmd::MEMBARRIER_CMD_GLOBAL as _, - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - GlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_GLOBAL_EXPEDITED as _, - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - RegisterGlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - PrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - RegisterPrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - PrivateExpeditedSyncCore = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - RegisterPrivateExpeditedSyncCore = - membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - PrivateExpeditedRseq = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - RegisterPrivateExpeditedRseq = - membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as _, -} - -/// A resource value for use with [`getrlimit`], [`setrlimit`], and -/// [`prlimit`]. -/// -/// [`getrlimit`]: crate::process::getrlimit -/// [`setrlimit`]: crate::process::setrlimit -/// [`prlimit`]: crate::process::prlimit -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum Resource { - /// `RLIMIT_CPU` - Cpu = linux_raw_sys::general::RLIMIT_CPU, - /// `RLIMIT_FSIZE` - Fsize = linux_raw_sys::general::RLIMIT_FSIZE, - /// `RLIMIT_DATA` - Data = linux_raw_sys::general::RLIMIT_DATA, - /// `RLIMIT_STACK` - Stack = linux_raw_sys::general::RLIMIT_STACK, - /// `RLIMIT_CORE` - Core = linux_raw_sys::general::RLIMIT_CORE, - /// `RLIMIT_RSS` - Rss = linux_raw_sys::general::RLIMIT_RSS, - /// `RLIMIT_NPROC` - Nproc = linux_raw_sys::general::RLIMIT_NPROC, - /// `RLIMIT_NOFILE` - Nofile = linux_raw_sys::general::RLIMIT_NOFILE, - /// `RLIMIT_MEMLOCK` - Memlock = linux_raw_sys::general::RLIMIT_MEMLOCK, - /// `RLIMIT_AS` - As = linux_raw_sys::general::RLIMIT_AS, - /// `RLIMIT_LOCKS` - Locks = linux_raw_sys::general::RLIMIT_LOCKS, - /// `RLIMIT_SIGPENDING` - Sigpending = linux_raw_sys::general::RLIMIT_SIGPENDING, - /// `RLIMIT_MSGQUEUE` - Msgqueue = linux_raw_sys::general::RLIMIT_MSGQUEUE, - /// `RLIMIT_NICE` - Nice = linux_raw_sys::general::RLIMIT_NICE, - /// `RLIMIT_RTPRIO` - Rtprio = linux_raw_sys::general::RLIMIT_RTPRIO, - /// `RLIMIT_RTTIME` - Rttime = linux_raw_sys::general::RLIMIT_RTTIME, -} - -/// A signal number for use with [`kill_process`] and [`kill_process_group`]. -/// -/// [`kill_process`]: crate::process::kill_process -/// [`kill_process_group`]: crate::process::kill_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 { - 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 `SIGABRT`. -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 { - #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] - pub(crate) bits: [u32; 32], - #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] - pub(crate) bits: [u64; 16], -} - -#[inline] -pub(crate) fn raw_cpu_set_new() -> RawCpuSet { - #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] - { - RawCpuSet { bits: [0; 32] } - } - #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] - { - RawCpuSet { bits: [0; 16] } - } -} - -pub(crate) const CPU_SETSIZE: usize = 8 * core::mem::size_of::(); diff --git a/vendor/rustix/src/imp/linux_raw/process/wait.rs b/vendor/rustix/src/imp/linux_raw/process/wait.rs deleted file mode 100644 index 701b4ac0c..000000000 --- a/vendor/rustix/src/imp/linux_raw/process/wait.rs +++ /dev/null @@ -1,39 +0,0 @@ -// The functions replacing the C macros use the same names as in libc. -#![allow(non_snake_case)] - -pub(crate) use linux_raw_sys::general::{WCONTINUED, WNOHANG, WUNTRACED}; - -#[inline] -pub(crate) fn WIFSTOPPED(status: u32) -> bool { - (status & 0xff) == 0x7f -} - -#[inline] -pub(crate) fn WSTOPSIG(status: u32) -> u32 { - (status >> 8) & 0xff -} - -#[inline] -pub(crate) fn WIFCONTINUED(status: u32) -> bool { - status == 0xffff -} - -#[inline] -pub(crate) fn WIFSIGNALED(status: u32) -> bool { - ((status & 0x7f) + 1) as i8 >= 2 -} - -#[inline] -pub(crate) fn WTERMSIG(status: u32) -> u32 { - status & 0x7f -} - -#[inline] -pub(crate) fn WIFEXITED(status: u32) -> bool { - (status & 0x7f) == 0 -} - -#[inline] -pub(crate) fn WEXITSTATUS(status: u32) -> u32 { - (status >> 8) & 0xff -} diff --git a/vendor/rustix/src/imp/linux_raw/rand/mod.rs b/vendor/rustix/src/imp/linux_raw/rand/mod.rs deleted file mode 100644 index 1e0181a99..000000000 --- a/vendor/rustix/src/imp/linux_raw/rand/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/linux_raw/rand/syscalls.rs b/vendor/rustix/src/imp/linux_raw/rand/syscalls.rs deleted file mode 100644 index 2b5ca28e5..000000000 --- a/vendor/rustix/src/imp/linux_raw/rand/syscalls.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! linux_raw syscalls supporting `rustix::rand`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::super::conv::{ret_usize, slice_mut}; -use crate::io; -use crate::rand::GetRandomFlags; - -#[inline] -pub(crate) fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { ret_usize(syscall!(__NR_getrandom, buf_addr_mut, buf_len, flags)) } -} diff --git a/vendor/rustix/src/imp/linux_raw/rand/types.rs b/vendor/rustix/src/imp/linux_raw/rand/types.rs deleted file mode 100644 index 75f17443e..000000000 --- a/vendor/rustix/src/imp/linux_raw/rand/types.rs +++ /dev/null @@ -1,15 +0,0 @@ -use bitflags::bitflags; - -bitflags! { - /// `GRND_*` flags for use with [`getrandom`]. - /// - /// [`getrandom`]: crate::rand::getrandom - pub struct GetRandomFlags: u32 { - /// `GRND_RANDOM` - const RANDOM = linux_raw_sys::general::GRND_RANDOM; - /// `GRND_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::GRND_NONBLOCK; - /// `GRND_INSECURE` - const INSECURE = linux_raw_sys::general::GRND_INSECURE; - } -} diff --git a/vendor/rustix/src/imp/linux_raw/reg.rs b/vendor/rustix/src/imp/linux_raw/reg.rs deleted file mode 100644 index afe99c5f4..000000000 --- a/vendor/rustix/src/imp/linux_raw/reg.rs +++ /dev/null @@ -1,258 +0,0 @@ -//! Encapsulation for system call arguments and return values. -//! -//! The inline-asm and outline-asm code paths do some amount of reordering -//! of arguments; to ensure that we don't accidentally misroute an argument -//! or return value, we use distinct types for each argument index and -//! return value. -//! -//! # Safety -//! -//! The `ToAsm` and `FromAsm` traits are unsafe to use; they should only be -//! used by the syscall code which executes actual syscall machine -//! instructions. - -#![allow(unsafe_code)] - -use super::c; -use super::fd::RawFd; -use core::marker::PhantomData; - -pub(super) trait ToAsm: private::Sealed { - /// Convert `self` to a `usize` ready to be passed to a syscall - /// machine instruction. - /// - /// # Safety - /// - /// This should be used immediately before the syscall instruction, and - /// the returned value shouldn't be used for any other purpose. - #[must_use] - unsafe fn to_asm(self) -> *mut Opaque; -} - -pub(super) trait FromAsm: private::Sealed { - /// Convert `raw` from a value produced by a syscall machine instruction - /// into a `Self`. - /// - /// # Safety - /// - /// This should be used immediately after the syscall instruction, and - /// the operand value shouldn't be used for any other purpose. - #[must_use] - unsafe fn from_asm(raw: *mut Opaque) -> Self; -} - -/// To preserve provenance, syscall arguments and return values are passed as -/// pointer types. They need a type to point to, so we define a custom private -/// type, to prevent it from being used for anything else. -#[repr(transparent)] -pub(super) struct Opaque(c::c_void); - -// Argument numbers. -pub(super) struct A0(()); -pub(super) struct A1(()); -pub(super) struct A2(()); -pub(super) struct A3(()); -pub(super) struct A4(()); -pub(super) struct A5(()); -#[cfg(target_arch = "mips")] -pub(super) struct A6(()); -#[cfg(target_arch = "x86")] -pub(super) struct SocketArg; - -pub(super) trait ArgNumber: private::Sealed {} -impl ArgNumber for A0 {} -impl ArgNumber for A1 {} -impl ArgNumber for A2 {} -impl ArgNumber for A3 {} -impl ArgNumber for A4 {} -impl ArgNumber for A5 {} -#[cfg(target_arch = "mips")] -impl ArgNumber for A6 {} -#[cfg(target_arch = "x86")] -impl ArgNumber for SocketArg {} - -// Return value numbers. -pub(super) struct R0(()); - -pub(super) trait RetNumber: private::Sealed {} -impl RetNumber for R0 {} - -/// Syscall arguments use register-sized types. We use a newtype to -/// discourage accidental misuse of the raw integer values. -/// -/// This type doesn't implement `Clone` or `Copy`; it should be used exactly -/// once. And it has a lifetime to ensure that it doesn't outlive any resources -/// it might be pointing to. -#[repr(transparent)] -#[must_use] -pub(super) struct ArgReg<'a, Num: ArgNumber> { - raw: *mut Opaque, - _phantom: PhantomData<(&'a (), Num)>, -} - -impl<'a, Num: ArgNumber> ToAsm for ArgReg<'a, Num> { - #[inline] - unsafe fn to_asm(self) -> *mut Opaque { - self.raw - } -} - -/// Syscall return values use register-sized types. We use a newtype to -/// discourage accidental misuse of the raw integer values. -/// -/// This type doesn't implement `Clone` or `Copy`; it should be used exactly -/// once. -#[repr(transparent)] -#[must_use] -pub(super) struct RetReg { - raw: *mut Opaque, - _phantom: PhantomData, -} - -impl RetReg { - #[inline] - pub(super) fn decode_usize(self) -> usize { - debug_assert!(!(-4095..0).contains(&(self.raw as isize))); - self.raw as usize - } - - #[inline] - pub(super) fn decode_raw_fd(self) -> RawFd { - let bits = self.decode_usize(); - let raw_fd = bits as RawFd; - - // Converting `raw` to `RawFd` should be lossless. - debug_assert_eq!(raw_fd as usize, bits); - - raw_fd - } - - #[inline] - pub(super) fn decode_c_int(self) -> c::c_int { - let bits = self.decode_usize(); - let c_int_ = bits as c::c_int; - - // Converting `raw` to `c_int` should be lossless. - debug_assert_eq!(c_int_ as usize, bits); - - c_int_ - } - - #[inline] - pub(super) fn decode_c_uint(self) -> c::c_uint { - let bits = self.decode_usize(); - let c_uint_ = bits as c::c_uint; - - // Converting `raw` to `c_uint` should be lossless. - debug_assert_eq!(c_uint_ as usize, bits); - - c_uint_ - } - - #[inline] - pub(super) fn decode_void_star(self) -> *mut c::c_void { - self.raw.cast() - } - - #[cfg(target_pointer_width = "64")] - #[inline] - pub(super) fn decode_u64(self) -> u64 { - self.decode_usize() as u64 - } - - #[inline] - pub(super) fn decode_void(self) { - let ignore = self.decode_usize(); - debug_assert_eq!(ignore, 0); - } - - #[inline] - pub(super) fn decode_error_code(self) -> u16 { - let bits = self.raw as usize; - - // `raw` must be in `-4095..0`. Linux always returns errors in - // `-4095..0`, and we double-check it here. - debug_assert!((-4095..0).contains(&(bits as isize))); - - bits as u16 - } - - #[inline] - pub(super) fn is_nonzero(&self) -> bool { - !self.raw.is_null() - } - - #[inline] - pub(super) fn is_negative(&self) -> bool { - (self.raw as isize) < 0 - } - - #[inline] - pub(super) fn is_in_range(&self, range: core::ops::Range) -> bool { - range.contains(&(self.raw as isize)) - } -} - -impl FromAsm for RetReg { - #[inline] - unsafe fn from_asm(raw: *mut Opaque) -> Self { - Self { - raw, - _phantom: PhantomData, - } - } -} - -#[repr(transparent)] -pub(super) struct SyscallNumber<'a> { - nr: usize, - _phantom: PhantomData<&'a ()>, -} - -impl<'a> ToAsm for SyscallNumber<'a> { - #[inline] - unsafe fn to_asm(self) -> *mut Opaque { - self.nr as usize as *mut Opaque - } -} - -/// Encode a system call argument as an `ArgReg`. -#[inline] -pub(super) fn raw_arg<'a, Num: ArgNumber>(raw: *mut Opaque) -> ArgReg<'a, Num> { - ArgReg { - raw, - _phantom: PhantomData, - } -} - -/// Encode a system call number (a `__NR_*` constant) as a `SyscallNumber`. -#[inline] -pub(super) const fn nr<'a>(nr: u32) -> SyscallNumber<'a> { - SyscallNumber { - nr: nr as usize, - _phantom: PhantomData, - } -} - -/// Seal our various traits using the technique documented [here]. -/// -/// [here]: https://rust-lang.github.io/api-guidelines/future-proofing.html -mod private { - pub trait Sealed {} - - // Implement for those same types, but no others. - impl<'a, Num: super::ArgNumber> Sealed for super::ArgReg<'a, Num> {} - impl Sealed for super::RetReg {} - impl<'a> Sealed for super::SyscallNumber<'a> {} - impl Sealed for super::A0 {} - impl Sealed for super::A1 {} - impl Sealed for super::A2 {} - impl Sealed for super::A3 {} - impl Sealed for super::A4 {} - impl Sealed for super::A5 {} - #[cfg(target_arch = "mips")] - impl Sealed for super::A6 {} - #[cfg(target_arch = "x86")] - impl Sealed for super::SocketArg {} - impl Sealed for super::R0 {} -} diff --git a/vendor/rustix/src/imp/linux_raw/runtime/mod.rs b/vendor/rustix/src/imp/linux_raw/runtime/mod.rs deleted file mode 100644 index 0b48649ce..000000000 --- a/vendor/rustix/src/imp/linux_raw/runtime/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod tls; diff --git a/vendor/rustix/src/imp/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/imp/linux_raw/runtime/syscalls.rs deleted file mode 100644 index 49a29b2a2..000000000 --- a/vendor/rustix/src/imp/linux_raw/runtime/syscalls.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! linux_raw syscalls supporting `rustix::runtime`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::super::c; -#[cfg(target_arch = "x86")] -use super::super::conv::by_mut; -use super::super::conv::{c_int, c_uint, ret, ret_c_uint, ret_error, ret_usize_infallible, zero}; -use crate::fd::BorrowedFd; -use crate::ffi::CStr; -use crate::fs::AtFlags; -use crate::io; -use crate::process::{Pid, RawNonZeroPid}; -use linux_raw_sys::general::{__kernel_pid_t, PR_SET_NAME, SIGCHLD}; -#[cfg(target_arch = "x86_64")] -use {super::super::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; - -#[inline] -pub(crate) unsafe fn fork() -> io::Result> { - let pid = ret_c_uint(syscall_readonly!( - __NR_clone, - c_uint(SIGCHLD), - zero(), - zero(), - zero(), - zero() - ))?; - Ok(Pid::from_raw(pid)) -} - -pub(crate) unsafe fn execveat( - dirfd: BorrowedFd<'_>, - path: &CStr, - args: *const *const u8, - env_vars: *const *const u8, - flags: AtFlags, -) -> io::Errno { - ret_error(syscall_readonly!( - __NR_execveat, - dirfd, - path, - args, - env_vars, - flags - )) -} - -pub(crate) unsafe fn execve( - path: &CStr, - args: *const *const u8, - env_vars: *const *const u8, -) -> io::Errno { - ret_error(syscall_readonly!(__NR_execve, path, args, env_vars)) -} - -pub(crate) mod tls { - #[cfg(target_arch = "x86")] - use super::super::tls::UserDesc; - use super::*; - - #[cfg(target_arch = "x86")] - #[inline] - pub(crate) unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { - ret(syscall!(__NR_set_thread_area, by_mut(u_info))) - } - - #[cfg(target_arch = "arm")] - #[inline] - pub(crate) unsafe fn arm_set_tls(data: *mut c::c_void) -> io::Result<()> { - ret(syscall_readonly!(__ARM_NR_set_tls, data)) - } - - #[cfg(target_arch = "x86_64")] - #[inline] - pub(crate) unsafe fn set_fs(data: *mut c::c_void) { - ret_infallible(syscall_readonly!( - __NR_arch_prctl, - c_uint(ARCH_SET_FS), - data - )) - } - - #[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)) - } - - #[inline] - pub(crate) unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { - ret(syscall_readonly!(__NR_prctl, c_uint(PR_SET_NAME), name)) - } - - #[inline] - pub(crate) fn exit_thread(code: c::c_int) -> ! { - unsafe { syscall_noreturn!(__NR_exit, c_int(code)) } - } -} diff --git a/vendor/rustix/src/imp/linux_raw/runtime/tls.rs b/vendor/rustix/src/imp/linux_raw/runtime/tls.rs deleted file mode 100644 index 63eed9bbd..000000000 --- a/vendor/rustix/src/imp/linux_raw/runtime/tls.rs +++ /dev/null @@ -1,62 +0,0 @@ -#![allow(unsafe_code)] - -use super::super::c; -use super::super::elf::*; -use super::super::param::auxv::exe_phdrs_slice; -use core::ptr::null; - -/// For use with [`set_thread_area`]. -/// -/// [`set_thread_area`]: crate::runtime::set_thread_area -#[cfg(target_arch = "x86")] -pub type UserDesc = linux_raw_sys::general::user_desc; - -pub(crate) fn startup_tls_info() -> StartupTlsInfo { - let mut base = null(); - let mut tls_phdr = null(); - let mut stack_size = 0; - - let phdrs = exe_phdrs_slice(); - - // Safety: We assume the phdr array pointer and length the kernel provided - // to the process describe a valid phdr array. - unsafe { - for phdr in phdrs { - match (*phdr).p_type { - PT_PHDR => { - base = phdrs - .as_ptr() - .cast::() - .offset(-((*phdr).p_vaddr as isize)) - } - PT_TLS => tls_phdr = phdr, - PT_GNU_STACK => stack_size = (*phdr).p_memsz, - _ => {} - } - } - - StartupTlsInfo { - addr: base.cast::().add((*tls_phdr).p_vaddr).cast(), - mem_size: (*tls_phdr).p_memsz, - file_size: (*tls_phdr).p_filesz, - align: (*tls_phdr).p_align, - stack_size, - } - } -} - -/// The values returned from [`startup_tls_info`]. -/// -/// [`startup_tls_info`]: crate::runtime::startup_tls_info -pub struct StartupTlsInfo { - /// The base address of the TLS segment. - pub addr: *const c::c_void, - /// The size of the memory region. - pub mem_size: usize, - /// The size beyond which all memory is zero-initialized. - pub file_size: usize, - /// The required alignment for the TLS segment. - pub align: usize, - /// The requested minimum size for stacks. - pub stack_size: usize, -} diff --git a/vendor/rustix/src/imp/linux_raw/termios/mod.rs b/vendor/rustix/src/imp/linux_raw/termios/mod.rs deleted file mode 100644 index 1e0181a99..000000000 --- a/vendor/rustix/src/imp/linux_raw/termios/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/linux_raw/termios/syscalls.rs b/vendor/rustix/src/imp/linux_raw/termios/syscalls.rs deleted file mode 100644 index b62a033e0..000000000 --- a/vendor/rustix/src/imp/linux_raw/termios/syscalls.rs +++ /dev/null @@ -1,249 +0,0 @@ -//! linux_raw syscalls supporting `rustix::termios`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::super::conv::{by_ref, c_uint, ret}; -use crate::fd::BorrowedFd; -use crate::io; -use crate::process::{Pid, RawNonZeroPid}; -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, -}; -#[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::ioctl::{ - TCFLSH, TCGETS, TCSBRK, TCSETS, TCXONC, TIOCGPGRP, TIOCGSID, TIOCGWINSZ, TIOCSPGRP, TIOCSWINSZ, -}; - -#[inline] -pub(crate) fn tcgetwinsize(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGWINSZ), &mut result)) - .map(|()| result.assume_init()) - } -} - -#[inline] -pub(crate) fn tcgetattr(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut result = MaybeUninit::::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(TCGETS), &mut result)).map(|()| result.assume_init()) - } -} - -#[inline] -pub(crate) fn tcgetpgrp(fd: BorrowedFd<'_>) -> io::Result { - unsafe { - let mut result = MaybeUninit::<__kernel_pid_t>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGPGRP), &mut result)).map(|()| { - let pid = result.assume_init(); - debug_assert!(pid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid as u32)) - }) - } -} - -#[inline] -pub(crate) fn tcsetattr( - fd: BorrowedFd, - optional_actions: OptionalActions, - termios: &Termios, -) -> 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] -pub(crate) fn tcsendbreak(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TCSBRK), c_uint(0))) } -} - -#[inline] -pub(crate) fn tcdrain(fd: BorrowedFd) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_ioctl, fd, c_uint(TCSBRK), c_uint(1))) } -} - -#[inline] -pub(crate) fn tcflush(fd: BorrowedFd, queue_selector: QueueSelector) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(TCFLSH), - c_uint(queue_selector as u32) - )) - } -} - -#[inline] -pub(crate) fn tcflow(fd: BorrowedFd, action: Action) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_ioctl, - fd, - c_uint(TCXONC), - c_uint(action as u32) - )) - } -} - -#[inline] -pub(crate) fn tcgetsid(fd: BorrowedFd) -> io::Result { - unsafe { - let mut result = MaybeUninit::<__kernel_pid_t>::uninit(); - ret(syscall!(__NR_ioctl, fd, c_uint(TIOCGSID), &mut result)).map(|()| { - let pid = result.assume_init(); - debug_assert!(pid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid as u32)) - }) - } -} - -#[inline] -pub(crate) fn tcsetwinsize(fd: BorrowedFd, winsize: Winsize) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_ioctl, - fd, - c_uint(TIOCSWINSZ), - by_ref(&winsize) - )) - } -} - -#[inline] -pub(crate) fn tcsetpgrp(fd: BorrowedFd<'_>, pid: Pid) -> io::Result<()> { - unsafe { ret(syscall!(__NR_ioctl, fd, c_uint(TIOCSPGRP), pid)) } -} - -#[inline] -#[must_use] -#[allow(clippy::missing_const_for_fn)] -pub(crate) fn cfgetospeed(termios: &Termios) -> u32 { - termios.c_cflag & CBAUD -} - -#[inline] -#[must_use] -#[allow(clippy::missing_const_for_fn)] -pub(crate) fn cfgetispeed(termios: &Termios) -> u32 { - termios.c_cflag & CBAUD -} - -#[inline] -pub(crate) fn cfmakeraw(termios: &mut Termios) { - // From the Linux [`cfmakeraw` man page]: - // - // [`cfmakeraw` man 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; - - // Musl and glibc also do these: - termios.c_cc[VMIN] = 1; - termios.c_cc[VTIME] = 0; -} - -#[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; - Ok(()) -} - -#[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; - 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(()) -} - -#[inline] -pub(crate) fn isatty(fd: BorrowedFd<'_>) -> bool { - // On error, Linux will return either `EINVAL` (2.6.32) or `ENOTTY` - // (otherwise), because we assume we're never passing an invalid - // file descriptor (which would get `EBADF`). Either way, an error - // means we don't have a tty. - tcgetwinsize(fd).is_ok() -} - -#[cfg(feature = "procfs")] -pub(crate) fn ttyname(fd: BorrowedFd<'_>, buf: &mut [u8]) -> io::Result { - let fd_stat = super::super::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 { - return Err(crate::io::Errno::NOTTY); - } - - // Check that `fd` is really a tty. - tcgetwinsize(fd)?; - - // Get a fd to '/proc/self/fd'. - let proc_self_fd = io::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)?; - - // 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 - // adding a NUL terminator. - if r == buf.len() { - return Err(io::Errno::RANGE); - } - buf[r] = 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(); - - 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(crate::io::Errno::NODEV); - } - - Ok(r) -} diff --git a/vendor/rustix/src/imp/linux_raw/termios/types.rs b/vendor/rustix/src/imp/linux_raw/termios/types.rs deleted file mode 100644 index ce8832455..000000000 --- a/vendor/rustix/src/imp/linux_raw/termios/types.rs +++ /dev/null @@ -1,456 +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. - Now = linux_raw_sys::general::TCSANOW, - - /// `TCSADRAIN`—Make the change after all output has been transmitted. - Drain = linux_raw_sys::general::TCSADRAIN, - - /// `TCSAFLUSH`—Discard any pending input and then make the change - /// after all output has been transmitted. - 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. - IFlush = linux_raw_sys::general::TCIFLUSH, - - /// `TCOFLUSH`—Flush data written but not transmitted. - OFlush = linux_raw_sys::general::TCOFLUSH, - - /// `TCIOFLUSH`—`IFlush` and `OFlush` combined. - 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. - OOff = linux_raw_sys::general::TCOOFF, - - /// `TCOON`—Restart suspended output. - OOn = linux_raw_sys::general::TCOON, - - /// `TCIOFF`—Transmits a STOP byte. - IOff = linux_raw_sys::general::TCIOFF, - - /// `TCION`—Transmits a START byte. - IOn = linux_raw_sys::general::TCION, -} - -/// `struct termios` for use with [`tcgetattr`]. -/// -/// [`tcgetattr`]: crate::termios::tcgetattr -pub type Termios = linux_raw_sys::general::termios; - -/// `struct winsize` for use with [`tcgetwinsize`]. -/// -/// [`tcgetwinsize`]: crate::termios::tcgetwinsize -pub type Winsize = linux_raw_sys::general::winsize; - -/// `tcflag_t`—A type for the flags fields of [`Termios`]. -pub type Tcflag = linux_raw_sys::general::tcflag_t; - -/// `speed_t`—A return type for [`cfsetspeed`] and similar. -/// -/// [`cfsetspeed`]: crate::termios::cfsetspeed -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` -pub const B2500000: Speed = linux_raw_sys::general::B2500000; - -/// `B3000000` -pub const B3000000: Speed = linux_raw_sys::general::B3000000; - -/// `B3500000` -pub const B3500000: Speed = linux_raw_sys::general::B3500000; - -/// `B4000000` -pub const B4000000: Speed = linux_raw_sys::general::B4000000; - -/// `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/imp/linux_raw/thread/futex.rs b/vendor/rustix/src/imp/linux_raw/thread/futex.rs deleted file mode 100644 index 9e087f9f1..000000000 --- a/vendor/rustix/src/imp/linux_raw/thread/futex.rs +++ /dev/null @@ -1,39 +0,0 @@ -bitflags::bitflags! { - /// Flags for use with [`futex`]. - /// - /// [`futex`]: crate::thread::futex - pub struct FutexFlags: u32 { - /// `FUTEX_PRIVATE_FLAG` - const PRIVATE = linux_raw_sys::general::FUTEX_PRIVATE_FLAG; - /// `FUTEX_CLOCK_REALTIME` - const CLOCK_REALTIME = linux_raw_sys::general::FUTEX_CLOCK_REALTIME; - } -} - -/// Operations for use with [`futex`]. -/// -/// [`futex`]: crate::thread::futex -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum FutexOperation { - /// `FUTEX_WAIT` - Wait = linux_raw_sys::general::FUTEX_WAIT, - /// `FUTEX_WAKE` - Wake = linux_raw_sys::general::FUTEX_WAKE, - /// `FUTEX_FD` - Fd = linux_raw_sys::general::FUTEX_FD, - /// `FUTEX_REQUEUE` - Requeue = linux_raw_sys::general::FUTEX_REQUEUE, - /// `FUTEX_CMP_REQUEUE` - CmpRequeue = linux_raw_sys::general::FUTEX_CMP_REQUEUE, - /// `FUTEX_WAKE_OP` - WakeOp = linux_raw_sys::general::FUTEX_WAKE_OP, - /// `FUTEX_LOCK_PI` - LockPi = linux_raw_sys::general::FUTEX_LOCK_PI, - /// `FUTEX_UNLOCK_PI` - UnlockPi = linux_raw_sys::general::FUTEX_UNLOCK_PI, - /// `FUTEX_TRYLOCK_PI` - TrylockPi = linux_raw_sys::general::FUTEX_TRYLOCK_PI, - /// `FUTEX_WAIT_BITSET` - WaitBitset = linux_raw_sys::general::FUTEX_WAIT_BITSET, -} diff --git a/vendor/rustix/src/imp/linux_raw/thread/mod.rs b/vendor/rustix/src/imp/linux_raw/thread/mod.rs deleted file mode 100644 index 8bb80c33a..000000000 --- a/vendor/rustix/src/imp/linux_raw/thread/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod futex; -pub(crate) mod syscalls; - -pub use futex::{FutexFlags, FutexOperation}; diff --git a/vendor/rustix/src/imp/linux_raw/thread/syscalls.rs b/vendor/rustix/src/imp/linux_raw/thread/syscalls.rs deleted file mode 100644 index 600b4649d..000000000 --- a/vendor/rustix/src/imp/linux_raw/thread/syscalls.rs +++ /dev/null @@ -1,280 +0,0 @@ -//! linux_raw syscalls supporting `rustix::thread`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::super::conv::{by_ref, c_int, c_uint, ret, ret_usize, ret_usize_infallible, zero}; -use crate::io; -use crate::process::{Pid, RawNonZeroPid}; -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, -}; - -#[inline] -pub(crate) fn clock_nanosleep_relative( - id: ClockId, - req: &__kernel_timespec, -) -> NanosleepRelativeResult { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); - match ret(syscall!( - __NR_clock_nanosleep_time64, - id, - c_int(0), - by_ref(req), - &mut rem - )) - .or_else(|err| { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - if err == io::Errno::NOSYS { - clock_nanosleep_relative_old(id, req, &mut rem) - } else { - Err(err) - } - }) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); - match ret(syscall!( - __NR_clock_nanosleep, - id, - c_int(0), - by_ref(req), - &mut rem - )) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn clock_nanosleep_relative_old( - id: ClockId, - req: &__kernel_timespec, - rem: &mut MaybeUninit<__kernel_timespec>, -) -> io::Result<()> { - let old_req = __kernel_old_timespec { - tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - let mut old_rem = MaybeUninit::<__kernel_old_timespec>::uninit(); - ret(syscall!( - __NR_clock_nanosleep, - id, - c_int(0), - 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(), - }, - ); - Ok(()) -} - -#[inline] -pub(crate) fn clock_nanosleep_absolute(id: ClockId, req: &__kernel_timespec) -> io::Result<()> { - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall_readonly!( - __NR_clock_nanosleep_time64, - id, - c_uint(TIMER_ABSTIME), - by_ref(req), - zero() - )) - .or_else(|err| { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - if err == io::Errno::NOSYS { - clock_nanosleep_absolute_old(id, req) - } else { - Err(err) - } - }) - } - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall_readonly!( - __NR_clock_nanosleep, - id, - c_uint(TIMER_ABSTIME), - by_ref(req), - zero() - )) - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn clock_nanosleep_absolute_old(id: ClockId, req: &__kernel_timespec) -> io::Result<()> { - let old_req = __kernel_old_timespec { - tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - ret(syscall_readonly!( - __NR_clock_nanosleep, - id, - c_int(0), - by_ref(&old_req), - zero() - )) -} - -#[inline] -pub(crate) fn nanosleep(req: &__kernel_timespec) -> NanosleepRelativeResult { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); - match ret(syscall!( - __NR_clock_nanosleep_time64, - ClockId::Realtime, - c_int(0), - by_ref(req), - &mut rem - )) - .or_else(|err| { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - if err == io::Errno::NOSYS { - nanosleep_old(req, &mut rem) - } else { - Err(err) - } - }) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut rem = MaybeUninit::<__kernel_timespec>::uninit(); - match ret(syscall!(__NR_nanosleep, by_ref(req), &mut rem)) { - Ok(()) => NanosleepRelativeResult::Ok, - Err(io::Errno::INTR) => NanosleepRelativeResult::Interrupted(rem.assume_init()), - Err(err) => NanosleepRelativeResult::Err(err), - } - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn nanosleep_old( - req: &__kernel_timespec, - rem: &mut MaybeUninit<__kernel_timespec>, -) -> io::Result<()> { - let old_req = __kernel_old_timespec { - tv_sec: req.tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: req.tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - 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(), - }, - ); - 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)) - } -} - -// TODO: This could be de-multiplexed. -#[inline] -pub(crate) unsafe fn futex( - uaddr: *mut u32, - op: FutexOperation, - flags: FutexFlags, - val: u32, - utime: *const Timespec, - uaddr2: *mut u32, - val3: u32, -) -> io::Result { - #[cfg(target_pointer_width = "32")] - { - ret_usize(syscall!( - __NR_futex_time64, - uaddr, - (op, flags), - c_uint(val), - utime, - uaddr2, - c_uint(val3) - )) - .or_else(|err| { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - if err == io::Errno::NOSYS { - futex_old(uaddr, op, flags, val, utime, uaddr2, val3) - } else { - Err(err) - } - }) - } - #[cfg(target_pointer_width = "64")] - ret_usize(syscall!( - __NR_futex, - uaddr, - (op, flags), - c_uint(val), - utime, - uaddr2, - c_uint(val3) - )) -} - -#[cfg(target_pointer_width = "32")] -unsafe fn futex_old( - uaddr: *mut u32, - op: FutexOperation, - flags: FutexFlags, - val: u32, - utime: *const Timespec, - uaddr2: *mut u32, - val3: u32, -) -> io::Result { - let old_utime = __kernel_old_timespec { - tv_sec: (*utime).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: (*utime).tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, - }; - ret_usize(syscall!( - __NR_futex, - uaddr, - (op, flags), - c_uint(val), - by_ref(&old_utime), - uaddr2, - c_uint(val3) - )) -} diff --git a/vendor/rustix/src/imp/linux_raw/time/mod.rs b/vendor/rustix/src/imp/linux_raw/time/mod.rs deleted file mode 100644 index c42592c4f..000000000 --- a/vendor/rustix/src/imp/linux_raw/time/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -#[cfg(any(feature = "time", target_arch = "x86"))] -pub(crate) mod syscalls; -pub(crate) mod types; diff --git a/vendor/rustix/src/imp/linux_raw/time/syscalls.rs b/vendor/rustix/src/imp/linux_raw/time/syscalls.rs deleted file mode 100644 index 93651e499..000000000 --- a/vendor/rustix/src/imp/linux_raw/time/syscalls.rs +++ /dev/null @@ -1,229 +0,0 @@ -//! linux_raw syscalls supporting `rustix::time`. -//! -//! # Safety -//! -//! See the `rustix::imp` module documentation for details. -#![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; -use crate::io; -#[cfg(feature = "time")] -use crate::io::OwnedFd; -#[cfg(feature = "time")] -use crate::time::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; -use core::mem::MaybeUninit; -use linux_raw_sys::general::__kernel_timespec; -#[cfg(feature = "time")] -#[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}; - -// `clock_gettime` has special optimizations via the vDSO. -#[cfg(feature = "time")] -pub(crate) use super::super::vdso_wrappers::{clock_gettime, clock_gettime_dynamic}; - -#[inline] -pub(crate) fn clock_getres(which_clock: ClockId) -> __kernel_timespec { - #[cfg(target_pointer_width = "32")] - unsafe { - let mut result = MaybeUninit::<__kernel_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. - debug_assert_eq!(err, io::Errno::NOSYS); - clock_getres_old(which_clock, &mut result); - } - result.assume_init() - } - #[cfg(target_pointer_width = "64")] - unsafe { - let mut result = MaybeUninit::<__kernel_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>) { - 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(), - }, - ); -} - -#[cfg(feature = "time")] -#[inline] -pub(crate) fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result { - unsafe { ret_owned_fd(syscall!(__NR_timerfd_create, clockid, flags)) } -} - -#[cfg(feature = "time")] -#[inline] -pub(crate) fn timerfd_settime( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, -) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall!( - __NR_timerfd_settime, - fd, - flags, - by_ref(new_value), - &mut result - )) - .map(|()| result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!( - __NR_timerfd_settime64, - fd, - flags, - by_ref(new_value), - &mut result - )) - .or_else(|err| { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - if err == io::Errno::NOSYS { - timerfd_settime_old(fd, flags, new_value, &mut result) - } else { - Err(err) - } - }) - .map(|()| result.assume_init()) - } -} - -#[cfg(feature = "time")] -#[cfg(target_pointer_width = "32")] -unsafe fn timerfd_settime_old( - fd: BorrowedFd<'_>, - flags: TimerfdTimerFlags, - new_value: &Itimerspec, - result: &mut MaybeUninit, -) -> io::Result<()> { - let mut old_result = MaybeUninit::<__kernel_old_itimerspec>::uninit(); - - // Convert `new_value` to the old `__kernel_old_itimerspec` format. - let old_new_value = __kernel_old_itimerspec { - it_interval: __kernel_old_timespec { - tv_sec: new_value - .it_interval - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_interval - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - it_value: __kernel_old_timespec { - tv_sec: new_value - .it_value - .tv_sec - .try_into() - .map_err(|_| io::Errno::OVERFLOW)?, - tv_nsec: new_value - .it_value - .tv_nsec - .try_into() - .map_err(|_| io::Errno::INVAL)?, - }, - }; - ret(syscall!( - __NR_timerfd_settime, - fd, - flags, - by_ref(&old_new_value), - &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(), - }, - }, - ); - Ok(()) -} - -#[cfg(feature = "time")] -#[inline] -pub(crate) fn timerfd_gettime(fd: BorrowedFd<'_>) -> io::Result { - let mut result = MaybeUninit::::uninit(); - - #[cfg(target_pointer_width = "64")] - unsafe { - ret(syscall!(__NR_timerfd_gettime, fd, &mut result)).map(|()| result.assume_init()) - } - - #[cfg(target_pointer_width = "32")] - unsafe { - ret(syscall!(__NR_timerfd_gettime64, fd, &mut result)) - .or_else(|err| { - // See the comments in `rustix_clock_gettime_via_syscall` about - // emulation. - if err == io::Errno::NOSYS { - timerfd_gettime_old(fd, &mut result) - } else { - Err(err) - } - }) - .map(|()| result.assume_init()) - } -} - -#[cfg(feature = "time")] -#[cfg(target_pointer_width = "32")] -unsafe fn timerfd_gettime_old( - fd: BorrowedFd<'_>, - result: &mut MaybeUninit, -) -> io::Result<()> { - 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(), - }, - }, - ); - Ok(()) -} diff --git a/vendor/rustix/src/imp/linux_raw/time/types.rs b/vendor/rustix/src/imp/linux_raw/time/types.rs deleted file mode 100644 index 5a0fcc6f5..000000000 --- a/vendor/rustix/src/imp/linux_raw/time/types.rs +++ /dev/null @@ -1,154 +0,0 @@ -use super::super::c; -use crate::fd::BorrowedFd; -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`]. -/// -/// [`timerfd_gettime`]: crate::time::timerfd_gettime -/// [`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 - pub struct TimerfdFlags: c::c_uint { - /// `TFD_NONBLOCK` - const NONBLOCK = linux_raw_sys::general::TFD_NONBLOCK; - - /// `TFD_CLOEXEC` - const CLOEXEC = linux_raw_sys::general::TFD_CLOEXEC; - } -} - -bitflags! { - /// `TFD_TIMER_*` flags for use with [`timerfd_settime`]. - /// - /// [`timerfd_settime`]: crate::time::timerfd_settime - pub struct TimerfdTimerFlags: c::c_uint { - /// `TFD_TIMER_ABSTIME` - const ABSTIME = linux_raw_sys::general::TFD_TIMER_ABSTIME; - - /// `TFD_TIMER_CANCEL_ON_SET` - const CANCEL_ON_SET = linux_raw_sys::general::TFD_TIMER_CANCEL_ON_SET; - } -} - -/// `CLOCK_*` constants for use with [`timerfd_create`]. -/// -/// [`timerfd_create`]: crate::time::timerfd_create -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -#[repr(u32)] -#[non_exhaustive] -pub enum TimerfdClockId { - /// `CLOCK_REALTIME`—A clock that tells the "real" time. - /// - /// This is a clock that tells the amount of time elapsed since the - /// Unix epoch, 1970-01-01T00:00:00Z. The clock is externally settable, so - /// it is not monotonic. Successive reads may see decreasing times, so it - /// isn't reliable for measuring durations. - Realtime = linux_raw_sys::general::CLOCK_REALTIME, - - /// `CLOCK_MONOTONIC`—A clock that tells an abstract time. - /// - /// Unlike `Realtime`, this clock is not based on a fixed known epoch, so - /// individual times aren't meaningful. However, since it isn't settable, - /// it is reliable for measuring durations. - /// - /// This clock does not advance while the system is suspended; see - /// `Boottime` for a clock that does. - Monotonic = linux_raw_sys::general::CLOCK_MONOTONIC, - - /// `CLOCK_BOOTTIME`—Like `Monotonic`, but advances while suspended. - /// - /// This clock is similar to `Monotonic`, but does advance while the system - /// is suspended. - Boottime = linux_raw_sys::general::CLOCK_BOOTTIME, - - /// `CLOCK_REALTIME_ALARM`—Like `Realtime`, but wakes a suspended system. - /// - /// This clock is like `Realtime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - RealtimeAlarm = linux_raw_sys::general::CLOCK_REALTIME_ALARM, - - /// `CLOCK_BOOTTIME_ALARM`—Like `Boottime`, but wakes a suspended system. - /// - /// This clock is like `Boottime`, but can wake up a suspended system. - /// - /// Use of this clock requires the `CAP_WAKE_ALARM` Linux capability. - BoottimeAlarm = linux_raw_sys::general::CLOCK_BOOTTIME_ALARM, -} diff --git a/vendor/rustix/src/imp/linux_raw/vdso.rs b/vendor/rustix/src/imp/linux_raw/vdso.rs deleted file mode 100644 index bda0a4773..000000000 --- a/vendor/rustix/src/imp/linux_raw/vdso.rs +++ /dev/null @@ -1,435 +0,0 @@ -//! Parse the Linux vDSO. -//! -//! The following code is transliterated from -//! tools/testing/selftests/vDSO/parse_vdso.c in Linux 5.11, which is licensed -//! with Creative Commons Zero License, version 1.0, -//! available at -//! -//! # Safety -//! -//! Parsing the vDSO involves a lot of raw pointer manipulation. This -//! implementation follows Linux's reference implementation, and adds several -//! additional safety checks. -#![allow(unsafe_code)] - -use super::c; -use super::elf::*; -use super::mm::syscalls::madvise; -use super::mm::types::Advice; -use crate::ffi::CStr; -use crate::io; -use core::ffi::c_void; -use core::mem::{align_of, size_of}; -use core::ptr::{null, null_mut}; - -pub(super) struct Vdso { - // Load information - load_addr: *const Elf_Ehdr, - load_end: *const c_void, // the end of the `PT_LOAD` segment - pv_offset: usize, // recorded paddr - recorded vaddr - - // Symbol table - symtab: *const Elf_Sym, - symstrings: *const u8, - bucket: *const u32, - chain: *const u32, - nbucket: u32, - //nchain: u32, - - // Version table - versym: *const u16, - verdef: *const Elf_Verdef, -} - -// Straight from the ELF specification. -fn elf_hash(name: &CStr) -> u32 { - let mut h: u32 = 0; - for b in name.to_bytes() { - h = (h << 4).wrapping_add(u32::from(*b)); - let g = h & 0xf000_0000; - if g != 0 { - h ^= g >> 24; - } - h &= !g; - } - h -} - -/// Cast `value` to a pointer type, doing some checks for validity. -fn make_pointer(value: *const c_void) -> Option<*const T> { - if value.is_null() - || (value as usize).checked_add(size_of::()).is_none() - || (value as usize) % align_of::() != 0 - { - return None; - } - - Some(value.cast()) -} - -/// Create a `Vdso` value by parsing the vDSO at the given address. -/// -/// # Safety -/// -/// `base` must be a valid pointer to an ELF image in memory. -unsafe fn init_from_sysinfo_ehdr(base: *const Elf_Ehdr) -> Option { - // Check that `base` is a valid pointer to the kernel-provided vDSO. - let hdr = check_vdso_base(base)?; - - let mut vdso = Vdso { - load_addr: base, - load_end: base.cast(), - pv_offset: 0, - symtab: null(), - symstrings: null(), - bucket: null(), - chain: null(), - nbucket: 0, - //nchain: 0, - versym: null(), - verdef: null(), - }; - - let pt = make_pointer::(vdso.base_plus(hdr.e_phoff)?)?; - let mut dyn_: *const Elf_Dyn = null(); - let mut num_dyn = 0; - - // We need two things from the segment table: the load offset - // and the dynamic table. - let mut found_vaddr = false; - for i in 0..hdr.e_phnum { - let phdr = &*pt.add(i as usize); - if phdr.p_flags & PF_W != 0 { - // Don't trust any vDSO that claims to be loading writable - // segments into memory. - return None; - } - if phdr.p_type == PT_LOAD && !found_vaddr { - // The segment should be readable and executable, because it - // contains the symbol table and the function bodies. - if phdr.p_flags & (PF_R | PF_X) != (PF_R | PF_X) { - return None; - } - found_vaddr = true; - vdso.load_end = vdso.base_plus(phdr.p_offset.checked_add(phdr.p_memsz)?)?; - vdso.pv_offset = phdr.p_offset.wrapping_sub(phdr.p_vaddr); - } else if phdr.p_type == PT_DYNAMIC { - // If `p_offset` is zero, it's more likely that we're looking at memory - // that has been zeroed than that the kernel has somehow aliased the - // `Ehdr` and the `Elf_Dyn` array. - if phdr.p_offset < size_of::() { - return None; - } - - dyn_ = make_pointer::(vdso.base_plus(phdr.p_offset)?)?; - num_dyn = phdr.p_memsz / size_of::(); - } else if phdr.p_type == PT_INTERP || phdr.p_type == PT_GNU_RELRO { - // Don't trust any ELF image that has an "interpreter" or that uses - // RELRO, which is likely to be a user ELF image rather and not the - // kernel vDSO. - return None; - } - } - - if !found_vaddr || dyn_.is_null() { - return None; // Failed - } - - // Fish out the useful bits of the dynamic table. - let mut hash: *const u32 = null(); - vdso.symstrings = null(); - vdso.symtab = null(); - vdso.versym = null(); - vdso.verdef = null(); - let mut i = 0; - loop { - if i == num_dyn { - return None; - } - let d = &*dyn_.add(i); - match d.d_tag { - DT_STRTAB => { - vdso.symstrings = make_pointer::(vdso.addr_from_elf(d.d_val)?)?; - } - DT_SYMTAB => { - vdso.symtab = make_pointer::(vdso.addr_from_elf(d.d_val)?)?; - } - DT_HASH => { - hash = make_pointer::(vdso.addr_from_elf(d.d_val)?)?; - } - DT_VERSYM => { - vdso.versym = make_pointer::(vdso.addr_from_elf(d.d_val)?)?; - } - DT_VERDEF => { - vdso.verdef = make_pointer::(vdso.addr_from_elf(d.d_val)?)?; - } - DT_SYMENT => { - if d.d_val != size_of::() { - return None; // Failed - } - } - DT_NULL => break, - _ => {} - } - i = i.checked_add(1)?; - } - if vdso.symstrings.is_null() || vdso.symtab.is_null() || hash.is_null() { - return None; // Failed - } - - if vdso.verdef.is_null() { - vdso.versym = null(); - } - - // Parse the hash table header. - vdso.nbucket = *hash.add(0); - //vdso.nchain = *hash.add(1); - vdso.bucket = hash.add(2); - vdso.chain = hash.add(vdso.nbucket as usize + 2); - - // That's all we need. - Some(vdso) -} - -/// Check that `base` is a valid pointer to the kernel-provided vDSO. -/// -/// `base` is some value we got from a `AT_SYSINFO_EHDR` aux record somewhere, -/// which hopefully holds the value of the kernel-provided vDSO in memory. Do a -/// series of checks to be as sure as we can that it's safe to use. -unsafe fn check_vdso_base<'vdso>(base: *const Elf_Ehdr) -> Option<&'vdso Elf_Ehdr> { - // In theory, we could check that we're not attempting to parse our own ELF - // image, as an additional check. However, older Linux toolchains don't - // support this, and Rust's `#[linkage = "extern_weak"]` isn't stable yet, - // so just disable this for now. - /* - { - extern "C" { - static __ehdr_start: c::c_void; - } - - let ehdr_start: *const c::c_void = &__ehdr_start; - if base == ehdr_start { - return None; - } - } - */ - - let hdr = &*make_pointer::(base.cast())?; - - // Check that the vDSO is page-aligned and appropriately mapped. We call - // this after `make_pointer` so that we don't do a syscall if there's no - // chance the pointer is valid. - madvise(base as *mut c_void, size_of::(), Advice::Normal).ok()?; - - if hdr.e_ident[..SELFMAG] != ELFMAG { - return None; // Wrong ELF magic - } - if hdr.e_ident[EI_CLASS] != ELFCLASS { - return None; // Wrong ELF class - } - if hdr.e_ident[EI_DATA] != ELFDATA { - return None; // Wrong ELF data - } - if !matches!(hdr.e_ident[EI_OSABI], ELFOSABI_SYSV | ELFOSABI_LINUX) { - return None; // Unrecognized ELF OS ABI - } - if hdr.e_ident[EI_ABIVERSION] != ELFABIVERSION { - return None; // Unrecognized ELF ABI version - } - if hdr.e_type != ET_DYN { - return None; // Wrong ELF type - } - // Verify that the `e_machine` matches the architecture we're running as. - // This helps catch cases where we're running under qemu. - if hdr.e_machine != EM_CURRENT { - return None; // Wrong machine type - } - - // If ELF is extended, we'll need to adjust. - if hdr.e_ident[EI_VERSION] != EV_CURRENT - || hdr.e_ehsize as usize != size_of::() - || hdr.e_phentsize as usize != size_of::() - { - return None; - } - // We don't currently support extra-large numbers of segments. - if hdr.e_phnum == PN_XNUM { - return None; - } - - // If `e_phoff` is zero, it's more likely that we're looking at memory that - // has been zeroed than that the kernel has somehow aliased the `Ehdr` and - // the `Phdr`. - if hdr.e_phoff < size_of::() { - return None; - } - - // Check that the vDSO is not writable, since that would indicate that this - // isn't the kernel vDSO. Here we're just using `clock_getres` just as an - // arbitrary system call which writes to a buffer and fails with `EFAULT` - // if the buffer is not writable. - { - use super::conv::ret; - use super::time::types::ClockId; - if ret(syscall!(__NR_clock_getres, ClockId::Monotonic, base)) != Err(io::Errno::FAULT) { - // We can't gracefully fail here because we would seem to have just - // mutated some unknown memory. - #[cfg(feature = "std")] - { - std::process::abort(); - } - #[cfg(all(not(feature = "std"), feature = "rustc-dep-of-std"))] - { - core::intrinsics::abort(); - } - } - } - - Some(hdr) -} - -impl Vdso { - /// Parse the vDSO. - /// - /// Returns None if the vDSO can't be located or if it doesn't conform - /// to our expectations. - #[inline] - pub(super) fn new() -> Option { - init_from_auxv() - } - - /// Check the version for a symbol. - /// - /// # Safety - /// - /// The raw pointers inside `self` must be valid. - unsafe fn match_version(&self, mut ver: u16, name: &CStr, hash: u32) -> bool { - // This is a helper function to check if the version indexed by - // ver matches name (which hashes to hash). - // - // The version definition table is a mess, and I don't know how - // to do this in better than linear time without allocating memory - // to build an index. I also don't know why the table has - // variable size entries in the first place. - // - // For added fun, I can't find a comprehensible specification of how - // to parse all the weird flags in the table. - // - // So I just parse the whole table every time. - - // First step: find the version definition - ver &= 0x7fff; // Apparently bit 15 means "hidden" - let mut def = self.verdef; - loop { - if (*def).vd_version != VER_DEF_CURRENT { - return false; // Failed - } - - if ((*def).vd_flags & VER_FLG_BASE) == 0 && ((*def).vd_ndx & 0x7fff) == ver { - break; - } - - if (*def).vd_next == 0 { - return false; // No definition. - } - - def = def - .cast::() - .add((*def).vd_next as usize) - .cast::(); - } - - // Now figure out whether it matches. - let aux = &*(def.cast::()) - .add((*def).vd_aux as usize) - .cast::(); - (*def).vd_hash == hash - && (name == CStr::from_ptr(self.symstrings.add(aux.vda_name as usize).cast())) - } - - /// Look up a symbol in the vDSO. - pub(super) fn sym(&self, version: &CStr, name: &CStr) -> *mut c::c_void { - let ver_hash = elf_hash(version); - let name_hash = elf_hash(name); - - // Safety: The pointers in `self` must be valid. - unsafe { - let mut chain = *self.bucket.add((name_hash % self.nbucket) as usize); - - while chain != STN_UNDEF { - let sym = &*self.symtab.add(chain as usize); - - // Check for a defined global or weak function w/ right name. - // - // The reference parser in Linux's parse_vdso.c requires - // symbols to have type `STT_FUNC`, but on powerpc64, the vDSO - // uses `STT_NOTYPE`, so allow that too. - if (ELF_ST_TYPE(sym.st_info) != STT_FUNC && - ELF_ST_TYPE(sym.st_info) != STT_NOTYPE) - || (ELF_ST_BIND(sym.st_info) != STB_GLOBAL - && ELF_ST_BIND(sym.st_info) != STB_WEAK) - || sym.st_shndx == SHN_UNDEF - || sym.st_shndx == SHN_ABS - || ELF_ST_VISIBILITY(sym.st_other) != STV_DEFAULT - || (name != CStr::from_ptr(self.symstrings.add(sym.st_name as usize).cast())) - // Check symbol version. - || (!self.versym.is_null() - && !self.match_version(*self.versym.add(chain as usize), version, ver_hash)) - { - chain = *self.chain.add(chain as usize); - continue; - } - - let sum = self.addr_from_elf(sym.st_value).unwrap(); - assert!( - sum as usize >= self.load_addr as usize - && sum as usize <= self.load_end as usize - ); - return sum as *mut c::c_void; - } - } - - null_mut() - } - - /// Add the given address to the vDSO base address. - unsafe fn base_plus(&self, offset: usize) -> Option<*const c_void> { - // Check for overflow. - let _ = (self.load_addr as usize).checked_add(offset)?; - // Add the offset to the base. - Some(self.load_addr.cast::().add(offset).cast()) - } - - /// Translate an ELF-address-space address into a usable virtual address. - unsafe fn addr_from_elf(&self, elf_addr: usize) -> Option<*const c_void> { - self.base_plus(elf_addr.wrapping_add(self.pv_offset)) - } -} - -// Find the `AT_SYSINFO_EHDR` in auxv records in memory. We have our own code -// for reading the auxv records in memory, so we don't currently use this. -// -// # Safety -// -// `elf_auxv` must point to a valid array of AUXV records terminated by an -// `AT_NULL` record. -/* -unsafe fn init_from_auxv(elf_auxv: *const Elf_auxv_t) -> Option { - let mut i = 0; - while (*elf_auxv.add(i)).a_type != AT_NULL { - if (*elf_auxv.add(i)).a_type == AT_SYSINFO_EHDR { - return init_from_sysinfo_ehdr((*elf_auxv.add(i)).a_val); - } - i += 1; - } - - None -} -*/ - -/// Find the vDSO image by following the `AT_SYSINFO_EHDR` auxv record pointer. -fn init_from_auxv() -> Option { - // Safety: `sysinfo_ehdr` does extensive checks to ensure that the value - // we get really is an `AT_SYSINFO_EHDR` value from the kernel. - unsafe { init_from_sysinfo_ehdr(super::param::auxv::sysinfo_ehdr()) } -} diff --git a/vendor/rustix/src/imp/linux_raw/vdso_wrappers.rs b/vendor/rustix/src/imp/linux_raw/vdso_wrappers.rs deleted file mode 100644 index 80c8dbefd..000000000 --- a/vendor/rustix/src/imp/linux_raw/vdso_wrappers.rs +++ /dev/null @@ -1,397 +0,0 @@ -//! Implement syscalls using the vDSO. -//! -//! -//! -//! # Safety -//! -//! Similar to syscalls.rs, this file performs raw system calls, and sometimes -//! passes them uninitialized memory buffers. This file also calls vDSO -//! 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; -#[cfg(all(asm, target_arch = "x86"))] -use core::arch::asm; -use core::mem::{transmute, MaybeUninit}; -use core::ptr::null_mut; -use core::sync::atomic::AtomicPtr; -use core::sync::atomic::Ordering::Relaxed; -#[cfg(target_pointer_width = "32")] -use linux_raw_sys::general::timespec as __kernel_old_timespec; -use linux_raw_sys::general::{__kernel_clockid_t, __kernel_timespec}; - -#[inline] -pub(crate) fn clock_gettime(which_clock: ClockId) -> __kernel_timespec { - // Safety: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has - // the side effect of writing to the result buffer, and no others. - unsafe { - let mut result = MaybeUninit::<__kernel_timespec>::uninit(); - let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { - Some(callee) => callee, - None => init_clock_gettime(), - }; - let r0 = callee(which_clock as c::c_int, result.as_mut_ptr()); - assert_eq!(r0, 0); - result.assume_init() - } -} - -#[inline] -pub(crate) fn clock_gettime_dynamic(which_clock: DynamicClockId<'_>) -> io::Result { - let id = match which_clock { - DynamicClockId::Known(id) => id as __kernel_clockid_t, - - DynamicClockId::Dynamic(fd) => { - // See `FD_TO_CLOCKID` in Linux's `clock_gettime` documentation. - use crate::imp::fd::AsRawFd; - const CLOCKFD: i32 = 3; - ((!fd.as_raw_fd() << 3) | CLOCKFD) as __kernel_clockid_t - } - - DynamicClockId::RealtimeAlarm => { - linux_raw_sys::general::CLOCK_REALTIME_ALARM as __kernel_clockid_t - } - DynamicClockId::Tai => linux_raw_sys::general::CLOCK_TAI as __kernel_clockid_t, - DynamicClockId::Boottime => linux_raw_sys::general::CLOCK_BOOTTIME as __kernel_clockid_t, - DynamicClockId::BoottimeAlarm => { - linux_raw_sys::general::CLOCK_BOOTTIME_ALARM as __kernel_clockid_t - } - }; - - // Safety: `CLOCK_GETTIME` contains either null or the address of a - // function with an ABI like libc `clock_gettime`, and calling it has - // the side effect of writing to the result buffer, and no others. - unsafe { - const EINVAL: c::c_int = -(c::EINVAL as c::c_int); - let mut timespec = MaybeUninit::::uninit(); - let callee = match transmute(CLOCK_GETTIME.load(Relaxed)) { - Some(callee) => callee, - None => init_clock_gettime(), - }; - match callee(id, timespec.as_mut_ptr()) { - 0 => (), - EINVAL => return Err(io::Errno::INVAL), - _ => _rustix_clock_gettime_via_syscall(id, timespec.as_mut_ptr())?, - } - Ok(timespec.assume_init()) - } -} - -#[cfg(target_arch = "x86")] -pub(super) mod x86_via_vdso { - use super::{transmute, ArgReg, Relaxed, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0}; - use crate::imp::arch::asm; - - #[inline] - pub(in crate::imp) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall0(callee, nr) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall1<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - ) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall1(callee, nr, a0) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall1_noreturn<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - ) -> ! { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall1_noreturn(callee, nr, a0) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall2<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - ) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall2(callee, nr, a0, a1) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall3<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - ) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall3(callee, nr, a0, a1, a2) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall4<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - a3: ArgReg<'a, A3>, - ) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall4(callee, nr, a0, a1, a2, a3) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall5<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - a3: ArgReg<'a, A3>, - a4: ArgReg<'a, A4>, - ) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall5(callee, nr, a0, a1, a2, a3, a4) - } - - #[inline] - pub(in crate::imp) unsafe fn syscall6<'a>( - nr: SyscallNumber<'a>, - a0: ArgReg<'a, A0>, - a1: ArgReg<'a, A1>, - a2: ArgReg<'a, A2>, - a3: ArgReg<'a, A3>, - a4: ArgReg<'a, A4>, - a5: ArgReg<'a, A5>, - ) -> RetReg { - let callee = match transmute(super::SYSCALL.load(Relaxed)) { - Some(callee) => callee, - None => super::init_syscall(), - }; - asm::indirect_syscall6(callee, nr, a0, a1, a2, a3, a4, a5) - } - - // With the indirect call, it isn't meaningful to do a separate - // `_readonly` optimization. - pub(in crate::imp) use { - syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, - syscall2 as syscall2_readonly, syscall3 as syscall3_readonly, - syscall4 as syscall4_readonly, syscall5 as syscall5_readonly, - syscall6 as syscall6_readonly, - }; -} - -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 -/// special syscall calling convention to pass arguments and return values, -/// which the signature here doesn't reflect. -#[cfg(target_arch = "x86")] -pub(super) type SyscallType = unsafe extern "C" fn(); - -fn init_clock_gettime() -> ClockGettimeType { - init(); - // Safety: Load the function address from static storage that we - // just initialized. - unsafe { transmute(CLOCK_GETTIME.load(Relaxed)) } -} - -#[cfg(target_arch = "x86")] -fn init_syscall() -> SyscallType { - init(); - // Safety: Load the function address from static storage that we - // just initialized. - unsafe { transmute(SYSCALL.load(Relaxed)) } -} - -/// `AtomicPtr` can't hold a `fn` pointer, so we use a `*` pointer to this -/// placeholder type, and cast it as needed. -struct Function; -static mut CLOCK_GETTIME: AtomicPtr = AtomicPtr::new(null_mut()); -#[cfg(target_arch = "x86")] -static mut SYSCALL: AtomicPtr = AtomicPtr::new(null_mut()); - -unsafe extern "C" fn rustix_clock_gettime_via_syscall( - clockid: c::c_int, - res: *mut Timespec, -) -> c::c_int { - match _rustix_clock_gettime_via_syscall(clockid, res) { - Ok(()) => 0, - Err(e) => e.raw_os_error().wrapping_neg(), - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn _rustix_clock_gettime_via_syscall( - clockid: c::c_int, - res: *mut Timespec, -) -> io::Result<()> { - let r0 = syscall!(__NR_clock_gettime64, c_int(clockid), res); - match ret(r0) { - Err(io::Errno::NOSYS) => _rustix_clock_gettime_via_syscall_old(clockid, res), - otherwise => otherwise, - } -} - -#[cfg(target_pointer_width = "32")] -unsafe fn _rustix_clock_gettime_via_syscall_old( - clockid: c::c_int, - res: *mut Timespec, -) -> io::Result<()> { - // Ordinarily `rustix` doesn't like to emulate system calls, but in - // the case of time APIs, it's specific to Linux, specific to - // 32-bit architectures *and* specific to old kernel versions, and - // it's not that hard to fix up here, so that no other code needs - // to worry about this. - let mut old_result = MaybeUninit::<__kernel_old_timespec>::uninit(); - let r0 = syscall!(__NR_clock_gettime, c_int(clockid), &mut old_result); - match ret(r0) { - Ok(()) => { - let old_result = old_result.assume_init(); - *res = Timespec { - tv_sec: old_result.tv_sec.into(), - tv_nsec: old_result.tv_nsec.into(), - }; - Ok(()) - } - otherwise => otherwise, - } -} - -#[cfg(target_pointer_width = "64")] -unsafe fn _rustix_clock_gettime_via_syscall( - clockid: c::c_int, - res: *mut Timespec, -) -> io::Result<()> { - ret(syscall!(__NR_clock_gettime, c_int(clockid), res)) -} - -/// A symbol pointing to an `int 0x80` instruction. This "function" is only -/// called from assembly, and only with the x86 syscall calling convention, -/// so its signature here is not its true signature. -#[cfg(all(asm, target_arch = "x86"))] -#[naked] -unsafe extern "C" fn rustix_int_0x80() { - asm!("int $$0x80", "ret", options(noreturn)) -} - -// The outline version of the `rustix_int_0x80` above. -#[cfg(all(not(asm), target_arch = "x86"))] -extern "C" { - fn rustix_int_0x80(); -} - -fn minimal_init() { - // Safety: Store default function addresses in static storage so that if we - // end up making any system calls while we read the vDSO, they'll work. - // 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(target_arch = "x86")] - { - SYSCALL - .compare_exchange( - null_mut(), - rustix_int_0x80 as *mut Function, - Relaxed, - Relaxed, - ) - .ok(); - } - } -} - -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(any(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); - } - } - - // On x86, also look up the vsyscall entry point. - #[cfg(target_arch = "x86")] - { - let ptr = vdso.sym(cstr!("LINUX_2.5"), cstr!("__kernel_vsyscall")); - assert!(!ptr.is_null()); - - // Safety: As above, store the computed function addresses in - // static storage. - unsafe { - SYSCALL.store(ptr.cast(), Relaxed); - } - } - } -} diff --git a/vendor/rustix/src/io/close.rs b/vendor/rustix/src/io/close.rs index 2116f53bd..b286d2368 100644 --- a/vendor/rustix/src/io/close.rs +++ b/vendor/rustix/src/io/close.rs @@ -5,8 +5,8 @@ //! Operating on raw file descriptors is unsafe. #![allow(unsafe_code)] -use crate::imp; -use imp::fd::RawFd; +use crate::backend; +use backend::fd::RawFd; /// `close(raw_fd)`—Closes a `RawFd` directly. /// @@ -37,5 +37,5 @@ use imp::fd::RawFd; /// not valid after the call. #[inline] pub unsafe fn close(raw_fd: RawFd) { - imp::io::syscalls::close(raw_fd) + backend::io::syscalls::close(raw_fd) } diff --git a/vendor/rustix/src/io/dup.rs b/vendor/rustix/src/io/dup.rs index ffa0401f2..8da6aa091 100644 --- a/vendor/rustix/src/io/dup.rs +++ b/vendor/rustix/src/io/dup.rs @@ -1,11 +1,11 @@ //! Functions which duplicate file descriptors. -use crate::imp; -use crate::io::{self, OwnedFd}; -use imp::fd::AsFd; +use crate::fd::OwnedFd; +use crate::{backend, io}; +use backend::fd::AsFd; #[cfg(not(target_os = "wasi"))] -pub use imp::io::types::DupFlags; +pub use backend::io::types::DupFlags; /// `dup(fd)`—Creates a new `OwnedFd` instance that shares the same /// underlying [file description] as `fd`. @@ -23,14 +23,14 @@ pub use imp::io::types::DupFlags; /// - [Apple] /// /// [file description]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258 -/// [`fcntl_dupfd_cloexec`]: crate::fs::fcntl_dupfd_cloexec +/// [`fcntl_dupfd_cloexec`]: crate::io::fcntl_dupfd_cloexec /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html /// [Linux]: https://man7.org/linux/man-pages/man2/dup.2.html /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/dup.2.html #[cfg(not(target_os = "wasi"))] #[inline] pub fn dup(fd: Fd) -> io::Result { - imp::io::syscalls::dup(fd.as_fd()) + backend::io::syscalls::dup(fd.as_fd()) } /// `dup2(fd, new)`—Changes the [file description] of a file descriptor. @@ -50,14 +50,14 @@ pub fn dup(fd: Fd) -> io::Result { /// - [Apple] /// /// [file description]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258 -/// [`fcntl_dupfd_cloexec`]: crate::fs::fcntl_dupfd_cloexec +/// [`fcntl_dupfd_cloexec`]: crate::io::fcntl_dupfd_cloexec /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html /// [Linux]: https://man7.org/linux/man-pages/man2/dup2.2.html /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/dup2.2.html #[cfg(not(target_os = "wasi"))] #[inline] pub fn dup2(fd: Fd, new: &mut OwnedFd) -> io::Result<()> { - imp::io::syscalls::dup2(fd.as_fd(), new) + backend::io::syscalls::dup2(fd.as_fd(), new) } /// `dup3(fd, new, flags)`—Changes the [file description] of a file @@ -73,8 +73,8 @@ pub fn dup2(fd: Fd, new: &mut OwnedFd) -> io::Result<()> { /// /// [file description]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258 /// [Linux]: https://man7.org/linux/man-pages/man2/dup3.2.html -#[cfg(not(target_os = "wasi"))] +#[cfg(not(any(target_os = "aix", target_os = "wasi")))] #[inline] pub fn dup3(fd: Fd, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> { - imp::io::syscalls::dup3(fd.as_fd(), new, flags) + backend::io::syscalls::dup3(fd.as_fd(), new, flags) } diff --git a/vendor/rustix/src/io/errno.rs b/vendor/rustix/src/io/errno.rs index 84ced6a37..f39573797 100644 --- a/vendor/rustix/src/io/errno.rs +++ b/vendor/rustix/src/io/errno.rs @@ -4,7 +4,7 @@ //! enum because we may not know about all of the host's error values //! and we don't want unrecognized values to create UB. -use crate::imp; +use crate::backend; use core::{fmt, result}; #[cfg(feature = "std")] use std::error; @@ -25,7 +25,7 @@ pub type Result = result::Result; /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html /// [Linux]: https://man7.org/linux/man-pages/man3/errno.3.html -pub use imp::io::errno::Errno; +pub use backend::io::errno::Errno; impl Errno { /// Shorthand for `std::io::Error::from(self).kind()`. diff --git a/vendor/rustix/src/io/eventfd.rs b/vendor/rustix/src/io/eventfd.rs index 53e9d11f0..22ffc627c 100644 --- a/vendor/rustix/src/io/eventfd.rs +++ b/vendor/rustix/src/io/eventfd.rs @@ -1,7 +1,7 @@ -use crate::imp; -use crate::io::{self, OwnedFd}; +use crate::fd::OwnedFd; +use crate::{backend, io}; -pub use imp::io::types::EventfdFlags; +pub use backend::io::types::EventfdFlags; /// `eventfd(initval, flags)`—Creates a file descriptor for event /// notification. @@ -12,5 +12,5 @@ pub use imp::io::types::EventfdFlags; /// [Linux]: https://man7.org/linux/man-pages/man2/eventfd.2.html #[inline] pub fn eventfd(initval: u32, flags: EventfdFlags) -> io::Result { - imp::io::syscalls::eventfd(initval, flags) + backend::io::syscalls::eventfd(initval, flags) } diff --git a/vendor/rustix/src/io/fcntl.rs b/vendor/rustix/src/io/fcntl.rs new file mode 100644 index 000000000..109e4540b --- /dev/null +++ b/vendor/rustix/src/io/fcntl.rs @@ -0,0 +1,86 @@ +//! The Unix `fcntl` function is effectively lots of different functions +//! hidden behind a single dynamic dispatch interface. In order to provide +//! a type-safe API, rustix makes them all separate functions so that they +//! can have dedicated static type signatures. +//! +//! `fcntl` functions which are not specific to files or directories live +//! in the [`io`] module instead. +//! +//! [`io`]: crate::io + +use crate::backend; +use crate::io; +use backend::fd::{AsFd, OwnedFd, RawFd}; + +pub use backend::io::types::FdFlags; + +/// `fcntl(fd, F_GETFD)`—Returns a file descriptor's flags. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html +/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html +#[inline] +#[doc(alias = "F_GETFD")] +pub fn fcntl_getfd(fd: Fd) -> io::Result { + backend::io::syscalls::fcntl_getfd(fd.as_fd()) +} + +/// `fcntl(fd, F_SETFD, flags)`—Sets a file descriptor's flags. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html +/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html +#[inline] +#[doc(alias = "F_SETFD")] +pub fn fcntl_setfd(fd: Fd, flags: FdFlags) -> io::Result<()> { + backend::io::syscalls::fcntl_setfd(fd.as_fd(), flags) +} + +/// `fcntl(fd, F_DUPFD_CLOEXEC)`—Creates a new `OwnedFd` instance, with value +/// at least `min`, that has `O_CLOEXEC` set and that shares the same +/// underlying [file description] as `fd`. +/// +/// POSIX guarantees that `F_DUPFD_CLOEXEC` will use the lowest unused file +/// descriptor which is at least `min`, however it is not safe in general to +/// rely on this, as file descriptors may be unexpectedly allocated on other +/// threads or in libraries. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html +/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html +#[cfg(not(any(target_os = "wasi", target_os = "espidf")))] +#[inline] +#[doc(alias = "F_DUPFD_CLOEXEC")] +pub fn fcntl_dupfd_cloexec(fd: Fd, min: RawFd) -> io::Result { + backend::io::syscalls::fcntl_dupfd_cloexec(fd.as_fd(), min) +} + +/// `fcntl(fd, F_DUPFD)`—Creates a new `OwnedFd` instance, with value at least +/// `min`, that shares the same underlying [file description] as `fd`. +/// +/// POSIX guarantees that `F_DUPFD` will use the lowest unused file descriptor +/// which is at least `min`, however it is not safe in general to rely on this, +/// as file descriptors may be unexpectedly allocated on other threads or in +/// libraries. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html +/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html +#[cfg(target_os = "espidf")] +#[inline] +#[doc(alias = "F_DUPFD")] +pub fn fcntl_dupfd(fd: Fd, min: RawFd) -> io::Result { + backend::io::syscalls::fcntl_dupfd(fd.as_fd(), min) +} diff --git a/vendor/rustix/src/io/fd/owned.rs b/vendor/rustix/src/io/fd/owned.rs index d99b6a0f9..c2972b073 100644 --- a/vendor/rustix/src/io/fd/owned.rs +++ b/vendor/rustix/src/io/fd/owned.rs @@ -92,14 +92,14 @@ impl OwnedFd { // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This // is a POSIX flag that was added to Linux in 2.6.24. #[cfg(not(target_os = "espidf"))] - let fd = crate::fs::fcntl_dupfd_cloexec(self, 0)?; + let fd = crate::io::fcntl_dupfd_cloexec(self, 0)?; // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics // will never be supported, as this is a bare metal framework with // no capabilities for multi-process execution. While F_DUPFD is also // not supported yet, it might be (currently it returns ENOSYS). #[cfg(target_os = "espidf")] - let fd = crate::fs::fcntl_dupfd(self)?; + let fd = crate::io::fcntl_dupfd(self)?; Ok(fd.into()) } diff --git a/vendor/rustix/src/io/fd/raw.rs b/vendor/rustix/src/io/fd/raw.rs index 44322d9fe..a522c9794 100644 --- a/vendor/rustix/src/io/fd/raw.rs +++ b/vendor/rustix/src/io/fd/raw.rs @@ -7,7 +7,7 @@ #![cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #![allow(unsafe_code)] -use crate::imp::c; +use crate::backend::c; /// Raw file descriptors. #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] diff --git a/vendor/rustix/src/io/ioctl.rs b/vendor/rustix/src/io/ioctl.rs index be47e7958..01ded2e12 100644 --- a/vendor/rustix/src/io/ioctl.rs +++ b/vendor/rustix/src/io/ioctl.rs @@ -3,8 +3,8 @@ //! a type-safe API, rustix makes them all separate functions so that they //! can have dedicated static type signatures. -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; /// `ioctl(fd, TIOCEXCL)`—Enables exclusive mode on a terminal. /// @@ -12,11 +12,11 @@ use imp::fd::AsFd; /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))] #[inline] #[doc(alias = "TIOCEXCL")] pub fn ioctl_tiocexcl(fd: Fd) -> io::Result<()> { - imp::io::syscalls::ioctl_tiocexcl(fd.as_fd()) + backend::io::syscalls::ioctl_tiocexcl(fd.as_fd()) } /// `ioctl(fd, TIOCNXCL)`—Disables exclusive mode on a terminal. @@ -25,11 +25,11 @@ pub fn ioctl_tiocexcl(fd: Fd) -> io::Result<()> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))] #[inline] #[doc(alias = "TIOCNXCL")] pub fn ioctl_tiocnxcl(fd: Fd) -> io::Result<()> { - imp::io::syscalls::ioctl_tiocnxcl(fd.as_fd()) + backend::io::syscalls::ioctl_tiocnxcl(fd.as_fd()) } /// `ioctl(fd, FIOCLEX)`—Set the close-on-exec flag. @@ -47,7 +47,7 @@ pub fn ioctl_tiocnxcl(fd: Fd) -> io::Result<()> { #[doc(alias = "FIOCLEX")] #[doc(alias = "FD_CLOEXEC")] pub fn ioctl_fioclex(fd: Fd) -> io::Result<()> { - imp::io::syscalls::ioctl_fioclex(fd.as_fd()) + backend::io::syscalls::ioctl_fioclex(fd.as_fd()) } /// `ioctl(fd, FIONBIO, &value)`—Enables or disables non-blocking mode. @@ -61,7 +61,7 @@ pub fn ioctl_fioclex(fd: Fd) -> io::Result<()> { #[inline] #[doc(alias = "FIONBIO")] pub fn ioctl_fionbio(fd: Fd, value: bool) -> io::Result<()> { - imp::io::syscalls::ioctl_fionbio(fd.as_fd(), value) + backend::io::syscalls::ioctl_fionbio(fd.as_fd(), value) } /// `ioctl(fd, FIONREAD)`—Returns the number of bytes ready to be read. @@ -79,7 +79,7 @@ pub fn ioctl_fionbio(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "FIONREAD")] pub fn ioctl_fionread(fd: Fd) -> io::Result { - imp::io::syscalls::ioctl_fionread(fd.as_fd()) + backend::io::syscalls::ioctl_fionread(fd.as_fd()) } /// `ioctl(fd, BLKSSZGET)`—Returns the logical block size of a block device. @@ -87,7 +87,7 @@ pub fn ioctl_fionread(fd: Fd) -> io::Result { #[inline] #[doc(alias = "BLKSSZGET")] pub fn ioctl_blksszget(fd: Fd) -> io::Result { - imp::io::syscalls::ioctl_blksszget(fd.as_fd()) + backend::io::syscalls::ioctl_blksszget(fd.as_fd()) } /// `ioctl(fd, BLKPBSZGET)`—Returns the physical block size of a block device. @@ -95,5 +95,5 @@ pub fn ioctl_blksszget(fd: Fd) -> io::Result { #[inline] #[doc(alias = "BLKPBSZGET")] pub fn ioctl_blkpbszget(fd: Fd) -> io::Result { - imp::io::syscalls::ioctl_blkpbszget(fd.as_fd()) + backend::io::syscalls::ioctl_blkpbszget(fd.as_fd()) } diff --git a/vendor/rustix/src/io/is_read_write.rs b/vendor/rustix/src/io/is_read_write.rs index c6f189090..74007e7f9 100644 --- a/vendor/rustix/src/io/is_read_write.rs +++ b/vendor/rustix/src/io/is_read_write.rs @@ -1,7 +1,9 @@ //! The [`is_read_write`] function. -use crate::{imp, io}; -use imp::fd::AsFd; +#[cfg(all(feature = "fs", feature = "net"))] +use crate::{backend, io}; +#[cfg(all(feature = "fs", feature = "net"))] +use backend::fd::AsFd; /// Returns a pair of booleans indicating whether the file descriptor is /// readable and/or writable, respectively. @@ -11,6 +13,8 @@ use imp::fd::AsFd; /// /// [`is_file_read_write`]: crate::fs::is_file_read_write #[inline] +#[cfg(all(feature = "fs", feature = "net"))] +#[cfg_attr(doc_cfg, doc(cfg(all(feature = "fs", feature = "net"))))] pub fn is_read_write(fd: Fd) -> io::Result<(bool, bool)> { - imp::io::syscalls::is_read_write(fd.as_fd()) + backend::io::syscalls::is_read_write(fd.as_fd()) } diff --git a/vendor/rustix/src/io/mod.rs b/vendor/rustix/src/io/mod.rs index 5cd5e2ec9..03f06c4ac 100644 --- a/vendor/rustix/src/io/mod.rs +++ b/vendor/rustix/src/io/mod.rs @@ -6,13 +6,13 @@ mod dup; mod errno; #[cfg(any(target_os = "android", target_os = "linux"))] mod eventfd; +#[cfg(not(windows))] +mod fcntl; #[cfg(not(feature = "std"))] pub(crate) mod fd; mod ioctl; #[cfg(not(any(windows, target_os = "redox")))] -#[cfg(feature = "net")] mod is_read_write; -mod owned_fd; #[cfg(not(any(windows, target_os = "wasi")))] mod pipe; mod poll; @@ -26,13 +26,17 @@ mod seek_from; mod stdio; #[cfg(any(target_os = "android", target_os = "linux"))] -pub use crate::imp::io::epoll; +pub use crate::backend::io::epoll; pub use close::close; -#[cfg(not(any(windows, target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "aix", target_os = "wasi")))] pub use dup::{dup, dup2, dup3, DupFlags}; pub use errno::{retry_on_intr, Errno, Result}; #[cfg(any(target_os = "android", target_os = "linux"))] pub use eventfd::{eventfd, EventfdFlags}; +#[cfg(not(any(windows, target_os = "wasi")))] +pub use fcntl::fcntl_dupfd_cloexec; +#[cfg(not(windows))] +pub use fcntl::{fcntl_getfd, fcntl_setfd, FdFlags}; #[cfg(any(target_os = "ios", target_os = "macos"))] pub use ioctl::ioctl_fioclex; pub use ioctl::ioctl_fionbio; @@ -40,29 +44,46 @@ pub use ioctl::ioctl_fionbio; pub use ioctl::ioctl_fionread; #[cfg(any(target_os = "android", target_os = "linux"))] pub use ioctl::{ioctl_blkpbszget, ioctl_blksszget}; -#[cfg(not(any(windows, target_os = "redox", target_os = "wasi")))] +#[cfg(not(any(windows, target_os = "haiku", target_os = "redox", target_os = "wasi")))] pub use ioctl::{ioctl_tiocexcl, ioctl_tiocnxcl}; #[cfg(not(any(windows, target_os = "redox")))] -#[cfg(feature = "net")] +#[cfg(all(feature = "fs", feature = "net"))] pub use is_read_write::is_read_write; -pub use owned_fd::OwnedFd; #[cfg(not(any(windows, target_os = "wasi")))] pub use pipe::pipe; #[cfg(not(any( windows, + target_os = "haiku", target_os = "illumos", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] pub use pipe::PIPE_BUF; -#[cfg(not(any(windows, target_os = "ios", target_os = "macos", target_os = "wasi")))] +#[cfg(not(any( + windows, + target_os = "aix", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "wasi" +)))] pub use pipe::{pipe_with, PipeFlags}; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use pipe::{splice, vmsplice, IoSliceRaw, SpliceFlags}; pub use poll::{poll, PollFd, PollFlags}; #[cfg(all(feature = "procfs", any(target_os = "android", target_os = "linux")))] -pub use procfs::{proc_self_fd, proc_self_fdinfo_fd, proc_self_maps, proc_self_pagemap}; +pub use procfs::{ + proc_self_fd, proc_self_fdinfo_fd, proc_self_maps, proc_self_pagemap, proc_self_status, +}; #[cfg(not(windows))] pub use read_write::{pread, pwrite, read, readv, write, writev, IoSlice, IoSliceMut}; -#[cfg(not(any(windows, target_os = "redox")))] +#[cfg(not(any( + windows, + target_os = "haiku", + target_os = "redox", + target_os = "solaris" +)))] pub use read_write::{preadv, pwritev}; #[cfg(any(target_os = "android", target_os = "linux"))] pub use read_write::{preadv2, pwritev2, ReadWriteFlags}; @@ -71,4 +92,6 @@ pub use seek_from::SeekFrom; #[cfg(feature = "std")] pub use std::io::SeekFrom; #[cfg(not(windows))] -pub use stdio::{stderr, stdin, stdout, take_stderr, take_stdin, take_stdout}; +pub use stdio::{ + raw_stderr, raw_stdin, raw_stdout, stderr, stdin, stdout, take_stderr, take_stdin, take_stdout, +}; diff --git a/vendor/rustix/src/io/owned_fd.rs b/vendor/rustix/src/io/owned_fd.rs deleted file mode 100644 index 63c6145b0..000000000 --- a/vendor/rustix/src/io/owned_fd.rs +++ /dev/null @@ -1,272 +0,0 @@ -//! A wrapper around [`io_lifetimes::OwnedFd`]. -//! -//! rustix needs to wrap io-lifetimes' `OwnedFd` type so that it can call its -//! own [`close`] function when the `OwnedFd` is dropped. -//! -//! [`close`]: crate::io::close -//! -//! # Safety -//! -//! We wrap an `OwnedFd` in a `ManuallyDrop` so that we can extract the -//! file descriptor and close it ourselves. -#![allow(unsafe_code)] - -use crate::imp::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; -#[cfg(all(not(io_lifetimes_use_std), feature = "std"))] -use crate::imp::fd::{FromFd, IntoFd}; -use crate::io::close; -use core::fmt; -use core::mem::{forget, ManuallyDrop}; - -/// A wrapper around [`io_lifetimes::OwnedFd`] which closes the file descriptor -/// using rustix's own [`close`] rather than libc's `close`. -/// -/// [`close`]: crate::io::close -#[repr(transparent)] -pub struct OwnedFd { - inner: ManuallyDrop, -} - -impl OwnedFd { - /// Creates a new `OwnedFd` instance that shares the same underlying file - /// handle as the existing `OwnedFd` instance. - #[cfg(all(unix, not(target_os = "wasi")))] - pub fn try_clone(&self) -> crate::io::Result { - // We want to atomically duplicate this file descriptor and set the - // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This - // is a POSIX flag that was added to Linux in 2.6.24. - #[cfg(not(target_os = "espidf"))] - let fd = crate::fs::fcntl_dupfd_cloexec(self, 0)?; - - // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics - // will never be supported, as this is a bare metal framework with - // no capabilities for multi-process execution. While F_DUPFD is also - // not supported yet, it might be (currently it returns ENOSYS). - #[cfg(target_os = "espidf")] - let fd = crate::fs::fcntl_dupfd(self)?; - - Ok(fd) - } - - /// Creates a new `OwnedFd` instance that shares the same underlying file - /// handle as the existing `OwnedFd` instance. - #[cfg(target_os = "wasi")] - pub fn try_clone(&self) -> std::io::Result { - Err(std::io::Error::new( - std::io::ErrorKind::Unsupported, - "operation not supported on WASI yet", - )) - } - - /// Creates a new `OwnedFd` instance that shares the same underlying file - /// handle as the existing `OwnedFd` instance. - #[cfg(target_os = "windows")] - pub fn try_clone(&self) -> std::io::Result { - use windows_sys::Win32::Networking::WinSock::{ - WSADuplicateSocketW, WSAGetLastError, WSASocketW, INVALID_SOCKET, SOCKET_ERROR, - WSAEINVAL, WSAEPROTOTYPE, WSAPROTOCOL_INFOW, WSA_FLAG_NO_HANDLE_INHERIT, - WSA_FLAG_OVERLAPPED, - }; - use windows_sys::Win32::System::Threading::GetCurrentProcessId; - - let mut info = unsafe { std::mem::zeroed::() }; - let result = - unsafe { WSADuplicateSocketW(self.as_raw_fd() as _, GetCurrentProcessId(), &mut info) }; - match result { - SOCKET_ERROR => return Err(std::io::Error::last_os_error()), - 0 => (), - _ => panic!(), - } - let socket = unsafe { - WSASocketW( - info.iAddressFamily, - info.iSocketType, - info.iProtocol, - &mut info, - 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT, - ) - }; - - if socket != INVALID_SOCKET { - unsafe { Ok(Self::from_raw_fd(socket as _)) } - } else { - let error = unsafe { WSAGetLastError() }; - - if error != WSAEPROTOTYPE && error != WSAEINVAL { - return Err(std::io::Error::from_raw_os_error(error)); - } - - let socket = unsafe { - WSASocketW( - info.iAddressFamily, - info.iSocketType, - info.iProtocol, - &mut info, - 0, - WSA_FLAG_OVERLAPPED, - ) - }; - - if socket == INVALID_SOCKET { - return Err(std::io::Error::last_os_error()); - } - - unsafe { - let socket = Self::from_raw_fd(socket as _); - socket.set_no_inherit()?; - Ok(socket) - } - } - } - - #[cfg(windows)] - #[cfg(not(target_vendor = "uwp"))] - fn set_no_inherit(&self) -> std::io::Result<()> { - use windows_sys::Win32::Foundation::{SetHandleInformation, HANDLE, HANDLE_FLAG_INHERIT}; - match unsafe { SetHandleInformation(self.as_raw_fd() as HANDLE, HANDLE_FLAG_INHERIT, 0) } { - 0 => return Err(std::io::Error::last_os_error()), - _ => Ok(()), - } - } - - #[cfg(windows)] - #[cfg(target_vendor = "uwp")] - fn set_no_inherit(&self) -> std::io::Result<()> { - Err(std::io::Error::new( - std::io::ErrorKind::Unsupported, - "Unavailable on UWP", - )) - } -} - -#[cfg(not(windows))] -impl AsFd for OwnedFd { - #[inline] - fn as_fd(&self) -> BorrowedFd<'_> { - self.inner.as_fd() - } -} - -#[cfg(windows)] -impl io_lifetimes::AsSocket for OwnedFd { - #[inline] - fn as_socket(&self) -> BorrowedFd<'_> { - self.inner.as_socket() - } -} - -#[cfg(any(io_lifetimes_use_std, not(feature = "std")))] -impl From for crate::imp::fd::OwnedFd { - #[inline] - fn from(owned_fd: OwnedFd) -> Self { - let raw_fd = owned_fd.inner.as_fd().as_raw_fd(); - forget(owned_fd); - - // Safety: We use `as_fd().as_raw_fd()` to extract the raw file - // descriptor from `self.inner`, and then `forget` `self` so - // that they remain valid until the new `OwnedFd` acquires them. - unsafe { crate::imp::fd::OwnedFd::from_raw_fd(raw_fd) } - } -} - -#[cfg(not(any(io_lifetimes_use_std, not(feature = "std"))))] -impl IntoFd for OwnedFd { - #[inline] - fn into_fd(self) -> crate::imp::fd::OwnedFd { - let raw_fd = self.inner.as_fd().as_raw_fd(); - forget(self); - - // Safety: We use `as_fd().as_raw_fd()` to extract the raw file - // descriptor from `self.inner`, and then `forget` `self` so - // that they remain valid until the new `OwnedFd` acquires them. - unsafe { crate::imp::fd::OwnedFd::from_raw_fd(raw_fd) } - } -} - -#[cfg(any(io_lifetimes_use_std, not(feature = "std")))] -impl From for OwnedFd { - #[inline] - fn from(owned_fd: crate::imp::fd::OwnedFd) -> Self { - Self { - inner: ManuallyDrop::new(owned_fd), - } - } -} - -#[cfg(all(not(io_lifetimes_use_std), feature = "std"))] -impl FromFd for OwnedFd { - #[inline] - fn from_fd(owned_fd: crate::imp::fd::OwnedFd) -> Self { - Self { - inner: ManuallyDrop::new(owned_fd), - } - } -} - -#[cfg(not(any(io_lifetimes_use_std, not(feature = "std"))))] -impl From for OwnedFd { - #[inline] - fn from(fd: crate::imp::fd::OwnedFd) -> Self { - Self { - inner: ManuallyDrop::new(fd), - } - } -} - -#[cfg(not(any(io_lifetimes_use_std, not(feature = "std"))))] -impl From for crate::imp::fd::OwnedFd { - #[inline] - fn from(fd: OwnedFd) -> Self { - let raw_fd = fd.inner.as_fd().as_raw_fd(); - forget(fd); - - // Safety: We use `as_fd().as_raw_fd()` to extract the raw file - // descriptor from `self.inner`, and then `forget` `self` so - // that they remain valid until the new `OwnedFd` acquires them. - unsafe { Self::from_raw_fd(raw_fd) } - } -} - -impl AsRawFd for OwnedFd { - #[inline] - fn as_raw_fd(&self) -> RawFd { - self.inner.as_raw_fd() - } -} - -impl IntoRawFd for OwnedFd { - #[inline] - fn into_raw_fd(self) -> RawFd { - let raw_fd = self.inner.as_fd().as_raw_fd(); - forget(self); - raw_fd - } -} - -impl FromRawFd for OwnedFd { - #[inline] - unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self { - inner: ManuallyDrop::new(crate::imp::fd::OwnedFd::from_raw_fd(raw_fd)), - } - } -} - -impl Drop for OwnedFd { - #[inline] - fn drop(&mut self) { - // Safety: We use `as_fd().as_raw_fd()` to extract the raw file - // descriptor from `self.inner`. `self.inner` is wrapped with - // `ManuallyDrop` so dropping it doesn't invalid them. - unsafe { - close(self.as_fd().as_raw_fd()); - } - } -} - -impl fmt::Debug for OwnedFd { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.inner.fmt(f) - } -} diff --git a/vendor/rustix/src/io/pipe.rs b/vendor/rustix/src/io/pipe.rs index 2878d10b1..2b8af6a84 100644 --- a/vendor/rustix/src/io/pipe.rs +++ b/vendor/rustix/src/io/pipe.rs @@ -1,8 +1,15 @@ -use crate::imp; -use crate::io::{self, OwnedFd}; +#![allow(unsafe_code)] + +use crate::fd::OwnedFd; +use crate::{backend, io}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use backend::fd::AsFd; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::io::types::PipeFlags; +pub use backend::io::types::PipeFlags; + +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use backend::io::types::{IoSliceRaw, SpliceFlags}; /// `PIPE_BUF`—The maximum length at which writes to a pipe are atomic. /// @@ -14,11 +21,13 @@ pub use imp::io::types::PipeFlags; /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html #[cfg(not(any( windows, + target_os = "haiku", target_os = "illumos", target_os = "redox", + target_os = "solaris", target_os = "wasi", )))] -pub const PIPE_BUF: usize = imp::io::types::PIPE_BUF; +pub const PIPE_BUF: usize = backend::io::types::PIPE_BUF; /// `pipe()`—Creates a pipe. /// @@ -33,7 +42,7 @@ pub const PIPE_BUF: usize = imp::io::types::PIPE_BUF; /// [Linux]: https://man7.org/linux/man-pages/man2/pipe.2.html #[inline] pub fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { - imp::io::syscalls::pipe() + backend::io::syscalls::pipe() } /// `pipe2(flags)`—Creates a pipe, with flags. @@ -45,9 +54,77 @@ pub fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/pipe2.2.html -#[cfg(not(any(target_os = "ios", target_os = "macos")))] +#[cfg(not(any( + target_os = "aix", + target_os = "haiku", + target_os = "ios", + target_os = "macos" +)))] #[inline] #[doc(alias = "pipe2")] pub fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { - imp::io::syscalls::pipe_with(flags) + backend::io::syscalls::pipe_with(flags) +} + +/// `splice(fd_in, off_in, fd_out, off_out, len, flags)`—Transfer data between a file and a pipe. +/// +/// This function transfers up to `len` bytes of data from the file descriptor `fd_in` +/// to the file descriptor `fd_out`, where one of the file descriptors +/// must refer to a pipe. +/// +/// `off_*` must be `None` if the corresponding fd refers to a pipe. +/// Otherwise its value points to the starting offset to the file, +/// from which the data is read/written. +/// on success the number of bytes read/written is added to the offset. +/// +/// passing `None` causes the read/write to start from the file offset, +/// and the file offset is adjusted appropriately. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/splice.2.html +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub fn splice( + fd_in: FdIn, + off_in: Option<&mut u64>, + fd_out: FdOut, + off_out: Option<&mut u64>, + len: usize, + flags: SpliceFlags, +) -> io::Result { + backend::io::syscalls::splice(fd_in.as_fd(), off_in, fd_out.as_fd(), off_out, len, flags) +} + +/// `vmsplice(fd, bufs, flags)`—Transfer data between memory and a pipe. +/// +/// If `fd` is the write end of the pipe, +/// the function maps the memory pointer at by `bufs` to the pipe. +/// +/// If `fd` is the read end of the pipe, +/// the function writes data from the pipe to said memory. +/// +/// # Safety +/// +/// If the memory must not be mutated (such as when `bufs` were originally immutable slices), +/// it is up to the caller to ensure that the write end of the pipe is placed in `fd`. +/// +/// Additionally if `SpliceFlags::GIFT` is set, the caller must also ensure +/// that the contents of `bufs` in never modified following the call, +/// and that all of the pointers in `bufs` are page aligned, +/// and the lengths are multiples of a page size in bytes. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/vmsplice.2.html +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub unsafe fn vmsplice( + fd: PipeFd, + bufs: &[io::IoSliceRaw], + flags: SpliceFlags, +) -> io::Result { + backend::io::syscalls::vmsplice(fd.as_fd(), bufs, flags) } diff --git a/vendor/rustix/src/io/poll.rs b/vendor/rustix/src/io/poll.rs index efa25045c..01f625af2 100644 --- a/vendor/rustix/src/io/poll.rs +++ b/vendor/rustix/src/io/poll.rs @@ -1,6 +1,6 @@ -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::io::poll_fd::{PollFd, PollFlags}; +pub use backend::io::poll_fd::{PollFd, PollFlags}; /// `poll(self.fds, timeout)` /// @@ -16,5 +16,5 @@ pub use imp::io::poll_fd::{PollFd, PollFlags}; /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll #[inline] pub fn poll(fds: &mut [PollFd<'_>], timeout: i32) -> io::Result { - imp::io::syscalls::poll(fds, timeout) + backend::io::syscalls::poll(fds, timeout) } diff --git a/vendor/rustix/src/io/procfs.rs b/vendor/rustix/src/io/procfs.rs index a947a4e06..c6eeb08e0 100644 --- a/vendor/rustix/src/io/procfs.rs +++ b/vendor/rustix/src/io/procfs.rs @@ -16,15 +16,15 @@ //! namespace. So with the checking here, they may fail, but they won't be able //! to succeed with bogus results. -use crate::fd::{AsFd, BorrowedFd}; +use crate::fd::{AsFd, BorrowedFd, OwnedFd}; use crate::ffi::CStr; use crate::fs::{ cwd, fstat, fstatfs, major, openat, renameat, Dir, FileType, Mode, OFlags, Stat, PROC_SUPER_MAGIC, }; -use crate::io::{self, OwnedFd}; +use crate::io; use crate::path::DecInt; -use crate::process::{getgid, getpid, getuid, Gid, RawGid, RawUid, Uid}; +use crate::process::getpid; #[cfg(feature = "rustc-dep-of-std")] use core::lazy::OnceCell; #[cfg(not(feature = "rustc-dep-of-std"))] @@ -47,11 +47,9 @@ fn check_proc_entry( kind: Kind, entry: BorrowedFd<'_>, proc_stat: Option<&Stat>, - uid: RawUid, - gid: RawGid, ) -> io::Result { let entry_stat = fstat(entry)?; - check_proc_entry_with_stat(kind, entry, entry_stat, proc_stat, uid, gid) + check_proc_entry_with_stat(kind, entry, entry_stat, proc_stat) } /// Check a subdirectory of "/proc" for anomalies, using the provided `Stat`. @@ -60,8 +58,6 @@ fn check_proc_entry_with_stat( entry: BorrowedFd<'_>, entry_stat: Stat, proc_stat: Option<&Stat>, - uid: RawUid, - gid: RawGid, ) -> io::Result { // Check the filesystem magic. check_procfs(entry)?; @@ -72,13 +68,6 @@ fn check_proc_entry_with_stat( Kind::File => check_proc_file(&entry_stat, proc_stat)?, } - // Check the ownership of the directory. We can't do that for the toplevel - // "/proc" though, because in e.g. a user namespace scenario, root outside - // the container may be mapped to another uid like `nobody`. - if !matches!(kind, Kind::Proc) && (entry_stat.st_uid, entry_stat.st_gid) != (uid, gid) { - return Err(io::Errno::NOTSUP); - } - // "/proc" directories are typically mounted r-xr-xr-x. // "/proc/self/fd" is r-x------. Allow them to have fewer permissions, but // not more. @@ -207,6 +196,7 @@ fn is_mountpoint(file: BorrowedFd<'_>) -> bool { /// Open a directory in `/proc`, mapping all errors to `io::Errno::NOTSUP`. fn proc_opendirat(dirfd: Fd, path: P) -> io::Result { // We could add `PATH`|`NOATIME` here but Linux 2.6.32 doesn't support it. + // Also for `NOATIME` see the comment in `open_and_check_file`. let oflags = OFlags::NOFOLLOW | OFlags::DIRECTORY | OFlags::CLOEXEC | OFlags::NOCTTY; openat(dirfd, path, oflags, Mode::empty()).map_err(|_err| io::Errno::NOTSUP) } @@ -229,14 +219,8 @@ fn proc() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { PROC.get_or_try_init(|| { // Open "/proc". let proc = proc_opendirat(cwd(), cstr!("/proc"))?; - let proc_stat = check_proc_entry( - Kind::Proc, - proc.as_fd(), - None, - Uid::ROOT.as_raw(), - Gid::ROOT.as_raw(), - ) - .map_err(|_err| io::Errno::NOTSUP)?; + let proc_stat = + check_proc_entry(Kind::Proc, proc.as_fd(), None).map_err(|_err| io::Errno::NOTSUP)?; Ok(new_static_fd(proc, proc_stat)) }) @@ -260,19 +244,13 @@ fn proc_self() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { .get_or_try_init(|| { let (proc, proc_stat) = proc()?; - let (uid, gid, pid) = (getuid(), getgid(), getpid()); + let pid = getpid(); // Open "/proc/self". Use our pid to compute the name rather than literally // using "self", as "self" is a symlink. let proc_self = proc_opendirat(proc, DecInt::new(pid.as_raw_nonzero().get()))?; - let proc_self_stat = check_proc_entry( - Kind::Pid, - proc_self.as_fd(), - Some(proc_stat), - uid.as_raw(), - gid.as_raw(), - ) - .map_err(|_err| io::Errno::NOTSUP)?; + let proc_self_stat = check_proc_entry(Kind::Pid, proc_self.as_fd(), Some(proc_stat)) + .map_err(|_err| io::Errno::NOTSUP)?; Ok(new_static_fd(proc_self, proc_self_stat)) }) @@ -297,18 +275,13 @@ pub fn proc_self_fd() -> io::Result> { .get_or_try_init(|| { let (_, proc_stat) = proc()?; - let (proc_self, proc_self_stat) = proc_self()?; + let (proc_self, _proc_self_stat) = proc_self()?; // Open "/proc/self/fd". let proc_self_fd = proc_opendirat(proc_self, cstr!("fd"))?; - let proc_self_fd_stat = check_proc_entry( - Kind::Fd, - proc_self_fd.as_fd(), - Some(proc_stat), - proc_self_stat.st_uid, - proc_self_stat.st_gid, - ) - .map_err(|_err| io::Errno::NOTSUP)?; + let proc_self_fd_stat = + check_proc_entry(Kind::Fd, proc_self_fd.as_fd(), Some(proc_stat)) + .map_err(|_err| io::Errno::NOTSUP)?; Ok(new_static_fd(proc_self_fd, proc_self_fd_stat)) }) @@ -333,24 +306,19 @@ fn new_static_fd(fd: OwnedFd, stat: Stat) -> (OwnedFd, Stat) { /// /// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html fn proc_self_fdinfo() -> io::Result<(BorrowedFd<'static>, &'static Stat)> { - static PROC_SELF_FDINFO: OnceCell<(OwnedFd, Stat)> = OnceCell::new(); + static PROC_SELF_FDINFO: StaticFd = StaticFd::new(); PROC_SELF_FDINFO .get_or_try_init(|| { let (_, proc_stat) = proc()?; - let (proc_self, proc_self_stat) = proc_self()?; + let (proc_self, _proc_self_stat) = proc_self()?; // Open "/proc/self/fdinfo". let proc_self_fdinfo = proc_opendirat(proc_self, cstr!("fdinfo"))?; - let proc_self_fdinfo_stat = check_proc_entry( - Kind::Fd, - proc_self_fdinfo.as_fd(), - Some(proc_stat), - proc_self_stat.st_uid, - proc_self_stat.st_gid, - ) - .map_err(|_err| io::Errno::NOTSUP)?; + let proc_self_fdinfo_stat = + check_proc_entry(Kind::Fd, proc_self_fdinfo.as_fd(), Some(proc_stat)) + .map_err(|_err| io::Errno::NOTSUP)?; Ok((proc_self_fdinfo, proc_self_fdinfo_stat)) }) @@ -410,6 +378,21 @@ pub fn proc_self_maps() -> io::Result { proc_self_file(cstr!("maps")) } +/// Returns a handle to a Linux `/proc/self/status` file. +/// +/// This ensures that `/proc/self/status` is `procfs`, that nothing is +/// mounted on top of it, and that it looks normal. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man5/proc.5.html +#[inline] +#[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] +pub fn proc_self_status() -> io::Result { + proc_self_file(cstr!("status")) +} + /// Open a file under `/proc/self`. fn proc_self_file(name: &CStr) -> io::Result { let (proc_self, proc_self_stat) = proc_self()?; @@ -420,9 +403,14 @@ fn proc_self_file(name: &CStr) -> io::Result { fn open_and_check_file(dir: BorrowedFd, dir_stat: &Stat, name: &CStr) -> io::Result { let (_, proc_stat) = proc()?; - let oflags = - OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW | OFlags::NOCTTY | OFlags::NOATIME; - let file = openat(&dir, name, oflags, Mode::empty()).map_err(|_err| io::Errno::NOTSUP)?; + // Don't use `NOATIME`, because it [requires us to own the file], and when + // a process sets itself non-dumpable Linux changes the user:group of its + // `/proc/` files [to root:root]. + // + // [requires us to own the file]: https://man7.org/linux/man-pages/man2/openat.2.html + // [to root:root]: https://man7.org/linux/man-pages/man5/proc.5.html + let oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW | OFlags::NOCTTY; + let file = openat(dir, name, oflags, Mode::empty()).map_err(|_err| io::Errno::NOTSUP)?; let file_stat = fstat(&file)?; // `is_mountpoint` only works on directory mount points, not file mount @@ -455,14 +443,8 @@ fn open_and_check_file(dir: BorrowedFd, dir_stat: &Stat, name: &CStr) -> io::Res && entry.file_name() == name { // We found the file. Proceed to check the file handle. - let _ = check_proc_entry_with_stat( - Kind::File, - file.as_fd(), - file_stat, - Some(proc_stat), - dir_stat.st_uid, - dir_stat.st_gid, - )?; + let _ = + check_proc_entry_with_stat(Kind::File, file.as_fd(), file_stat, Some(proc_stat))?; found_file = true; } else if entry.ino() == dir_stat.st_ino diff --git a/vendor/rustix/src/io/read_write.rs b/vendor/rustix/src/io/read_write.rs index abb96e9c1..1a4d37b65 100644 --- a/vendor/rustix/src/io/read_write.rs +++ b/vendor/rustix/src/io/read_write.rs @@ -1,19 +1,19 @@ //! `read` and `write`, optionally positioned, optionally vectored -use crate::{imp, io}; -use imp::fd::AsFd; +use crate::{backend, io}; +use backend::fd::AsFd; // Declare `IoSlice` and `IoSliceMut`. #[cfg(not(windows))] #[cfg(not(feature = "std"))] -pub use imp::io::io_slice::{IoSlice, IoSliceMut}; +pub use backend::io::io_slice::{IoSlice, IoSliceMut}; #[cfg(not(windows))] #[cfg(feature = "std")] pub use std::io::{IoSlice, IoSliceMut}; /// `RWF_*` constants for use with [`preadv2`] and [`pwritev2`]. #[cfg(any(target_os = "android", target_os = "linux"))] -pub use imp::io::types::ReadWriteFlags; +pub use backend::io::types::ReadWriteFlags; /// `read(fd, buf)`—Reads from a stream. /// @@ -27,7 +27,7 @@ pub use imp::io::types::ReadWriteFlags; /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/read.2.html #[inline] pub fn read(fd: Fd, buf: &mut [u8]) -> io::Result { - imp::io::syscalls::read(fd.as_fd(), buf) + backend::io::syscalls::read(fd.as_fd(), buf) } /// `write(fd, buf)`—Writes to a stream. @@ -42,7 +42,7 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> io::Result { /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/write.2.html #[inline] pub fn write(fd: Fd, buf: &[u8]) -> io::Result { - imp::io::syscalls::write(fd.as_fd(), buf) + backend::io::syscalls::write(fd.as_fd(), buf) } /// `pread(fd, buf, offset)`—Reads from a file at a given position. @@ -57,7 +57,7 @@ pub fn write(fd: Fd, buf: &[u8]) -> io::Result { /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pread.2.html #[inline] pub fn pread(fd: Fd, buf: &mut [u8], offset: u64) -> io::Result { - imp::io::syscalls::pread(fd.as_fd(), buf, offset) + backend::io::syscalls::pread(fd.as_fd(), buf, offset) } /// `pwrite(fd, bufs)`—Writes to a file at a given position. @@ -72,7 +72,7 @@ pub fn pread(fd: Fd, buf: &mut [u8], offset: u64) -> io::Result /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/pwrite.2.html #[inline] pub fn pwrite(fd: Fd, buf: &[u8], offset: u64) -> io::Result { - imp::io::syscalls::pwrite(fd.as_fd(), buf, offset) + backend::io::syscalls::pwrite(fd.as_fd(), buf, offset) } /// `readv(fd, bufs)`—Reads from a stream into multiple buffers. @@ -87,7 +87,7 @@ pub fn pwrite(fd: Fd, buf: &[u8], offset: u64) -> io::Result { /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/readv.2.html #[inline] pub fn readv(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - imp::io::syscalls::readv(fd.as_fd(), bufs) + backend::io::syscalls::readv(fd.as_fd(), bufs) } /// `writev(fd, bufs)`—Writes to a stream from multiple buffers. @@ -102,7 +102,7 @@ pub fn readv(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result /// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/writev.2.html #[inline] pub fn writev(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result { - imp::io::syscalls::writev(fd.as_fd(), bufs) + backend::io::syscalls::writev(fd.as_fd(), bufs) } /// `preadv(fd, bufs, offset)`—Reads from a file at a given position into @@ -112,10 +112,10 @@ pub fn writev(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result { /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/preadv.2.html -#[cfg(not(target_os = "redox"))] +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))] #[inline] pub fn preadv(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { - imp::io::syscalls::preadv(fd.as_fd(), bufs, offset) + backend::io::syscalls::preadv(fd.as_fd(), bufs, offset) } /// `pwritev(fd, bufs, offset)`—Writes to a file at a given position from @@ -125,10 +125,10 @@ pub fn preadv(fd: Fd, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io: /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man2/pwritev.2.html -#[cfg(not(target_os = "redox"))] +#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "solaris")))] #[inline] pub fn pwritev(fd: Fd, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { - imp::io::syscalls::pwritev(fd.as_fd(), bufs, offset) + backend::io::syscalls::pwritev(fd.as_fd(), bufs, offset) } /// `preadv2(fd, bufs, offset, flags)`—Reads data, with several options. @@ -147,7 +147,7 @@ pub fn preadv2( offset: u64, flags: ReadWriteFlags, ) -> io::Result { - imp::io::syscalls::preadv2(fd.as_fd(), bufs, offset, flags) + backend::io::syscalls::preadv2(fd.as_fd(), bufs, offset, flags) } /// `pwritev2(fd, bufs, offset, flags)`—Writes data, with several options. @@ -166,5 +166,5 @@ pub fn pwritev2( offset: u64, flags: ReadWriteFlags, ) -> io::Result { - imp::io::syscalls::pwritev2(fd.as_fd(), bufs, offset, flags) + backend::io::syscalls::pwritev2(fd.as_fd(), bufs, offset, flags) } diff --git a/vendor/rustix/src/io/stdio.rs b/vendor/rustix/src/io/stdio.rs index f9d03a701..caa8183c2 100644 --- a/vendor/rustix/src/io/stdio.rs +++ b/vendor/rustix/src/io/stdio.rs @@ -8,9 +8,9 @@ //! stdio streams. #![allow(unsafe_code)] -use crate::imp; -use crate::io::OwnedFd; -use imp::fd::{BorrowedFd, FromRawFd, RawFd}; +use crate::backend; +use crate::fd::OwnedFd; +use backend::fd::{BorrowedFd, FromRawFd, RawFd}; /// `STDIN_FILENO`—Standard input, borrowed. /// @@ -36,9 +36,10 @@ use imp::fd::{BorrowedFd, FromRawFd, RawFd}; /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html /// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html +#[doc(alias = "STDIN_FILENO")] #[inline] -pub unsafe fn stdin() -> BorrowedFd<'static> { - BorrowedFd::borrow_raw(imp::io::types::STDIN_FILENO as RawFd) +pub const unsafe fn stdin() -> BorrowedFd<'static> { + BorrowedFd::borrow_raw(backend::io::types::STDIN_FILENO as RawFd) } /// `STDIN_FILENO`—Standard input, owned. @@ -65,11 +66,10 @@ pub unsafe fn stdin() -> BorrowedFd<'static> { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html /// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html +#[doc(alias = "STDIN_FILENO")] #[inline] pub unsafe fn take_stdin() -> OwnedFd { - OwnedFd::from(imp::fd::OwnedFd::from_raw_fd( - imp::io::types::STDIN_FILENO as RawFd, - )) + backend::fd::OwnedFd::from_raw_fd(backend::io::types::STDIN_FILENO as RawFd) } /// `STDOUT_FILENO`—Standard output, borrowed. @@ -97,9 +97,10 @@ pub unsafe fn take_stdin() -> OwnedFd { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdout.html /// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html +#[doc(alias = "STDOUT_FILENO")] #[inline] -pub unsafe fn stdout() -> BorrowedFd<'static> { - BorrowedFd::borrow_raw(imp::io::types::STDOUT_FILENO as RawFd) +pub const unsafe fn stdout() -> BorrowedFd<'static> { + BorrowedFd::borrow_raw(backend::io::types::STDOUT_FILENO as RawFd) } /// `STDOUT_FILENO`—Standard output, owned. @@ -126,11 +127,10 @@ pub unsafe fn stdout() -> BorrowedFd<'static> { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdout.html /// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html +#[doc(alias = "STDOUT_FILENO")] #[inline] pub unsafe fn take_stdout() -> OwnedFd { - OwnedFd::from(imp::fd::OwnedFd::from_raw_fd( - imp::io::types::STDOUT_FILENO as RawFd, - )) + backend::fd::OwnedFd::from_raw_fd(backend::io::types::STDOUT_FILENO as RawFd) } /// `STDERR_FILENO`—Standard error, borrowed. @@ -157,9 +157,10 @@ pub unsafe fn take_stdout() -> OwnedFd { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stderr.html /// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html +#[doc(alias = "STDERR_FILENO")] #[inline] -pub unsafe fn stderr() -> BorrowedFd<'static> { - BorrowedFd::borrow_raw(imp::io::types::STDERR_FILENO as RawFd) +pub const unsafe fn stderr() -> BorrowedFd<'static> { + BorrowedFd::borrow_raw(backend::io::types::STDERR_FILENO as RawFd) } /// `STDERR_FILENO`—Standard error, owned. @@ -186,9 +187,68 @@ pub unsafe fn stderr() -> BorrowedFd<'static> { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stderr.html /// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html +#[doc(alias = "STDERR_FILENO")] #[inline] pub unsafe fn take_stderr() -> OwnedFd { - OwnedFd::from(imp::fd::OwnedFd::from_raw_fd( - imp::io::types::STDERR_FILENO as RawFd, - )) + backend::fd::OwnedFd::from_raw_fd(backend::io::types::STDERR_FILENO as RawFd) +} + +/// `STDIN_FILENO`—Standard input, raw. +/// +/// This is similar to [`stdin`], however it returns a `RawFd`. +/// +/// # Other hazards +/// +/// This has the same hazards as [`stdin`]. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html +/// [Linux]: https://man7.org/linux/man-pages/man3/stdin.3.html +#[doc(alias = "STDIN_FILENO")] +#[inline] +pub const fn raw_stdin() -> RawFd { + backend::io::types::STDIN_FILENO as RawFd +} + +/// `STDOUT_FILENO`—Standard output, raw. +/// +/// This is similar to [`stdout`], however it returns a `RawFd`. +/// +/// # Other hazards +/// +/// This has the same hazards as [`stdout`]. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdout.html +/// [Linux]: https://man7.org/linux/man-pages/man3/stdout.3.html +#[doc(alias = "STDOUT_FILENO")] +#[inline] +pub const fn raw_stdout() -> RawFd { + backend::io::types::STDOUT_FILENO as RawFd +} + +/// `STDERR_FILENO`—Standard error, raw. +/// +/// This is similar to [`stderr`], however it returns a `RawFd`. +/// +/// # Other hazards +/// +/// This has the same hazards as [`stderr`]. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/stderr.html +/// [Linux]: https://man7.org/linux/man-pages/man3/stderr.3.html +#[doc(alias = "STDERR_FILENO")] +#[inline] +pub const fn raw_stderr() -> RawFd { + backend::io::types::STDERR_FILENO as RawFd } diff --git a/vendor/rustix/src/io_uring.rs b/vendor/rustix/src/io_uring.rs index 13f3bbd10..2f67107ba 100644 --- a/vendor/rustix/src/io_uring.rs +++ b/vendor/rustix/src/io_uring.rs @@ -19,9 +19,8 @@ //! [io_uring]: https://en.wikipedia.org/wiki/Io_uring #![allow(unsafe_code)] -use crate::fd::{AsFd, BorrowedFd, RawFd}; -use crate::imp; -use crate::io::{self, OwnedFd}; +use crate::fd::{AsFd, BorrowedFd, OwnedFd, RawFd}; +use crate::{backend, io}; use core::ffi::c_void; use core::ptr::null_mut; use linux_raw_sys::general as sys; @@ -35,7 +34,7 @@ use linux_raw_sys::general as sys; /// [Linux]: https://man.archlinux.org/man/io_uring_setup.2.en #[inline] pub fn io_uring_setup(entries: u32, params: &mut io_uring_params) -> io::Result { - imp::io_uring::syscalls::io_uring_setup(entries, params) + backend::io_uring::syscalls::io_uring_setup(entries, params) } /// `io_uring_register(fd, opcode, arg, nr_args)`—Register files or user @@ -58,7 +57,7 @@ pub unsafe fn io_uring_register( arg: *const c_void, nr_args: u32, ) -> io::Result<()> { - imp::io_uring::syscalls::io_uring_register(fd.as_fd(), opcode, arg, nr_args) + backend::io_uring::syscalls::io_uring_register(fd.as_fd(), opcode, arg, nr_args) } /// `io_uring_enter(fd, to_submit, min_complete, flags, arg, size)`—Initiate @@ -83,7 +82,14 @@ pub unsafe fn io_uring_enter( arg: *const c_void, size: usize, ) -> io::Result { - imp::io_uring::syscalls::io_uring_enter(fd.as_fd(), to_submit, min_complete, flags, arg, size) + backend::io_uring::syscalls::io_uring_enter( + fd.as_fd(), + to_submit, + min_complete, + flags, + arg, + size, + ) } bitflags::bitflags! { @@ -545,7 +551,6 @@ pub const IORING_OFF_SQES: u64 = sys::IORING_OFF_SQES as _; /// `IORING_REGISTER_FILES_SKIP` #[inline] #[doc(alias = "IORING_REGISTER_FILES_SKIP")] -#[allow(unsafe_code)] pub const fn io_uring_register_files_skip() -> BorrowedFd<'static> { let files_skip = sys::IORING_REGISTER_FILES_SKIP as RawFd; diff --git a/vendor/rustix/src/lib.rs b/vendor/rustix/src/lib.rs index ca7c6cd4e..f8bf0729f 100644 --- a/vendor/rustix/src/lib.rs +++ b/vendor/rustix/src/lib.rs @@ -117,6 +117,12 @@ )] #![cfg_attr(asm_experimental_arch, feature(asm_experimental_arch))] #![cfg_attr(not(feature = "all-apis"), allow(dead_code))] +// Clamp depends on Rust 1.50 which is newer than our MSRV. +#![allow(clippy::manual_clamp)] +// It is common in linux and libc APIs for types to vary between platforms. +#![allow(clippy::unnecessary_cast)] +// It is common in linux and libc APIs for types to vary between platforms. +#![allow(clippy::useless_conversion)] #[cfg(not(feature = "rustc-dep-of-std"))] extern crate alloc; @@ -130,27 +136,20 @@ pub(crate) mod const_assert; pub(crate) mod utils; // Pick the backend implementation to use. -#[cfg_attr(libc, path = "imp/libc/mod.rs")] -#[cfg_attr(linux_raw, path = "imp/linux_raw/mod.rs")] -#[cfg_attr(wasi, path = "imp/wasi/mod.rs")] -mod imp; +#[cfg_attr(libc, path = "backend/libc/mod.rs")] +#[cfg_attr(linux_raw, path = "backend/linux_raw/mod.rs")] +#[cfg_attr(wasi, path = "backend/wasi/mod.rs")] +mod backend; /// Export the `*Fd` types and traits that are used in rustix's public API. /// /// Users can use this to avoid needing to import anything else to use the same /// versions of these types and traits. -/// -/// Rustix APIs that use `OwnedFd` use [`rustix::io::OwnedFd`] instead, which -/// allows rustix to implement `close` for them. -/// -/// [`rustix::io::OwnedFd`]: crate::io::OwnedFd pub mod fd { - use super::imp; - pub use imp::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; + use super::backend; #[cfg(windows)] - pub use imp::fd::{AsSocket, FromSocket, IntoSocket}; - #[cfg(feature = "std")] - pub use imp::fd::{FromFd, IntoFd}; + pub use backend::fd::AsSocket; + pub use backend::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; } // The public API modules. @@ -213,9 +212,6 @@ pub mod runtime; // for API features that aren't enabled, declare them as `pub(crate)` so // that they're not public, but still available for internal use. -#[cfg(not(windows))] -#[cfg(not(feature = "fs"))] -pub(crate) mod fs; #[cfg(not(windows))] #[cfg(all( not(feature = "param"), diff --git a/vendor/rustix/src/mm/madvise.rs b/vendor/rustix/src/mm/madvise.rs index 317c3b515..cf13f951b 100644 --- a/vendor/rustix/src/mm/madvise.rs +++ b/vendor/rustix/src/mm/madvise.rs @@ -6,10 +6,10 @@ //! mutate the memory or have other side effects. #![allow(unsafe_code)] -use crate::{imp, io}; +use crate::{backend, io}; use core::ffi::c_void; -pub use imp::mm::types::Advice; +pub use backend::mm::types::Advice; /// `posix_madvise(addr, len, advice)`—Declares an expected access pattern /// for a memory-mapped file. @@ -31,5 +31,5 @@ pub use imp::mm::types::Advice; #[inline] #[doc(alias = "posix_madvise")] pub unsafe fn madvise(addr: *mut c_void, len: usize, advice: Advice) -> io::Result<()> { - imp::mm::syscalls::madvise(addr, len, advice) + backend::mm::syscalls::madvise(addr, len, advice) } diff --git a/vendor/rustix/src/mm/mmap.rs b/vendor/rustix/src/mm/mmap.rs index 7be02464e..31d3a77b3 100644 --- a/vendor/rustix/src/mm/mmap.rs +++ b/vendor/rustix/src/mm/mmap.rs @@ -6,15 +6,15 @@ //! semantics and are wildly unsafe. #![allow(unsafe_code)] -use crate::{imp, io}; +use crate::{backend, io}; +use backend::fd::AsFd; use core::ffi::c_void; -use imp::fd::AsFd; #[cfg(any(target_os = "android", target_os = "linux"))] -pub use imp::mm::types::MlockFlags; +pub use backend::mm::types::MlockFlags; #[cfg(any(linux_raw, all(libc, target_os = "linux")))] -pub use imp::mm::types::MremapFlags; -pub use imp::mm::types::{MapFlags, MprotectFlags, ProtFlags}; +pub use backend::mm::types::MremapFlags; +pub use backend::mm::types::{MapFlags, MprotectFlags, ProtFlags}; /// `mmap(ptr, len, prot, flags, fd, offset)`—Create a file-backed memory /// mapping. @@ -41,7 +41,7 @@ pub unsafe fn mmap( fd: Fd, offset: u64, ) -> io::Result<*mut c_void> { - imp::mm::syscalls::mmap(ptr, len, prot, flags, fd.as_fd(), offset) + backend::mm::syscalls::mmap(ptr, len, prot, flags, fd.as_fd(), offset) } /// `mmap(ptr, len, prot, MAP_ANONYMOUS | flags, -1, 0)`—Create an anonymous @@ -67,7 +67,7 @@ pub unsafe fn mmap_anonymous( prot: ProtFlags, flags: MapFlags, ) -> io::Result<*mut c_void> { - imp::mm::syscalls::mmap_anonymous(ptr, len, prot, flags) + backend::mm::syscalls::mmap_anonymous(ptr, len, prot, flags) } /// `munmap(ptr, len)` @@ -84,7 +84,7 @@ pub unsafe fn mmap_anonymous( /// [Linux]: https://man7.org/linux/man-pages/man2/munmap.2.html #[inline] pub unsafe fn munmap(ptr: *mut c_void, len: usize) -> io::Result<()> { - imp::mm::syscalls::munmap(ptr, len) + backend::mm::syscalls::munmap(ptr, len) } /// `mremap(old_address, old_size, new_size, flags)`—Resize, modify, @@ -109,7 +109,7 @@ pub unsafe fn mremap( new_size: usize, flags: MremapFlags, ) -> io::Result<*mut c_void> { - imp::mm::syscalls::mremap(old_address, old_size, new_size, flags) + backend::mm::syscalls::mremap(old_address, old_size, new_size, flags) } /// `mremap(old_address, old_size, new_size, MREMAP_FIXED | flags)`—Resize, @@ -136,7 +136,7 @@ pub unsafe fn mremap_fixed( flags: MremapFlags, new_address: *mut c_void, ) -> io::Result<*mut c_void> { - imp::mm::syscalls::mremap_fixed(old_address, old_size, new_size, flags, new_address) + backend::mm::syscalls::mremap_fixed(old_address, old_size, new_size, flags, new_address) } /// `mprotect(ptr, len, flags)` @@ -153,7 +153,7 @@ pub unsafe fn mremap_fixed( /// [Linux]: https://man7.org/linux/man-pages/man2/mprotect.2.html #[inline] pub unsafe fn mprotect(ptr: *mut c_void, len: usize, flags: MprotectFlags) -> io::Result<()> { - imp::mm::syscalls::mprotect(ptr, len, flags) + backend::mm::syscalls::mprotect(ptr, len, flags) } /// `mlock(ptr, len)`—Lock memory into RAM. @@ -177,7 +177,7 @@ pub unsafe fn mprotect(ptr: *mut c_void, len: usize, flags: MprotectFlags) -> io /// [Linux]: https://man7.org/linux/man-pages/man2/mlock.2.html #[inline] pub unsafe fn mlock(ptr: *mut c_void, len: usize) -> io::Result<()> { - imp::mm::syscalls::mlock(ptr, len) + backend::mm::syscalls::mlock(ptr, len) } /// `mlock2(ptr, len, flags)`—Lock memory into RAM, with @@ -204,7 +204,7 @@ pub unsafe fn mlock(ptr: *mut c_void, len: usize) -> io::Result<()> { #[inline] #[doc(alias = "mlock2")] pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io::Result<()> { - imp::mm::syscalls::mlock_with(ptr, len, flags) + backend::mm::syscalls::mlock_with(ptr, len, flags) } /// `munlock(ptr, len)`—Unlock memory. @@ -227,5 +227,5 @@ pub unsafe fn mlock_with(ptr: *mut c_void, len: usize, flags: MlockFlags) -> io: /// [Linux]: https://man7.org/linux/man-pages/man2/munlock.2.html #[inline] pub unsafe fn munlock(ptr: *mut c_void, len: usize) -> io::Result<()> { - imp::mm::syscalls::munlock(ptr, len) + backend::mm::syscalls::munlock(ptr, len) } diff --git a/vendor/rustix/src/mm/msync.rs b/vendor/rustix/src/mm/msync.rs index 7117a5067..3ca418fc4 100644 --- a/vendor/rustix/src/mm/msync.rs +++ b/vendor/rustix/src/mm/msync.rs @@ -6,10 +6,10 @@ //! memory or have other side effects. #![allow(unsafe_code)] -use crate::{imp, io}; +use crate::{backend, io}; use core::ffi::c_void; -pub use imp::mm::types::MsyncFlags; +pub use backend::mm::types::MsyncFlags; /// `msync(addr, len, flags)`—Synchronizes a memory-mapping with its backing /// storage. @@ -28,5 +28,5 @@ pub use imp::mm::types::MsyncFlags; /// [Linux `msync`]: https://man7.org/linux/man-pages/man2/msync.2.html #[inline] pub unsafe fn msync(addr: *mut c_void, len: usize, flags: MsyncFlags) -> io::Result<()> { - imp::mm::syscalls::msync(addr, len, flags) + backend::mm::syscalls::msync(addr, len, flags) } diff --git a/vendor/rustix/src/mm/userfaultfd.rs b/vendor/rustix/src/mm/userfaultfd.rs index 65b4a0dd8..201d54772 100644 --- a/vendor/rustix/src/mm/userfaultfd.rs +++ b/vendor/rustix/src/mm/userfaultfd.rs @@ -6,10 +6,10 @@ //! observe and manipulate process memory in magical ways. #![allow(unsafe_code)] -use crate::imp; -use crate::io::{self, OwnedFd}; +use crate::fd::OwnedFd; +use crate::{backend, io}; -pub use imp::mm::types::UserfaultfdFlags; +pub use backend::mm::types::UserfaultfdFlags; /// `userfaultfd(flags)` /// @@ -26,5 +26,5 @@ pub use imp::mm::types::UserfaultfdFlags; /// [Linux userfaultfd]: https://www.kernel.org/doc/Documentation/vm/userfaultfd.txt #[inline] pub unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result { - imp::mm::syscalls::userfaultfd(flags) + backend::mm::syscalls::userfaultfd(flags) } diff --git a/vendor/rustix/src/net/addr.rs b/vendor/rustix/src/net/addr.rs index 59f4a55d7..af9e51a8a 100644 --- a/vendor/rustix/src/net/addr.rs +++ b/vendor/rustix/src/net/addr.rs @@ -1,22 +1,17 @@ //! The following is derived from Rust's -//! library/std/src/net/addr.rs at revision -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. +//! library/std/src/net/socket_addr.rs at revision +//! f7e8ba28a4785e698a55fb95e4b3e803302de0ff. //! -//! This defines `SocketAddr`, `SocketAddrV4`, and `SocketAddrV6`. These are -//! conceptually platform-independent, however in practice OS's have differing -//! representations. +//! All code in this file is licensed MIT or Apache 2.0 at your option. +//! +//! This defines `SocketAddr`, `SocketAddrV4`, and `SocketAddrV6` in a +//! platform-independent way. It is not the native representation. #![allow(unsafe_code)] -use crate::imp::c; -use crate::imp::net::ext::{ - in6_addr_s6_addr, in_addr_s_addr, sockaddr_in6_new, sockaddr_in6_sin6_scope_id, - sockaddr_in6_sin6_scope_id_mut, -}; use crate::net::ip::{IpAddr, Ipv4Addr, Ipv6Addr}; use core::cmp::Ordering; use core::hash; -use core::mem; /// An internet socket address, either IPv4 or IPv6. /// @@ -76,12 +71,11 @@ pub enum SocketAddr { /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); /// assert_eq!(socket.port(), 8080); /// ``` -#[derive(Copy)] +#[derive(Copy, Clone, Eq, PartialEq)] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] pub struct SocketAddrV4 { - // Do not assume that this struct is implemented as the underlying system representation. - // The memory layout is not part of the stable interface that std exposes. - pub(crate) inner: c::sockaddr_in, + ip: Ipv4Addr, + port: u16, } /// An IPv6 socket address. @@ -110,12 +104,13 @@ pub struct SocketAddrV4 { /// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)); /// assert_eq!(socket.port(), 8080); /// ``` -#[derive(Copy)] +#[derive(Copy, Clone, Eq, PartialEq)] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] pub struct SocketAddrV6 { - // Do not assume that this struct is implemented as the underlying system representation. - // The memory layout is not part of the stable interface that std exposes. - pub(crate) inner: c::sockaddr_in6, + ip: Ipv6Addr, + port: u16, + flowinfo: u32, + scope_id: u32, } impl SocketAddr { @@ -134,34 +129,14 @@ impl SocketAddr { /// ``` #[cfg_attr(staged_api, stable(feature = "ip_addr", since = "1.7.0"))] #[must_use] - pub fn new(ip: IpAddr, port: u16) -> SocketAddr { - match ip { - IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)), - IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)), - } - } - - /// Returns the IP address associated with this socket address. - /// - /// # Examples - /// - /// ``` - /// use std::net::{IpAddr, Ipv4Addr, SocketAddr}; - /// - /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); - /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); - /// ``` - #[cfg(const_raw_ptr_deref)] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "ip_addr", since = "1.7.0"))] #[cfg_attr( staged_api, rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] - pub const fn ip(&self) -> IpAddr { - match *self { - SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()), - SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()), + pub const fn new(ip: IpAddr, port: u16) -> SocketAddr { + match ip { + IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)), + IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)), } } @@ -175,14 +150,13 @@ impl SocketAddr { /// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); /// assert_eq!(socket.ip(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); /// ``` - #[cfg(not(const_raw_ptr_deref))] #[must_use] #[cfg_attr(staged_api, stable(feature = "ip_addr", since = "1.7.0"))] #[cfg_attr( staged_api, rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] - pub fn ip(&self) -> IpAddr { + pub const fn ip(&self) -> IpAddr { match *self { SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()), SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()), @@ -317,38 +291,12 @@ impl SocketAddrV4 { /// ``` #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use] - pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 { - SocketAddrV4 { - inner: c::sockaddr_in { - sin_family: c::AF_INET as c::sa_family_t, - sin_port: port.to_be(), - sin_addr: ip.inner, - ..unsafe { mem::zeroed() } - }, - } - } - - /// Returns the IP address associated with this socket address. - /// - /// # Examples - /// - /// ``` - /// use std::net::{SocketAddrV4, Ipv4Addr}; - /// - /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); - /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); - /// ``` - #[cfg(const_raw_ptr_deref)] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[cfg_attr( staged_api, rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] - pub const fn ip(&self) -> &Ipv4Addr { - // SAFETY: `Ipv4Addr` is `#[repr(C)] struct { _: in_addr; }`. - // It is safe to cast from `&in_addr` to `&Ipv4Addr`. - unsafe { &*(&self.inner.sin_addr as *const c::in_addr as *const Ipv4Addr) } + pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 { + SocketAddrV4 { ip, port } } /// Returns the IP address associated with this socket address. @@ -361,17 +309,14 @@ impl SocketAddrV4 { /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); /// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); /// ``` - #[cfg(not(const_raw_ptr_deref))] #[must_use] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[cfg_attr( staged_api, rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] - pub fn ip(&self) -> &Ipv4Addr { - // SAFETY: `Ipv4Addr` is `#[repr(C)] struct { _: in_addr; }`. - // It is safe to cast from `&in_addr` to `&Ipv4Addr`. - unsafe { &*(&self.inner.sin_addr as *const c::in_addr as *const Ipv4Addr) } + pub const fn ip(&self) -> &Ipv4Addr { + &self.ip } /// Changes the IP address associated with this socket address. @@ -387,7 +332,7 @@ impl SocketAddrV4 { /// ``` #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))] pub fn set_ip(&mut self, new_ip: Ipv4Addr) { - self.inner.sin_addr = new_ip.inner + self.ip = new_ip; } /// Returns the port number associated with this socket address. @@ -407,7 +352,7 @@ impl SocketAddrV4 { rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] pub const fn port(&self) -> u16 { - u16::from_be(self.inner.sin_port) + self.port } /// Changes the port number associated with this socket address. @@ -423,7 +368,7 @@ impl SocketAddrV4 { /// ``` #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))] pub fn set_port(&mut self, new_port: u16) { - self.inner.sin_port = new_port.to_be(); + self.port = new_port; } } @@ -446,37 +391,17 @@ impl SocketAddrV6 { /// ``` #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use] - pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 { - SocketAddrV6 { - inner: sockaddr_in6_new( - c::AF_INET6 as c::sa_family_t, - port.to_be(), - flowinfo, - ip.inner, - scope_id, - ), - } - } - - /// Returns the IP address associated with this socket address. - /// - /// # Examples - /// - /// ``` - /// use std::net::{SocketAddrV6, Ipv6Addr}; - /// - /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0); - /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); - /// ``` - #[cfg(const_raw_ptr_deref)] - #[must_use] - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[cfg_attr( staged_api, rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] - pub const fn ip(&self) -> &Ipv6Addr { - unsafe { &*(&self.inner.sin6_addr as *const c::in6_addr as *const Ipv6Addr) } + pub const fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 { + SocketAddrV6 { + ip, + port, + flowinfo, + scope_id, + } } /// Returns the IP address associated with this socket address. @@ -489,15 +414,14 @@ impl SocketAddrV6 { /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0); /// assert_eq!(socket.ip(), &Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); /// ``` - #[cfg(not(const_raw_ptr_deref))] #[must_use] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[cfg_attr( staged_api, rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] - pub fn ip(&self) -> &Ipv6Addr { - unsafe { &*(&self.inner.sin6_addr as *const c::in6_addr as *const Ipv6Addr) } + pub const fn ip(&self) -> &Ipv6Addr { + &self.ip } /// Changes the IP address associated with this socket address. @@ -513,7 +437,7 @@ impl SocketAddrV6 { /// ``` #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))] pub fn set_ip(&mut self, new_ip: Ipv6Addr) { - self.inner.sin6_addr = new_ip.inner + self.ip = new_ip; } /// Returns the port number associated with this socket address. @@ -533,7 +457,7 @@ impl SocketAddrV6 { rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] pub const fn port(&self) -> u16 { - u16::from_be(self.inner.sin6_port) + self.port } /// Changes the port number associated with this socket address. @@ -549,7 +473,7 @@ impl SocketAddrV6 { /// ``` #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))] pub fn set_port(&mut self, new_port: u16) { - self.inner.sin6_port = new_port.to_be(); + self.port = new_port; } /// Returns the flow information associated with this address. @@ -579,7 +503,7 @@ impl SocketAddrV6 { rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] pub const fn flowinfo(&self) -> u32 { - self.inner.sin6_flowinfo + self.flowinfo } /// Changes the flow information associated with this socket address. @@ -597,7 +521,7 @@ impl SocketAddrV6 { /// ``` #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))] pub fn set_flowinfo(&mut self, new_flowinfo: u32) { - self.inner.sin6_flowinfo = new_flowinfo; + self.flowinfo = new_flowinfo; } /// Returns the scope ID associated with this address. @@ -622,7 +546,7 @@ impl SocketAddrV6 { rustc_const_unstable(feature = "const_socketaddr", issue = "82485") )] pub const fn scope_id(&self) -> u32 { - sockaddr_in6_sin6_scope_id(self.inner) + self.scope_id } /// Changes the scope ID associated with this socket address. @@ -640,7 +564,7 @@ impl SocketAddrV6 { /// ``` #[cfg_attr(staged_api, stable(feature = "sockaddr_setters", since = "1.9.0"))] pub fn set_scope_id(&mut self, new_scope_id: u32) { - *sockaddr_in6_sin6_scope_id_mut(&mut self.inner) = new_scope_id; + self.scope_id = new_scope_id; } } @@ -673,40 +597,6 @@ impl> From<(I, u16)> for SocketAddr { } } -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Clone for SocketAddrV4 { - fn clone(&self) -> SocketAddrV4 { - *self - } -} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Clone for SocketAddrV6 { - fn clone(&self) -> SocketAddrV6 { - *self - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl PartialEq for SocketAddrV4 { - fn eq(&self, other: &SocketAddrV4) -> bool { - self.inner.sin_port == other.inner.sin_port - && in_addr_s_addr(self.inner.sin_addr) == in_addr_s_addr(other.inner.sin_addr) - } -} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl PartialEq for SocketAddrV6 { - fn eq(&self, other: &SocketAddrV6) -> bool { - self.inner.sin6_port == other.inner.sin6_port - && in6_addr_s6_addr(self.inner.sin6_addr) == in6_addr_s6_addr(self.inner.sin6_addr) - && self.inner.sin6_flowinfo == other.inner.sin6_flowinfo - && sockaddr_in6_sin6_scope_id(self.inner) == sockaddr_in6_sin6_scope_id(other.inner) - } -} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Eq for SocketAddrV4 {} -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Eq for SocketAddrV6 {} - #[cfg_attr(staged_api, stable(feature = "socketaddr_ordering", since = "1.45.0"))] impl PartialOrd for SocketAddrV4 { fn partial_cmp(&self, other: &SocketAddrV4) -> Option { @@ -742,18 +632,12 @@ impl Ord for SocketAddrV6 { #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] impl hash::Hash for SocketAddrV4 { fn hash(&self, s: &mut H) { - (self.inner.sin_port, in_addr_s_addr(self.inner.sin_addr)).hash(s) + (self.port, self.ip).hash(s) } } #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] impl hash::Hash for SocketAddrV6 { fn hash(&self, s: &mut H) { - ( - self.inner.sin6_port, - &in6_addr_s6_addr(self.inner.sin6_addr), - self.inner.sin6_flowinfo, - sockaddr_in6_sin6_scope_id(self.inner), - ) - .hash(s) + (self.port, &self.ip, self.flowinfo, self.scope_id).hash(s) } } diff --git a/vendor/rustix/src/net/ip.rs b/vendor/rustix/src/net/ip.rs index 7c587cc7a..4d921cc10 100644 --- a/vendor/rustix/src/net/ip.rs +++ b/vendor/rustix/src/net/ip.rs @@ -1,6 +1,8 @@ //! The following is derived from Rust's -//! library/std/src/net/ip.rs at revision -//! dca3f1b786efd27be3b325ed1e01e247aa589c3b. +//! library/std/src/net/ip_addr.rs at revision +//! 14230a7f8e117aa049d3ae661fa00ded7edefc68. +//! +//! All code in this file is licensed MIT or Apache 2.0 at your option. //! //! This defines `IpAddr`, `Ipv4Addr`, and `Ipv6Addr`. Ideally, these should be //! defined in `core`. See [RFC 2832]. @@ -9,10 +11,7 @@ #![allow(unsafe_code)] -use crate::imp::c; -use crate::imp::net::ext::{in6_addr_new, in6_addr_s6_addr, in_addr_new, in_addr_s_addr}; use core::cmp::Ordering; -use core::hash; use core::mem::transmute; /// An IP address, either IPv4 or IPv6. @@ -20,9 +19,6 @@ use core::mem::transmute; /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their /// respective documentation for more details. /// -/// The size of an `IpAddr` instance may vary depending on the target operating -/// system. -/// /// # Examples /// /// ``` @@ -55,9 +51,6 @@ pub enum IpAddr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// -/// The size of an `Ipv4Addr` struct may vary depending on the target operating -/// system. -/// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 /// /// # Textual representation @@ -82,10 +75,10 @@ pub enum IpAddr { /// assert!("0000000.0.0.0".parse::().is_err()); // first octet is a zero in octal /// assert!("0xcb.0x0.0x71.0x00".parse::().is_err()); // all octets are in hex /// ``` -#[derive(Copy)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] pub struct Ipv4Addr { - pub(crate) inner: c::in_addr, + octets: [u8; 4], } /// An IPv6 address. @@ -93,9 +86,6 @@ pub struct Ipv4Addr { /// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291]. /// They are usually represented as eight 16-bit segments. /// -/// The size of an `Ipv6Addr` struct may vary depending on the target operating -/// system. -/// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// /// # Embedding IPv4 Addresses @@ -143,6 +133,8 @@ pub struct Ipv4Addr { /// /// To convert from an IPv4 address to an IPv4-mapped IPv6 address, use [`Ipv4Addr::to_ipv6_mapped`]. /// Use [`Ipv6Addr::to_ipv4`] to convert an IPv4-mapped IPv6 address to the canonical IPv4 address. +/// Note that this will also convert the IPv6 loopback address `::1` to `0.0.0.1`. Use +/// [`Ipv6Addr::to_ipv4_mapped`] to avoid this. /// /// [IETF RFC 4291 Section 2.5.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2 /// @@ -165,10 +157,10 @@ pub struct Ipv4Addr { /// assert_eq!("::1".parse(), Ok(localhost)); /// assert_eq!(localhost.is_loopback(), true); /// ``` -#[derive(Copy)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] pub struct Ipv6Addr { - pub(crate) inner: c::in6_addr, + octets: [u8; 16], } /// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2]. @@ -240,7 +232,10 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)).is_unspecified(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).is_unspecified(), true); /// ``` - #[cfg_attr(staged_api, rustc_const_stable(feature = "const_ip", since = "1.50.0"))] + #[cfg_attr( + staged_api, + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") + )] #[cfg_attr(staged_api, stable(feature = "ip_shared", since = "1.12.0"))] #[must_use] #[inline] @@ -264,7 +259,10 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_loopback(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)).is_loopback(), true); /// ``` - #[cfg_attr(staged_api, rustc_const_stable(feature = "const_ip", since = "1.50.0"))] + #[cfg_attr( + staged_api, + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") + )] #[cfg_attr(staged_api, stable(feature = "ip_shared", since = "1.12.0"))] #[must_use] #[inline] @@ -317,7 +315,10 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(224, 254, 0, 0)).is_multicast(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0)).is_multicast(), true); /// ``` - #[cfg_attr(staged_api, rustc_const_stable(feature = "const_ip", since = "1.50.0"))] + #[cfg_attr( + staged_api, + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") + )] #[cfg_attr(staged_api, stable(feature = "ip_shared", since = "1.12.0"))] #[must_use] #[inline] @@ -398,7 +399,10 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(), false); /// ``` - #[cfg_attr(staged_api, rustc_const_stable(feature = "const_ip", since = "1.50.0"))] + #[cfg_attr( + staged_api, + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") + )] #[cfg_attr(staged_api, stable(feature = "ipaddr_checker", since = "1.16.0"))] #[must_use] #[inline] @@ -419,7 +423,10 @@ impl IpAddr { /// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(), true); /// ``` - #[cfg_attr(staged_api, rustc_const_stable(feature = "const_ip", since = "1.50.0"))] + #[cfg_attr( + staged_api, + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") + )] #[cfg_attr(staged_api, stable(feature = "ipaddr_checker", since = "1.16.0"))] #[must_use] #[inline] @@ -470,16 +477,14 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.32.0") + rustc_const_stable(feature = "const_ip_32", since = "1.32.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use] #[inline] pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { - // `s_addr` is stored as BE on all machine and the array is in BE order. - // So the native endian conversion method is used so that it's never swapped. Ipv4Addr { - inner: in_addr_new(u32::from_ne_bytes([a, b, c, d])), + octets: [a, b, c, d], } } @@ -537,14 +542,13 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use] #[inline] pub const fn octets(&self) -> [u8; 4] { - // This returns the order we want because s_addr is stored in big-endian. - in_addr_s_addr(self.inner).to_ne_bytes() + self.octets } /// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`). @@ -564,13 +568,13 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.32.0") + rustc_const_stable(feature = "const_ip_32", since = "1.32.0") )] #[cfg_attr(staged_api, stable(feature = "ip_shared", since = "1.12.0"))] #[must_use] #[inline] pub const fn is_unspecified(&self) -> bool { - in_addr_s_addr(self.inner) == 0 + u32::from_be_bytes(self.octets) == 0 } /// Returns [`true`] if this is a loopback address (`127.0.0.0/8`). @@ -589,7 +593,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -623,7 +627,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -654,7 +658,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -663,25 +667,31 @@ impl Ipv4Addr { matches!(self.octets(), [169, 254, ..]) } - /// Returns [`true`] if the address appears to be globally routable. - /// See [iana-ipv4-special-registry][ipv4-sr]. + /// Returns [`true`] if the address appears to be globally reachable + /// as specified by the [IANA IPv4 Special-Purpose Address Registry]. + /// Whether or not an address is practically reachable will depend on your network configuration. /// - /// The following return [`false`]: + /// Most IPv4 addresses are globally reachable; + /// unless they are specifically defined as *not* globally reachable. /// - /// - private addresses (see [`Ipv4Addr::is_private()`]) - /// - the loopback address (see [`Ipv4Addr::is_loopback()`]) - /// - the link-local address (see [`Ipv4Addr::is_link_local()`]) - /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`]) - /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`]) - /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole - /// `0.0.0.0/8` block - /// - addresses reserved for future protocols, except - /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable - /// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`] - /// - addresses reserved for networking devices benchmarking (see - /// [`Ipv4Addr::is_benchmarking()`]) + /// Non-exhaustive list of notable addresses that are not globally reachable: /// - /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml + /// - The [unspecified address] ([`is_unspecified`](Ipv4Addr::is_unspecified)) + /// - Addresses reserved for private use ([`is_private`](Ipv4Addr::is_private)) + /// - Addresses in the shared address space ([`is_shared`](Ipv4Addr::is_shared)) + /// - Loopback addresses ([`is_loopback`](Ipv4Addr::is_loopback)) + /// - Link-local addresses ([`is_link_local`](Ipv4Addr::is_link_local)) + /// - Addresses reserved for documentation ([`is_documentation`](Ipv4Addr::is_documentation)) + /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv4Addr::is_benchmarking)) + /// - Reserved addresses ([`is_reserved`](Ipv4Addr::is_reserved)) + /// - The [broadcast address] ([`is_broadcast`](Ipv4Addr::is_broadcast)) + /// + /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv4 Special-Purpose Address Registry]. + /// + /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml + /// [unspecified address]: Ipv4Addr::UNSPECIFIED + /// [broadcast address]: Ipv4Addr::BROADCAST + /// /// # Examples /// @@ -690,46 +700,44 @@ impl Ipv4Addr { /// /// use std::net::Ipv4Addr; /// - /// // private addresses are not global + /// // Most IPv4 addresses are globally reachable: + /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); + /// + /// // However some addresses have been assigned a special meaning + /// // that makes them not globally reachable. Some examples are: + /// + /// // The unspecified address (`0.0.0.0`) + /// assert_eq!(Ipv4Addr::UNSPECIFIED.is_global(), false); + /// + /// // Addresses reserved for private use (`10.0.0.0/8`, `172.16.0.0/12`, 192.168.0.0/16) /// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false); /// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false); /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false); /// - /// // the 0.0.0.0/8 block is not global - /// assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false); - /// // in particular, the unspecified address is not global - /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false); + /// // Addresses in the shared address space (`100.64.0.0/10`) + /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false); /// - /// // the loopback address is not global - /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_global(), false); + /// // The loopback addresses (`127.0.0.0/8`) + /// assert_eq!(Ipv4Addr::LOCALHOST.is_global(), false); /// - /// // link local addresses are not global + /// // Link-local addresses (`169.254.0.0/16`) /// assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false); /// - /// // the broadcast address is not global - /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false); - /// - /// // the address space designated for documentation is not global + /// // Addresses reserved for documentation (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`) /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false); /// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false); /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false); /// - /// // shared addresses are not global - /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false); - /// - /// // addresses reserved for protocol assignment are not global - /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false); - /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false); + /// // Addresses reserved for benchmarking (`198.18.0.0/15`) + /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false); /// - /// // addresses reserved for future use are not global + /// // Reserved addresses (`240.0.0.0/4`) /// assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false); /// - /// // addresses reserved for network devices benchmarking are not global - /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false); + /// // The broadcast address (`255.255.255.255`) + /// assert_eq!(Ipv4Addr::BROADCAST.is_global(), false); /// - /// // All the other addresses are global - /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true); - /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); + /// // For a complete overview see the IANA IPv4 Special-Purpose Address Registry. /// ``` #[cfg_attr( staged_api, @@ -739,25 +747,17 @@ impl Ipv4Addr { #[must_use] #[inline] pub const fn is_global(&self) -> bool { - // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two - // globally routable addresses in the 192.0.0.0/24 range. - if u32::from_be_bytes(self.octets()) == 0xc0000009 - || u32::from_be_bytes(self.octets()) == 0xc000000a - { - return true; - } - !self.is_private() - && !self.is_loopback() - && !self.is_link_local() - && !self.is_broadcast() - && !self.is_documentation() - && !self.is_shared() + !(self.octets()[0] == 0 // "This network" + || self.is_private() + || self.is_shared() + || self.is_loopback() + || self.is_link_local() // addresses reserved for future protocols (`192.0.0.0/24`) - && !(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0) - && !self.is_reserved() - && !self.is_benchmarking() - // Make sure the address is not in 0.0.0.0/8 - && self.octets()[0] != 0 + ||(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0) + || self.is_documentation() + || self.is_benchmarking() + || self.is_reserved() + || self.is_broadcast()) } /// Returns [`true`] if this address is part of the Shared Address Space defined in @@ -871,7 +871,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -896,7 +896,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -927,18 +927,16 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] #[inline] pub const fn is_documentation(&self) -> bool { - match self.octets() { - [192, 0, 2, _] => true, - [198, 51, 100, _] => true, - [203, 0, 113, _] => true, - _ => false, - } + matches!( + self.octets(), + [192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _] + ) } /// Converts this address to an [IPv4-compatible] [`IPv6` address]. @@ -963,7 +961,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use = "this returns the result of the operation, \ @@ -972,7 +970,7 @@ impl Ipv4Addr { pub const fn to_ipv6_compatible(&self) -> Ipv6Addr { let [a, b, c, d] = self.octets(); Ipv6Addr { - inner: in6_addr_new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d]), + octets: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d], } } @@ -993,7 +991,7 @@ impl Ipv4Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv4", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use = "this returns the result of the operation, \ @@ -1002,7 +1000,7 @@ impl Ipv4Addr { pub const fn to_ipv6_mapped(&self) -> Ipv6Addr { let [a, b, c, d] = self.octets(); Ipv6Addr { - inner: in6_addr_new([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d]), + octets: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d], } } } @@ -1051,22 +1049,6 @@ impl From for IpAddr { } } -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Clone for Ipv4Addr { - #[inline] - fn clone(&self) -> Ipv4Addr { - *self - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl PartialEq for Ipv4Addr { - #[inline] - fn eq(&self, other: &Ipv4Addr) -> bool { - in_addr_s_addr(self.inner) == in_addr_s_addr(other.inner) - } -} - #[cfg_attr(staged_api, stable(feature = "ip_cmp", since = "1.16.0"))] impl PartialEq for IpAddr { #[inline] @@ -1089,21 +1071,6 @@ impl PartialEq for Ipv4Addr { } } -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Eq for Ipv4Addr {} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl hash::Hash for Ipv4Addr { - #[inline] - fn hash(&self, s: &mut H) { - // NOTE: - // * hash in big endian order - // * in netbsd, `in_addr` has `repr(packed)`, we need to - // copy `s_addr` to avoid unsafe borrowing - { in_addr_s_addr(self.inner) }.hash(s) - } -} - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] impl PartialOrd for Ipv4Addr { #[inline] @@ -1138,8 +1105,7 @@ impl PartialOrd for Ipv4Addr { impl Ord for Ipv4Addr { #[inline] fn cmp(&self, other: &Ipv4Addr) -> Ordering { - // Compare as native endian - u32::from_be(in_addr_s_addr(self.inner)).cmp(&u32::from_be(in_addr_s_addr(other.inner))) + self.octets.cmp(&other.octets) } } @@ -1152,13 +1118,12 @@ impl From for u32 { /// ``` /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe); - /// assert_eq!(0xcafebabe, u32::from(addr)); + /// let addr = Ipv4Addr::new(0x12, 0x34, 0x56, 0x78); + /// assert_eq!(0x12345678, u32::from(addr)); /// ``` #[inline] fn from(ip: Ipv4Addr) -> u32 { - let ip = ip.octets(); - u32::from_be_bytes(ip) + u32::from_be_bytes(ip.octets) } } @@ -1171,12 +1136,14 @@ impl From for Ipv4Addr { /// ``` /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::from(0xcafebabe); - /// assert_eq!(Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe), addr); + /// let addr = Ipv4Addr::from(0x12345678); + /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr); /// ``` #[inline] fn from(ip: u32) -> Ipv4Addr { - Ipv4Addr::from(ip.to_be_bytes()) + Ipv4Addr { + octets: ip.to_be_bytes(), + } } } @@ -1194,7 +1161,7 @@ impl From<[u8; 4]> for Ipv4Addr { /// ``` #[inline] fn from(octets: [u8; 4]) -> Ipv4Addr { - Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]) + Ipv4Addr { octets } } } @@ -1230,7 +1197,7 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.32.0") + rustc_const_stable(feature = "const_ip_32", since = "1.32.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use] @@ -1249,9 +1216,7 @@ impl Ipv6Addr { Ipv6Addr { // All elements in `addr16` are big endian. // SAFETY: `[u16; 8]` is always safe to transmute to `[u8; 16]`. - // rustc_allow_const_fn_unstable: the transmute could be written as stable const - // code, but that leads to worse code generation (#75085) - inner: in6_addr_new(unsafe { transmute::<_, [u8; 16]>(addr16) }), + octets: unsafe { transmute::<_, [u8; 16]>(addr16) }, } } @@ -1293,18 +1258,15 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use] #[inline] pub const fn segments(&self) -> [u16; 8] { - // All elements in `s6_addr` must be big endian. + // All elements in `self.octets` must be big endian. // SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`. - // rustc_allow_const_fn_unstable: the transmute could be written as stable const code, but - // that leads to worse code generation (#75085) - let [a, b, c, d, e, f, g, h] = - unsafe { transmute::<_, [u16; 8]>(in6_addr_s6_addr(self.inner)) }; + let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.octets) }; // We want native endian u16 [ u16::from_be(a), @@ -1334,7 +1296,7 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -1361,7 +1323,7 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -1370,13 +1332,33 @@ impl Ipv6Addr { u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets()) } - /// Returns [`true`] if the address appears to be globally routable. + /// Returns [`true`] if the address appears to be globally reachable + /// as specified by the [IANA IPv6 Special-Purpose Address Registry]. + /// Whether or not an address is practically reachable will depend on your network configuration. /// - /// The following return [`false`]: + /// Most IPv6 addresses are globally reachable; + /// unless they are specifically defined as *not* globally reachable. /// - /// - the loopback address - /// - link-local and unique local unicast addresses - /// - interface-, link-, realm-, admin- and site-local multicast addresses + /// Non-exhaustive list of notable addresses that are not globally reachable: + /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified)) + /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback)) + /// - IPv4-mapped addresses + /// - Addresses reserved for benchmarking + /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation)) + /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local)) + /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local)) + /// + /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv6 Special-Purpose Address Registry]. + /// + /// Note that an address having global scope is not the same as being globally reachable, + /// and there is no direct relation between the two concepts: There exist addresses with global scope + /// that are not globally reachable (for example unique local addresses), + /// and addresses that are globally reachable without having global scope + /// (multicast addresses with non-global scope). + /// + /// [IANA IPv6 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml + /// [unspecified address]: Ipv6Addr::UNSPECIFIED + /// [loopback address]: Ipv6Addr::LOCALHOST /// /// # Examples /// @@ -1385,9 +1367,34 @@ impl Ipv6Addr { /// /// use std::net::Ipv6Addr; /// - /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true); - /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false); - /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true); + /// // Most IPv6 addresses are globally reachable: + /// assert_eq!(Ipv6Addr::new(0x26, 0, 0x1c9, 0, 0, 0xafc8, 0x10, 0x1).is_global(), true); + /// + /// // However some addresses have been assigned a special meaning + /// // that makes them not globally reachable. Some examples are: + /// + /// // The unspecified address (`::`) + /// assert_eq!(Ipv6Addr::UNSPECIFIED.is_global(), false); + /// + /// // The loopback address (`::1`) + /// assert_eq!(Ipv6Addr::LOCALHOST.is_global(), false); + /// + /// // IPv4-mapped addresses (`::ffff:0:0/96`) + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), false); + /// + /// // Addresses reserved for benchmarking (`2001:2::/48`) + /// assert_eq!(Ipv6Addr::new(0x2001, 2, 0, 0, 0, 0, 0, 1,).is_global(), false); + /// + /// // Addresses reserved for documentation (`2001:db8::/32`) + /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1).is_global(), false); + /// + /// // Unique local addresses (`fc00::/7`) + /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 1).is_global(), false); + /// + /// // Unicast addresses with link-local scope (`fe80::/10`) + /// assert_eq!(Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 1).is_global(), false); + /// + /// // For a complete overview see the IANA IPv6 Special-Purpose Address Registry. /// ``` #[cfg_attr( staged_api, @@ -1397,11 +1404,31 @@ impl Ipv6Addr { #[must_use] #[inline] pub const fn is_global(&self) -> bool { - match self.multicast_scope() { - Some(Ipv6MulticastScope::Global) => true, - None => self.is_unicast_global(), - _ => false, - } + !(self.is_unspecified() + || self.is_loopback() + // IPv4-mapped Address (`::ffff:0:0/96`) + || matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _]) + // IPv4-IPv6 Translat. (`64:ff9b:1::/48`) + || matches!(self.segments(), [0x64, 0xff9b, 1, _, _, _, _, _]) + // Discard-Only Address Block (`100::/64`) + || matches!(self.segments(), [0x100, 0, 0, 0, _, _, _, _]) + // IETF Protocol Assignments (`2001::/23`) + || (matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200) + && !( + // Port Control Protocol Anycast (`2001:1::1`) + u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001 + // Traversal Using Relays around NAT Anycast (`2001:1::2`) + || u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002 + // AMT (`2001:3::/32`) + || matches!(self.segments(), [0x2001, 3, _, _, _, _, _, _]) + // AS112-v6 (`2001:4:112::/48`) + || matches!(self.segments(), [0x2001, 4, 0x112, _, _, _, _, _]) + // ORCHIDv2 (`2001:20::/28`) + || matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F) + )) + || self.is_documentation() + || self.is_unique_local() + || self.is_unicast_link_local()) } /// Returns [`true`] if this is a unique local address (`fc00::/7`). @@ -1613,6 +1640,7 @@ impl Ipv6Addr { && !self.is_unique_local() && !self.is_unspecified() && !self.is_documentation() + && !self.is_benchmarking() } /// Returns the address's multicast scope if the address is multicast. @@ -1670,7 +1698,7 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(since = "1.7.0", feature = "ip_17"))] #[must_use] @@ -1692,8 +1720,6 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip)] - /// /// use std::net::{Ipv4Addr, Ipv6Addr}; /// /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).to_ipv4_mapped(), None); @@ -1705,7 +1731,7 @@ impl Ipv6Addr { staged_api, rustc_const_unstable(feature = "const_ipv6", issue = "76205") )] - #[cfg_attr(staged_api, unstable(feature = "ip", issue = "27709"))] + #[cfg_attr(staged_api, stable(feature = "ipv6_to_ipv4_mapped", since = "1.63.0"))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1723,7 +1749,10 @@ impl Ipv6Addr { /// or an [IPv4-mapped] address as defined in [IETF RFC 4291 section 2.5.5.2], /// otherwise returns [`None`]. /// - /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d` + /// Note that this will return an [`IPv4` address] for the IPv6 loopback address `::1`. Use + /// [`Ipv6Addr::to_ipv4_mapped`] to avoid this. + /// + /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`. `::1` becomes `0.0.0.1`. /// All addresses *not* starting with either all zeroes or `::ffff` will return `None`. /// /// [`IPv4` address]: Ipv4Addr @@ -1745,7 +1774,7 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.50.0") + rustc_const_stable(feature = "const_ip_50", since = "1.50.0") )] #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] #[must_use = "this returns the result of the operation, \ @@ -1798,29 +1827,13 @@ impl Ipv6Addr { /// ``` #[cfg_attr( staged_api, - rustc_const_stable(feature = "const_ipv6", since = "1.32.0") + rustc_const_stable(feature = "const_ip_32", since = "1.32.0") )] #[cfg_attr(staged_api, stable(feature = "ipv6_to_octets", since = "1.12.0"))] #[must_use] #[inline] pub const fn octets(&self) -> [u8; 16] { - in6_addr_s6_addr(self.inner) - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Clone for Ipv6Addr { - #[inline] - fn clone(&self) -> Ipv6Addr { - *self - } -} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl PartialEq for Ipv6Addr { - #[inline] - fn eq(&self, other: &Ipv6Addr) -> bool { - in6_addr_s6_addr(self.inner) == in6_addr_s6_addr(other.inner) + self.octets } } @@ -1846,17 +1859,6 @@ impl PartialEq for IpAddr { } } -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl Eq for Ipv6Addr {} - -#[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] -impl hash::Hash for Ipv6Addr { - #[inline] - fn hash(&self, s: &mut H) { - in6_addr_s6_addr(self.inner).hash(s) - } -} - #[cfg_attr(staged_api, stable(feature = "rust1", since = "1.0.0"))] impl PartialOrd for Ipv6Addr { #[inline] @@ -1912,8 +1914,7 @@ impl From for u128 { /// ``` #[inline] fn from(ip: Ipv6Addr) -> u128 { - let ip = ip.octets(); - u128::from_be_bytes(ip) + u128::from_be_bytes(ip.octets) } } #[cfg_attr(staged_api, stable(feature = "i128", since = "1.26.0"))] @@ -1964,9 +1965,7 @@ impl From<[u8; 16]> for Ipv6Addr { /// ``` #[inline] fn from(octets: [u8; 16]) -> Ipv6Addr { - Ipv6Addr { - inner: in6_addr_new(octets), - } + Ipv6Addr { octets } } } diff --git a/vendor/rustix/src/net/send_recv.rs b/vendor/rustix/src/net/send_recv.rs index 83ccc79d4..041077266 100644 --- a/vendor/rustix/src/net/send_recv.rs +++ b/vendor/rustix/src/net/send_recv.rs @@ -3,10 +3,10 @@ #[cfg(unix)] use crate::net::SocketAddrUnix; use crate::net::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; -use crate::{imp, io}; -use imp::fd::{AsFd, BorrowedFd}; +use crate::{backend, io}; +use backend::fd::{AsFd, BorrowedFd}; -pub use imp::net::send_recv::{RecvFlags, SendFlags}; +pub use backend::net::send_recv::{RecvFlags, SendFlags}; /// `recv(fd, buf, flags)`—Reads data from a socket. /// @@ -22,7 +22,7 @@ pub use imp::net::send_recv::{RecvFlags, SendFlags}; /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv #[inline] pub fn recv(fd: Fd, buf: &mut [u8], flags: RecvFlags) -> io::Result { - imp::net::syscalls::recv(fd.as_fd(), buf, flags) + backend::net::syscalls::recv(fd.as_fd(), buf, flags) } /// `send(fd, buf, flags)`—Writes data to a socket. @@ -39,7 +39,7 @@ pub fn recv(fd: Fd, buf: &mut [u8], flags: RecvFlags) -> io::Result(fd: Fd, buf: &[u8], flags: SendFlags) -> io::Result { - imp::net::syscalls::send(fd.as_fd(), buf, flags) + backend::net::syscalls::send(fd.as_fd(), buf, flags) } /// `recvfrom(fd, buf, flags, addr, len)`—Reads data from a socket and @@ -61,7 +61,7 @@ pub fn recvfrom( buf: &mut [u8], flags: RecvFlags, ) -> io::Result<(usize, Option)> { - imp::net::syscalls::recvfrom(fd.as_fd(), buf, flags) + backend::net::syscalls::recvfrom(fd.as_fd(), buf, flags) } /// `sendto(fd, buf, flags, addr)`—Writes data to a socket to a specific IP @@ -93,8 +93,8 @@ fn _sendto( addr: &SocketAddr, ) -> io::Result { match addr { - SocketAddr::V4(v4) => imp::net::syscalls::sendto_v4(fd, buf, flags, v4), - SocketAddr::V6(v6) => imp::net::syscalls::sendto_v6(fd, buf, flags, v6), + SocketAddr::V4(v4) => backend::net::syscalls::sendto_v4(fd, buf, flags, v4), + SocketAddr::V6(v6) => backend::net::syscalls::sendto_v6(fd, buf, flags, v6), } } @@ -127,10 +127,10 @@ fn _sendto_any( addr: &SocketAddrAny, ) -> io::Result { match addr { - SocketAddrAny::V4(v4) => imp::net::syscalls::sendto_v4(fd, buf, flags, v4), - SocketAddrAny::V6(v6) => imp::net::syscalls::sendto_v6(fd, buf, flags, v6), + SocketAddrAny::V4(v4) => backend::net::syscalls::sendto_v4(fd, buf, flags, v4), + SocketAddrAny::V6(v6) => backend::net::syscalls::sendto_v6(fd, buf, flags, v6), #[cfg(unix)] - SocketAddrAny::Unix(unix) => imp::net::syscalls::sendto_unix(fd, buf, flags, unix), + SocketAddrAny::Unix(unix) => backend::net::syscalls::sendto_unix(fd, buf, flags, unix), } } @@ -155,7 +155,7 @@ pub fn sendto_v4( flags: SendFlags, addr: &SocketAddrV4, ) -> io::Result { - imp::net::syscalls::sendto_v4(fd.as_fd(), buf, flags, addr) + backend::net::syscalls::sendto_v4(fd.as_fd(), buf, flags, addr) } /// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_in6))`—Writes data @@ -179,7 +179,7 @@ pub fn sendto_v6( flags: SendFlags, addr: &SocketAddrV6, ) -> io::Result { - imp::net::syscalls::sendto_v6(fd.as_fd(), buf, flags, addr) + backend::net::syscalls::sendto_v6(fd.as_fd(), buf, flags, addr) } /// `sendto(fd, buf, flags, addr, sizeof(struct sockaddr_un))`—Writes data to @@ -204,7 +204,7 @@ pub fn sendto_unix( flags: SendFlags, addr: &SocketAddrUnix, ) -> io::Result { - imp::net::syscalls::sendto_unix(fd.as_fd(), buf, flags, addr) + backend::net::syscalls::sendto_unix(fd.as_fd(), buf, flags, addr) } // TODO: `recvmsg`, `sendmsg` diff --git a/vendor/rustix/src/net/socket.rs b/vendor/rustix/src/net/socket.rs index cd8f149f6..687022afe 100644 --- a/vendor/rustix/src/net/socket.rs +++ b/vendor/rustix/src/net/socket.rs @@ -1,11 +1,11 @@ -use crate::imp; -use crate::io::{self, OwnedFd}; +use crate::fd::OwnedFd; use crate::net::{SocketAddr, SocketAddrAny, SocketAddrV4, SocketAddrV6}; -use imp::fd::{AsFd, BorrowedFd}; +use crate::{backend, io}; +use backend::fd::{AsFd, BorrowedFd}; #[cfg(unix)] -pub use imp::net::addr::SocketAddrUnix; -pub use imp::net::types::{ +pub use backend::net::addr::SocketAddrUnix; +pub use backend::net::types::{ AcceptFlags, AddressFamily, Protocol, Shutdown, SocketFlags, SocketType, }; @@ -34,7 +34,7 @@ impl Default for Protocol { /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket #[inline] pub fn socket(domain: AddressFamily, type_: SocketType, protocol: Protocol) -> io::Result { - imp::net::syscalls::socket(domain, type_, protocol) + backend::net::syscalls::socket(domain, type_, protocol) } /// `socket_with(domain, type_ | flags, protocol)`—Creates a socket, with @@ -64,7 +64,7 @@ pub fn socket_with( flags: SocketFlags, protocol: Protocol, ) -> io::Result { - imp::net::syscalls::socket_with(domain, type_, flags, protocol) + backend::net::syscalls::socket_with(domain, type_, flags, protocol) } /// `bind(sockfd, addr)`—Binds a socket to an IP address. @@ -85,8 +85,8 @@ pub fn bind(sockfd: Fd, addr: &SocketAddr) -> io::Result<()> { fn _bind(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()> { match addr { - SocketAddr::V4(v4) => imp::net::syscalls::bind_v4(sockfd, v4), - SocketAddr::V6(v6) => imp::net::syscalls::bind_v6(sockfd, v6), + SocketAddr::V4(v4) => backend::net::syscalls::bind_v4(sockfd, v4), + SocketAddr::V6(v6) => backend::net::syscalls::bind_v6(sockfd, v6), } } @@ -109,10 +109,10 @@ pub fn bind_any(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()> { fn _bind_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> { match addr { - SocketAddrAny::V4(v4) => imp::net::syscalls::bind_v4(sockfd, v4), - SocketAddrAny::V6(v6) => imp::net::syscalls::bind_v6(sockfd, v6), + SocketAddrAny::V4(v4) => backend::net::syscalls::bind_v4(sockfd, v4), + SocketAddrAny::V6(v6) => backend::net::syscalls::bind_v6(sockfd, v6), #[cfg(unix)] - SocketAddrAny::Unix(unix) => imp::net::syscalls::bind_unix(sockfd, unix), + SocketAddrAny::Unix(unix) => backend::net::syscalls::bind_unix(sockfd, unix), } } @@ -132,7 +132,7 @@ fn _bind_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> { #[inline] #[doc(alias = "bind")] pub fn bind_v4(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> { - imp::net::syscalls::bind_v4(sockfd.as_fd(), addr) + backend::net::syscalls::bind_v4(sockfd.as_fd(), addr) } /// `bind(sockfd, addr, sizeof(struct sockaddr_in6))`—Binds a socket to an @@ -151,7 +151,7 @@ pub fn bind_v4(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> { #[inline] #[doc(alias = "bind")] pub fn bind_v6(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> { - imp::net::syscalls::bind_v6(sockfd.as_fd(), addr) + backend::net::syscalls::bind_v6(sockfd.as_fd(), addr) } /// `bind(sockfd, addr, sizeof(struct sockaddr_un))`—Binds a socket to a @@ -171,7 +171,7 @@ pub fn bind_v6(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> { #[inline] #[doc(alias = "bind")] pub fn bind_unix(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()> { - imp::net::syscalls::bind_unix(sockfd.as_fd(), addr) + backend::net::syscalls::bind_unix(sockfd.as_fd(), addr) } /// `connect(sockfd, addr)`—Initiates a connection to an IP address. @@ -192,8 +192,8 @@ pub fn connect(sockfd: Fd, addr: &SocketAddr) -> io::Result<()> { fn _connect(sockfd: BorrowedFd<'_>, addr: &SocketAddr) -> io::Result<()> { match addr { - SocketAddr::V4(v4) => imp::net::syscalls::connect_v4(sockfd, v4), - SocketAddr::V6(v6) => imp::net::syscalls::connect_v6(sockfd, v6), + SocketAddr::V4(v4) => backend::net::syscalls::connect_v4(sockfd, v4), + SocketAddr::V6(v6) => backend::net::syscalls::connect_v6(sockfd, v6), } } @@ -216,10 +216,10 @@ pub fn connect_any(sockfd: Fd, addr: &SocketAddrAny) -> io::Result<()> fn _connect_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> { match addr { - SocketAddrAny::V4(v4) => imp::net::syscalls::connect_v4(sockfd, v4), - SocketAddrAny::V6(v6) => imp::net::syscalls::connect_v6(sockfd, v6), + SocketAddrAny::V4(v4) => backend::net::syscalls::connect_v4(sockfd, v4), + SocketAddrAny::V6(v6) => backend::net::syscalls::connect_v6(sockfd, v6), #[cfg(unix)] - SocketAddrAny::Unix(unix) => imp::net::syscalls::connect_unix(sockfd, unix), + SocketAddrAny::Unix(unix) => backend::net::syscalls::connect_unix(sockfd, unix), } } @@ -239,7 +239,7 @@ fn _connect_any(sockfd: BorrowedFd<'_>, addr: &SocketAddrAny) -> io::Result<()> #[inline] #[doc(alias = "connect")] pub fn connect_v4(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> { - imp::net::syscalls::connect_v4(sockfd.as_fd(), addr) + backend::net::syscalls::connect_v4(sockfd.as_fd(), addr) } /// `connect(sockfd, addr, sizeof(struct sockaddr_in6))`—Initiates a @@ -258,7 +258,7 @@ pub fn connect_v4(sockfd: Fd, addr: &SocketAddrV4) -> io::Result<()> { #[inline] #[doc(alias = "connect")] pub fn connect_v6(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> { - imp::net::syscalls::connect_v6(sockfd.as_fd(), addr) + backend::net::syscalls::connect_v6(sockfd.as_fd(), addr) } /// `connect(sockfd, addr, sizeof(struct sockaddr_un))`—Initiates a @@ -278,7 +278,7 @@ pub fn connect_v6(sockfd: Fd, addr: &SocketAddrV6) -> io::Result<()> { #[inline] #[doc(alias = "connect")] pub fn connect_unix(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<()> { - imp::net::syscalls::connect_unix(sockfd.as_fd(), addr) + backend::net::syscalls::connect_unix(sockfd.as_fd(), addr) } /// `listen(fd, backlog)`—Enables listening for incoming connections. @@ -295,7 +295,7 @@ pub fn connect_unix(sockfd: Fd, addr: &SocketAddrUnix) -> io::Result<( /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-listen #[inline] pub fn listen(sockfd: Fd, backlog: i32) -> io::Result<()> { - imp::net::syscalls::listen(sockfd.as_fd(), backlog) + backend::net::syscalls::listen(sockfd.as_fd(), backlog) } /// `accept(fd, NULL, NULL)`—Accepts an incoming connection. @@ -319,7 +319,7 @@ pub fn listen(sockfd: Fd, backlog: i32) -> io::Result<()> { #[inline] #[doc(alias = "accept4")] pub fn accept(sockfd: Fd) -> io::Result { - imp::net::syscalls::accept(sockfd.as_fd()) + backend::net::syscalls::accept(sockfd.as_fd()) } /// `accept4(fd, NULL, NULL, flags)`—Accepts an incoming connection, with @@ -341,7 +341,7 @@ pub fn accept(sockfd: Fd) -> io::Result { #[inline] #[doc(alias = "accept4")] pub fn accept_with(sockfd: Fd, flags: AcceptFlags) -> io::Result { - imp::net::syscalls::accept_with(sockfd.as_fd(), flags) + backend::net::syscalls::accept_with(sockfd.as_fd(), flags) } /// `accept(fd, &addr, &len)`—Accepts an incoming connection and returns the @@ -362,7 +362,7 @@ pub fn accept_with(sockfd: Fd, flags: AcceptFlags) -> io::Result(sockfd: Fd) -> io::Result<(OwnedFd, Option)> { - imp::net::syscalls::acceptfrom(sockfd.as_fd()) + backend::net::syscalls::acceptfrom(sockfd.as_fd()) } /// `accept4(fd, &addr, &len, flags)`—Accepts an incoming connection and @@ -383,7 +383,7 @@ pub fn acceptfrom_with( sockfd: Fd, flags: AcceptFlags, ) -> io::Result<(OwnedFd, Option)> { - imp::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags) + backend::net::syscalls::acceptfrom_with(sockfd.as_fd(), flags) } /// `shutdown(fd, how)`—Closes the read and/or write sides of a stream. @@ -400,7 +400,7 @@ pub fn acceptfrom_with( /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-shutdown #[inline] pub fn shutdown(sockfd: Fd, how: Shutdown) -> io::Result<()> { - imp::net::syscalls::shutdown(sockfd.as_fd(), how) + backend::net::syscalls::shutdown(sockfd.as_fd(), how) } /// `getsockname(fd, addr, len)`—Returns the address a socket is bound to. @@ -417,7 +417,7 @@ pub fn shutdown(sockfd: Fd, how: Shutdown) -> io::Result<()> { /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockname #[inline] pub fn getsockname(sockfd: Fd) -> io::Result { - imp::net::syscalls::getsockname(sockfd.as_fd()) + backend::net::syscalls::getsockname(sockfd.as_fd()) } /// `getpeername(fd, addr, len)`—Returns the address a socket is connected @@ -435,5 +435,5 @@ pub fn getsockname(sockfd: Fd) -> io::Result { /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getpeername #[inline] pub fn getpeername(sockfd: Fd) -> io::Result> { - imp::net::syscalls::getpeername(sockfd.as_fd()) + backend::net::syscalls::getpeername(sockfd.as_fd()) } diff --git a/vendor/rustix/src/net/socket_addr_any.rs b/vendor/rustix/src/net/socket_addr_any.rs index 4970dbf74..287c6c1ee 100644 --- a/vendor/rustix/src/net/socket_addr_any.rs +++ b/vendor/rustix/src/net/socket_addr_any.rs @@ -12,11 +12,11 @@ #[cfg(unix)] use crate::net::SocketAddrUnix; use crate::net::{AddressFamily, SocketAddrV4, SocketAddrV6}; -use crate::{imp, io}; +use crate::{backend, io}; #[cfg(feature = "std")] use core::fmt; -pub use imp::net::addr::SocketAddrStorage; +pub use backend::net::addr::SocketAddrStorage; /// `struct sockaddr_storage` as a Rust enum. #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] @@ -37,10 +37,10 @@ impl SocketAddrAny { #[inline] pub const fn address_family(&self) -> AddressFamily { match self { - SocketAddrAny::V4(_) => AddressFamily::INET, - SocketAddrAny::V6(_) => AddressFamily::INET6, + Self::V4(_) => AddressFamily::INET, + Self::V6(_) => AddressFamily::INET6, #[cfg(unix)] - SocketAddrAny::Unix(_) => AddressFamily::UNIX, + Self::Unix(_) => AddressFamily::UNIX, } } @@ -53,7 +53,7 @@ impl SocketAddrAny { /// `storage` must point to valid memory for encoding the socket /// address. pub unsafe fn write(&self, storage: *mut SocketAddrStorage) -> usize { - imp::net::write_sockaddr::write_sockaddr(self, storage) + backend::net::write_sockaddr::write_sockaddr(self, storage) } /// Reads a platform-specific encoding of a socket address from @@ -64,7 +64,7 @@ impl SocketAddrAny { /// `storage` must point to valid memory for decoding a socket /// address. pub unsafe fn read(storage: *const SocketAddrStorage, len: usize) -> io::Result { - imp::net::read_sockaddr::read_sockaddr(storage, len) + backend::net::read_sockaddr::read_sockaddr(storage, len) } } @@ -72,10 +72,10 @@ impl SocketAddrAny { impl fmt::Debug for SocketAddrAny { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - SocketAddrAny::V4(v4) => v4.fmt(fmt), - SocketAddrAny::V6(v6) => v6.fmt(fmt), + Self::V4(v4) => v4.fmt(fmt), + Self::V6(v6) => v6.fmt(fmt), #[cfg(unix)] - SocketAddrAny::Unix(unix) => unix.fmt(fmt), + Self::Unix(unix) => unix.fmt(fmt), } } } diff --git a/vendor/rustix/src/net/socketpair.rs b/vendor/rustix/src/net/socketpair.rs index 68a58f3e9..4a9568ce7 100644 --- a/vendor/rustix/src/net/socketpair.rs +++ b/vendor/rustix/src/net/socketpair.rs @@ -1,6 +1,6 @@ -use crate::imp; -use crate::io::{self, OwnedFd}; +use crate::fd::OwnedFd; use crate::net::{AddressFamily, Protocol, SocketFlags, SocketType}; +use crate::{backend, io}; /// `socketpair(domain, type_ | accept_flags, protocol)` /// @@ -17,5 +17,5 @@ pub fn socketpair( flags: SocketFlags, protocol: Protocol, ) -> io::Result<(OwnedFd, OwnedFd)> { - imp::net::syscalls::socketpair(domain, type_, flags, protocol) + backend::net::syscalls::socketpair(domain, type_, flags, protocol) } diff --git a/vendor/rustix/src/net/sockopt.rs b/vendor/rustix/src/net/sockopt.rs index f5b149b37..436d5bf86 100644 --- a/vendor/rustix/src/net/sockopt.rs +++ b/vendor/rustix/src/net/sockopt.rs @@ -7,11 +7,11 @@ #![doc(alias = "setsockopt")] use crate::net::{Ipv4Addr, Ipv6Addr, SocketType}; -use crate::{imp, io}; +use crate::{backend, io}; +use backend::fd::AsFd; use core::time::Duration; -use imp::fd::AsFd; -pub use imp::net::types::Timeout; +pub use backend::net::types::Timeout; /// `getsockopt(fd, SOL_SOCKET, SO_TYPE)`—Returns the type of a socket. /// @@ -32,7 +32,7 @@ pub use imp::net::types::Timeout; #[inline] #[doc(alias = "SO_TYPE")] pub fn get_socket_type(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_socket_type(fd.as_fd()) + backend::net::syscalls::sockopt::get_socket_type(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, value)` @@ -54,7 +54,7 @@ pub fn get_socket_type(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_REUSEADDR")] pub fn set_socket_reuseaddr(fd: Fd, value: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_socket_reuseaddr(fd.as_fd(), value) + backend::net::syscalls::sockopt::set_socket_reuseaddr(fd.as_fd(), value) } /// `setsockopt(fd, SOL_SOCKET, SO_BROADCAST, broadcast)` @@ -76,7 +76,7 @@ pub fn set_socket_reuseaddr(fd: Fd, value: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_BROADCAST")] pub fn set_socket_broadcast(fd: Fd, broadcast: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), broadcast) + backend::net::syscalls::sockopt::set_socket_broadcast(fd.as_fd(), broadcast) } /// `getsockopt(fd, SOL_SOCKET, SO_BROADCAST)` @@ -98,7 +98,7 @@ pub fn set_socket_broadcast(fd: Fd, broadcast: bool) -> io::Result<()> #[inline] #[doc(alias = "SO_BROADCAST")] pub fn get_socket_broadcast(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_socket_broadcast(fd.as_fd()) + backend::net::syscalls::sockopt::get_socket_broadcast(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_LINGER, linger)` @@ -120,7 +120,7 @@ pub fn get_socket_broadcast(fd: Fd) -> io::Result { #[inline] #[doc(alias = "SO_LINGER")] pub fn set_socket_linger(fd: Fd, linger: Option) -> io::Result<()> { - imp::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), linger) + backend::net::syscalls::sockopt::set_socket_linger(fd.as_fd(), linger) } /// `getsockopt(fd, SOL_SOCKET, SO_LINGER)` @@ -142,7 +142,7 @@ pub fn set_socket_linger(fd: Fd, linger: Option) -> io::Resu #[inline] #[doc(alias = "SO_LINGER")] pub fn get_socket_linger(fd: Fd) -> io::Result> { - imp::net::syscalls::sockopt::get_socket_linger(fd.as_fd()) + backend::net::syscalls::sockopt::get_socket_linger(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, SO_PASSCRED, passcred)` @@ -157,7 +157,7 @@ pub fn get_socket_linger(fd: Fd) -> io::Result> { #[inline] #[doc(alias = "SO_PASSCRED")] pub fn set_socket_passcred(fd: Fd, passcred: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), passcred) + backend::net::syscalls::sockopt::set_socket_passcred(fd.as_fd(), passcred) } /// `getsockopt(fd, SOL_SOCKET, SO_PASSCRED)` @@ -172,7 +172,7 @@ pub fn set_socket_passcred(fd: Fd, passcred: bool) -> io::Result<()> { #[inline] #[doc(alias = "SO_PASSCRED")] pub fn get_socket_passcred(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_socket_passcred(fd.as_fd()) + backend::net::syscalls::sockopt::get_socket_passcred(fd.as_fd()) } /// `setsockopt(fd, SOL_SOCKET, id, timeout)`—Set the sending @@ -200,7 +200,7 @@ pub fn set_socket_timeout( id: Timeout, timeout: Option, ) -> io::Result<()> { - imp::net::syscalls::sockopt::set_socket_timeout(fd.as_fd(), id, timeout) + backend::net::syscalls::sockopt::set_socket_timeout(fd.as_fd(), id, timeout) } /// `getsockopt(fd, SOL_SOCKET, id)`—Get the sending or receiving timeout. @@ -223,7 +223,7 @@ pub fn set_socket_timeout( #[doc(alias = "SO_RCVTIMEO")] #[doc(alias = "SO_SNDTIMEO")] pub fn get_socket_timeout(fd: Fd, id: Timeout) -> io::Result> { - imp::net::syscalls::sockopt::get_socket_timeout(fd.as_fd(), id) + backend::net::syscalls::sockopt::get_socket_timeout(fd.as_fd(), id) } /// `setsockopt(fd, IPPROTO_IP, IP_TTL, ttl)` @@ -244,7 +244,7 @@ pub fn get_socket_timeout(fd: Fd, id: Timeout) -> io::Result(fd: Fd, ttl: u32) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), ttl) + backend::net::syscalls::sockopt::set_ip_ttl(fd.as_fd(), ttl) } /// `getsockopt(fd, IPPROTO_IP, IP_TTL)` @@ -266,7 +266,7 @@ pub fn set_ip_ttl(fd: Fd, ttl: u32) -> io::Result<()> { #[inline] #[doc(alias = "IP_TTL")] pub fn get_ip_ttl(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_ip_ttl(fd.as_fd()) + backend::net::syscalls::sockopt::get_ip_ttl(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, only_v6)` @@ -288,7 +288,7 @@ pub fn get_ip_ttl(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IPV6_V6ONLY")] pub fn set_ipv6_v6only(fd: Fd, only_v6: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), only_v6) + backend::net::syscalls::sockopt::set_ipv6_v6only(fd.as_fd(), only_v6) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY)` @@ -310,7 +310,7 @@ pub fn set_ipv6_v6only(fd: Fd, only_v6: bool) -> io::Result<()> { #[inline] #[doc(alias = "IPV6_V6ONLY")] pub fn get_ipv6_v6only(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_ipv6_v6only(fd.as_fd()) + backend::net::syscalls::sockopt::get_ipv6_v6only(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, multicast_loop)` @@ -332,7 +332,7 @@ pub fn get_ipv6_v6only(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] pub fn set_ip_multicast_loop(fd: Fd, multicast_loop: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), multicast_loop) + backend::net::syscalls::sockopt::set_ip_multicast_loop(fd.as_fd(), multicast_loop) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP)` @@ -354,7 +354,7 @@ pub fn set_ip_multicast_loop(fd: Fd, multicast_loop: bool) -> io::Resu #[inline] #[doc(alias = "IP_MULTICAST_LOOP")] pub fn get_ip_multicast_loop(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_ip_multicast_loop(fd.as_fd()) + backend::net::syscalls::sockopt::get_ip_multicast_loop(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, multicast_ttl)` @@ -376,7 +376,7 @@ pub fn get_ip_multicast_loop(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn set_ip_multicast_ttl(fd: Fd, multicast_ttl: u32) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), multicast_ttl) + backend::net::syscalls::sockopt::set_ip_multicast_ttl(fd.as_fd(), multicast_ttl) } /// `getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL)` @@ -398,7 +398,7 @@ pub fn set_ip_multicast_ttl(fd: Fd, multicast_ttl: u32) -> io::Result< #[inline] #[doc(alias = "IP_MULTICAST_TTL")] pub fn get_ip_multicast_ttl(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_ip_multicast_ttl(fd.as_fd()) + backend::net::syscalls::sockopt::get_ip_multicast_ttl(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, multicast_loop)` @@ -420,7 +420,7 @@ pub fn get_ip_multicast_ttl(fd: Fd) -> io::Result { #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] pub fn set_ipv6_multicast_loop(fd: Fd, multicast_loop: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), multicast_loop) + backend::net::syscalls::sockopt::set_ipv6_multicast_loop(fd.as_fd(), multicast_loop) } /// `getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP)` @@ -442,7 +442,51 @@ pub fn set_ipv6_multicast_loop(fd: Fd, multicast_loop: bool) -> io::Re #[inline] #[doc(alias = "IPV6_MULTICAST_LOOP")] pub fn get_ipv6_multicast_loop(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_ipv6_multicast_loop(fd.as_fd()) + backend::net::syscalls::sockopt::get_ipv6_multicast_loop(fd.as_fd()) +} + +/// `setsockopt(fd, IPPROTO_IP, IPV6_MULTICAST_HOPS, multicast_hops)` +/// +/// # References +/// - [POSIX `setsockopt`] +/// - [POSIX `netinet/in.h`] +/// - [Linux `setsockopt`] +/// - [Linux `ipv6`] +/// - [Winsock2 `setsockopt`] +/// - [Winsock2 `IPPROTO_IPV6` options] +/// +/// [POSIX `setsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html +/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html +/// [Linux `setsockopt`]: https://man7.org/linux/man-pages/man2/setsockopt.2.html +/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html +/// [Winsock2 `setsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt +/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options +#[inline] +#[doc(alias = "IP_MULTICAST_TTL")] +pub fn set_ipv6_multicast_hops(fd: Fd, multicast_hops: u32) -> io::Result<()> { + backend::net::syscalls::sockopt::set_ipv6_multicast_hops(fd.as_fd(), multicast_hops) +} + +/// `getsockopt(fd, IPPROTO_IP, IPV6_MULTICAST_HOPS)` +/// +/// # References +/// - [POSIX `getsockopt`] +/// - [POSIX `netinet/in.h`] +/// - [Linux `getsockopt`] +/// - [Linux `ipv6`] +/// - [Winsock2 `getsockopt`] +/// - [Winsock2 `IPPROTO_IPV6` options] +/// +/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html +/// [POSIX `netinet/in.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html +/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html +/// [Linux `ipv6`]: https://man7.org/linux/man-pages/man7/ipv6.7.html +/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt +/// [Winsock2 `IPPROTO_IPV6` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options +#[inline] +#[doc(alias = "IP_MULTICAST_TTL")] +pub fn get_ipv6_multicast_hops(fd: Fd) -> io::Result { + backend::net::syscalls::sockopt::get_ipv6_multicast_hops(fd.as_fd()) } /// `setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, multiaddr, interface)` @@ -468,7 +512,7 @@ pub fn set_ip_add_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) + backend::net::syscalls::sockopt::set_ip_add_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, multiaddr, interface)` @@ -497,7 +541,7 @@ pub fn set_ipv6_add_membership( multiaddr: &Ipv6Addr, interface: u32, ) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) + backend::net::syscalls::sockopt::set_ipv6_add_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, multiaddr, interface)` @@ -523,7 +567,7 @@ pub fn set_ip_drop_membership( multiaddr: &Ipv4Addr, interface: &Ipv4Addr, ) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) + backend::net::syscalls::sockopt::set_ip_drop_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, multiaddr, interface)` @@ -552,7 +596,7 @@ pub fn set_ipv6_drop_membership( multiaddr: &Ipv6Addr, interface: u32, ) -> io::Result<()> { - imp::net::syscalls::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) + backend::net::syscalls::sockopt::set_ipv6_drop_membership(fd.as_fd(), multiaddr, interface) } /// `setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, nodelay)` @@ -574,7 +618,7 @@ pub fn set_ipv6_drop_membership( #[inline] #[doc(alias = "TCP_NODELAY")] pub fn set_tcp_nodelay(fd: Fd, nodelay: bool) -> io::Result<()> { - imp::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), nodelay) + backend::net::syscalls::sockopt::set_tcp_nodelay(fd.as_fd(), nodelay) } /// `getsockopt(fd, IPPROTO_TCP, TCP_NODELAY)` @@ -596,5 +640,5 @@ pub fn set_tcp_nodelay(fd: Fd, nodelay: bool) -> io::Result<()> { #[inline] #[doc(alias = "TCP_NODELAY")] pub fn get_tcp_nodelay(fd: Fd) -> io::Result { - imp::net::syscalls::sockopt::get_tcp_nodelay(fd.as_fd()) + backend::net::syscalls::sockopt::get_tcp_nodelay(fd.as_fd()) } diff --git a/vendor/rustix/src/net/wsa.rs b/vendor/rustix/src/net/wsa.rs index e2a70c97b..3367ca95c 100644 --- a/vendor/rustix/src/net/wsa.rs +++ b/vendor/rustix/src/net/wsa.rs @@ -1,6 +1,6 @@ use crate::io; use core::mem::MaybeUninit; -use windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAData, WSAGetLastError, WSAStartup}; +use windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAGetLastError, WSAStartup, WSADATA}; /// `WSAStartup()`—Initialize process-wide Windows support for sockets. /// @@ -11,7 +11,7 @@ use windows_sys::Win32::Networking::WinSock::{WSACleanup, WSAData, WSAGetLastErr /// - [Winsock2] /// /// [Winsock2]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastartup -pub fn wsa_startup() -> io::Result { +pub fn wsa_startup() -> io::Result { // Request version 2.2, which has been the latest version since far older // versions of Windows than we support here. For more information about // the version, see [here]. diff --git a/vendor/rustix/src/param/auxv.rs b/vendor/rustix/src/param/auxv.rs index 6aec061f7..03be2a29d 100644 --- a/vendor/rustix/src/param/auxv.rs +++ b/vendor/rustix/src/param/auxv.rs @@ -1,3 +1,4 @@ +use crate::backend; #[cfg(any( linux_raw, all( @@ -9,7 +10,6 @@ ) ))] use crate::ffi::CStr; -use crate::imp; /// `sysconf(_SC_PAGESIZE)`—Returns the process' page size. /// @@ -28,7 +28,7 @@ use crate::imp; #[doc(alias = "_SC_PAGE_SIZE")] #[doc(alias = "getpagesize")] pub fn page_size() -> usize { - imp::param::auxv::page_size() + backend::param::auxv::page_size() } /// `sysconf(_SC_CLK_TCK)`—Returns the process' clock ticks per second. @@ -43,7 +43,7 @@ pub fn page_size() -> usize { #[inline] #[doc(alias = "_SC_CLK_TCK")] pub fn clock_ticks_per_second() -> u64 { - imp::param::auxv::clock_ticks_per_second() + backend::param::auxv::clock_ticks_per_second() } /// `(getauxval(AT_HWCAP), getauxval(AT_HWCAP2)`—Returns the Linux "hwcap" @@ -68,7 +68,7 @@ pub fn clock_ticks_per_second() -> u64 { ))] #[inline] pub fn linux_hwcap() -> (usize, usize) { - imp::param::auxv::linux_hwcap() + backend::param::auxv::linux_hwcap() } /// `getauxval(AT_EXECFN)`—Returns the Linux "execfn" string. @@ -92,5 +92,5 @@ pub fn linux_hwcap() -> (usize, usize) { ))] #[inline] pub fn linux_execfn() -> &'static CStr { - imp::param::auxv::linux_execfn() + backend::param::auxv::linux_execfn() } diff --git a/vendor/rustix/src/param/init.rs b/vendor/rustix/src/param/init.rs index e66ff82bb..d261fabd2 100644 --- a/vendor/rustix/src/param/init.rs +++ b/vendor/rustix/src/param/init.rs @@ -7,7 +7,7 @@ //! operates on raw pointers. #![allow(unsafe_code)] -use crate::imp; +use crate::backend; /// Initialize process-wide state. /// @@ -19,5 +19,5 @@ use crate::imp; #[inline] #[doc(hidden)] pub unsafe fn init(envp: *mut *mut u8) { - imp::param::auxv::init(envp) + backend::param::auxv::init(envp) } diff --git a/vendor/rustix/src/param/mod.rs b/vendor/rustix/src/param/mod.rs index 5169d0a51..c47aca985 100644 --- a/vendor/rustix/src/param/mod.rs +++ b/vendor/rustix/src/param/mod.rs @@ -7,10 +7,7 @@ #[cfg(feature = "param")] mod auxv; -#[cfg(any( - target_vendor = "mustang", - not(any(target_env = "gnu", target_env = "musl")), -))] +#[cfg(target_vendor = "mustang")] mod init; #[cfg(feature = "param")] @@ -30,8 +27,5 @@ pub use auxv::page_size; ) ))] pub use auxv::{linux_execfn, linux_hwcap}; -#[cfg(any( - target_vendor = "mustang", - not(any(target_env = "gnu", target_env = "musl")), -))] +#[cfg(target_vendor = "mustang")] pub use init::init; diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs index 7f66f71f2..0ea673d19 100644 --- a/vendor/rustix/src/path/arg.rs +++ b/vendor/rustix/src/path/arg.rs @@ -15,7 +15,8 @@ use alloc::borrow::Cow; use alloc::borrow::ToOwned; use alloc::string::String; use alloc::vec::Vec; -use core::str; +use core::mem::MaybeUninit; +use core::{ptr, slice, str}; #[cfg(feature = "std")] use std::ffi::{OsStr, OsString}; #[cfg(feature = "std")] @@ -931,6 +932,7 @@ impl Arg for DecInt { } /// Runs a closure with `bytes` passed in as a `&CStr`. +#[allow(unsafe_code, clippy::int_plus_one)] #[inline] fn with_c_str(bytes: &[u8], f: F) -> io::Result where @@ -946,10 +948,26 @@ where if bytes.len() >= SMALL_PATH_BUFFER_SIZE { return with_c_str_slow_path(bytes, f); } - let mut buffer: [u8; SMALL_PATH_BUFFER_SIZE] = [0_u8; SMALL_PATH_BUFFER_SIZE]; - // Copy the bytes in; the buffer already has zeros for the trailing NUL. - buffer[..bytes.len()].copy_from_slice(bytes); - f(CStr::from_bytes_with_nul(&buffer[..=bytes.len()]).map_err(|_cstr_err| io::Errno::INVAL)?) + + // Taken from + // https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs + let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit(); + let buf_ptr = buf.as_mut_ptr() as *mut u8; + + // SAFETY: bytes.len() < SMALL_PATH_BUFFER_SIZE which means we have space for + // bytes.len() + 1 u8s: + debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE); + unsafe { + ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); + buf_ptr.add(bytes.len()).write(0); + } + + // SAFETY: we just wrote the bytes above and they will remain valid for the + // duration of f b/c buf doesn't get dropped until the end of the function. + match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { + Ok(s) => f(s), + Err(_) => Err(io::Errno::INVAL), + } } /// The slow path which handles any length. In theory OS's only support up diff --git a/vendor/rustix/src/path/dec_int.rs b/vendor/rustix/src/path/dec_int.rs index 4006fb06c..d0975694b 100644 --- a/vendor/rustix/src/path/dec_int.rs +++ b/vendor/rustix/src/path/dec_int.rs @@ -6,8 +6,8 @@ //! `str::from_utf8_unchecked`on the buffer that it filled itself. #![allow(unsafe_code)] +use crate::backend::fd::{AsFd, AsRawFd}; use crate::ffi::CStr; -use crate::imp::fd::{AsFd, AsRawFd}; #[cfg(feature = "std")] use core::fmt; use core::fmt::Write; diff --git a/vendor/rustix/src/process/chdir.rs b/vendor/rustix/src/process/chdir.rs index d8e251074..4951e5670 100644 --- a/vendor/rustix/src/process/chdir.rs +++ b/vendor/rustix/src/process/chdir.rs @@ -1,9 +1,9 @@ use crate::ffi::CString; use crate::path::SMALL_PATH_BUFFER_SIZE; -use crate::{imp, io, path}; +use crate::{backend, io, path}; use alloc::vec::Vec; #[cfg(not(target_os = "fuchsia"))] -use imp::fd::AsFd; +use backend::fd::AsFd; /// `chdir(path)`—Change the current working directory. /// @@ -15,7 +15,7 @@ use imp::fd::AsFd; /// [Linux]: https://man7.org/linux/man-pages/man2/chdir.2.html #[inline] pub fn chdir(path: P) -> io::Result<()> { - path.into_with_c_str(imp::process::syscalls::chdir) + path.into_with_c_str(backend::process::syscalls::chdir) } /// `fchdir(fd)`—Change the current working directory. @@ -29,7 +29,7 @@ pub fn chdir(path: P) -> io::Result<()> { #[cfg(not(target_os = "fuchsia"))] #[inline] pub fn fchdir(fd: Fd) -> io::Result<()> { - imp::process::syscalls::fchdir(fd.as_fd()) + backend::process::syscalls::fchdir(fd.as_fd()) } /// `getcwd()`—Return the current working directory. @@ -56,7 +56,7 @@ fn _getcwd(mut buffer: Vec) -> io::Result { buffer.resize(buffer.capacity(), 0_u8); loop { - match imp::process::syscalls::getcwd(&mut buffer) { + match backend::process::syscalls::getcwd(&mut buffer) { Err(io::Errno::RANGE) => { buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially buffer.resize(buffer.capacity(), 0_u8); diff --git a/vendor/rustix/src/process/exit.rs b/vendor/rustix/src/process/exit.rs index 26a2340ab..56db99b4f 100644 --- a/vendor/rustix/src/process/exit.rs +++ b/vendor/rustix/src/process/exit.rs @@ -1,4 +1,4 @@ -use crate::imp; +use crate::backend; /// `EXIT_SUCCESS` for use with [`exit`]. /// @@ -10,7 +10,7 @@ use crate::imp; /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html /// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_SUCCESS: i32 = imp::process::types::EXIT_SUCCESS; +pub const EXIT_SUCCESS: i32 = backend::process::types::EXIT_SUCCESS; /// `EXIT_FAILURE` for use with [`exit`]. /// @@ -22,7 +22,7 @@ pub const EXIT_SUCCESS: i32 = imp::process::types::EXIT_SUCCESS; /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html /// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_FAILURE: i32 = imp::process::types::EXIT_FAILURE; +pub const EXIT_FAILURE: i32 = backend::process::types::EXIT_FAILURE; /// The exit status used by a process terminated with `SIGABRT` signal. /// @@ -31,4 +31,4 @@ pub const EXIT_FAILURE: i32 = imp::process::types::EXIT_FAILURE; /// /// [Linux]: https://tldp.org/LDP/abs/html/exitcodes.html #[cfg(not(target_os = "wasi"))] -pub const EXIT_SIGNALED_SIGABRT: i32 = imp::process::types::EXIT_SIGNALED_SIGABRT; +pub const EXIT_SIGNALED_SIGABRT: i32 = backend::process::types::EXIT_SIGNALED_SIGABRT; diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs index 5f6ff5bfb..e7fff7e53 100644 --- a/vendor/rustix/src/process/id.rs +++ b/vendor/rustix/src/process/id.rs @@ -7,21 +7,21 @@ //! integer values. #![allow(unsafe_code)] -use crate::{imp, io}; +use crate::{backend, io}; #[cfg(any(target_os = "android", target_os = "linux"))] -use imp::process::types::RawCpuid; +use backend::process::types::RawCpuid; /// The raw integer value of a Unix user ID. -pub use imp::process::types::RawUid; +pub use backend::process::types::RawUid; /// The raw integer value of a Unix group ID. -pub use imp::process::types::RawGid; +pub use backend::process::types::RawGid; /// The raw integer value of a Unix process ID. -pub use imp::process::types::RawPid; +pub use backend::process::types::RawPid; /// The raw integer value of a Unix process ID. -pub use imp::process::types::RawNonZeroPid; +pub use backend::process::types::RawNonZeroPid; /// `uid_t`—A Unix user ID. #[repr(transparent)] @@ -194,7 +194,7 @@ impl Cpuid { #[inline] #[must_use] pub fn getuid() -> Uid { - imp::process::syscalls::getuid() + backend::process::syscalls::getuid() } /// `geteuid()`—Returns the process' effective user ID. @@ -208,7 +208,7 @@ pub fn getuid() -> Uid { #[inline] #[must_use] pub fn geteuid() -> Uid { - imp::process::syscalls::geteuid() + backend::process::syscalls::geteuid() } /// `getgid()`—Returns the process' real group ID. @@ -222,7 +222,7 @@ pub fn geteuid() -> Uid { #[inline] #[must_use] pub fn getgid() -> Gid { - imp::process::syscalls::getgid() + backend::process::syscalls::getgid() } /// `getegid()`—Returns the process' effective group ID. @@ -236,7 +236,7 @@ pub fn getgid() -> Gid { #[inline] #[must_use] pub fn getegid() -> Gid { - imp::process::syscalls::getegid() + backend::process::syscalls::getegid() } /// `getpid()`—Returns the process' ID. @@ -250,7 +250,7 @@ pub fn getegid() -> Gid { #[inline] #[must_use] pub fn getpid() -> Pid { - imp::process::syscalls::getpid() + backend::process::syscalls::getpid() } /// `getppid()`—Returns the parent process' ID. @@ -264,7 +264,34 @@ pub fn getpid() -> Pid { #[inline] #[must_use] pub fn getppid() -> Option { - imp::process::syscalls::getppid() + backend::process::syscalls::getppid() +} + +/// `getpgid(pid)`—Returns the process group ID of the given process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getpgid.2.html +#[inline] +pub fn getpgid(pid: Option) -> io::Result { + backend::process::syscalls::getpgid(pid) +} + +/// `getpgrp()`—Returns the process' group ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getpgrp.2.html +#[inline] +#[must_use] +pub fn getpgrp() -> Pid { + backend::process::syscalls::getpgrp() } /// `setsid()`—Create a new session. @@ -277,7 +304,7 @@ pub fn getppid() -> Option { /// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html #[inline] pub fn setsid() -> io::Result { - imp::process::syscalls::setsid() + backend::process::syscalls::setsid() } // translate_fchown_args returns the raw value of the IDs. In case of `None` diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs index d8daaf8da..69cfba261 100644 --- a/vendor/rustix/src/process/kill.rs +++ b/vendor/rustix/src/process/kill.rs @@ -1,7 +1,7 @@ use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::process::types::Signal; +pub use backend::process::types::Signal; /// `kill(pid, sig)`—Sends a signal to a process. /// @@ -14,7 +14,7 @@ pub use imp::process::types::Signal; #[inline] #[doc(alias = "kill")] pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - imp::process::syscalls::kill_process(pid, sig) + backend::process::syscalls::kill_process(pid, sig) } /// `kill(-pid, sig)`—Sends a signal to all processes in a process group. @@ -32,7 +32,7 @@ pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { #[inline] #[doc(alias = "kill")] pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - imp::process::syscalls::kill_process_group(pid, sig) + backend::process::syscalls::kill_process_group(pid, sig) } /// `kill(0, sig)`—Sends a signal to all processes in the current process @@ -47,5 +47,5 @@ pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { #[inline] #[doc(alias = "kill")] pub fn kill_current_process_group(sig: Signal) -> io::Result<()> { - imp::process::syscalls::kill_current_process_group(sig) + backend::process::syscalls::kill_current_process_group(sig) } diff --git a/vendor/rustix/src/process/membarrier.rs b/vendor/rustix/src/process/membarrier.rs index 0062f273b..b64deb82e 100644 --- a/vendor/rustix/src/process/membarrier.rs +++ b/vendor/rustix/src/process/membarrier.rs @@ -7,9 +7,9 @@ #![allow(unsafe_code)] use crate::process::Cpuid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::process::types::MembarrierCommand; +pub use backend::process::types::MembarrierCommand; #[cfg(any(target_os = "android", target_os = "linux"))] bitflags::bitflags! { @@ -66,7 +66,7 @@ impl MembarrierQuery { #[inline] #[doc(alias = "MEMBARRIER_CMD_QUERY")] pub fn membarrier_query() -> MembarrierQuery { - imp::process::syscalls::membarrier_query() + backend::process::syscalls::membarrier_query() } /// `membarrier(cmd, 0, 0)`—Perform a memory barrier. @@ -77,7 +77,7 @@ pub fn membarrier_query() -> MembarrierQuery { /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html #[inline] pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - imp::process::syscalls::membarrier(cmd) + backend::process::syscalls::membarrier(cmd) } /// `membarrier(cmd, MEMBARRIER_CMD_FLAG_CPU, cpu)`—Perform a memory barrier @@ -89,5 +89,5 @@ pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html #[inline] pub fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - imp::process::syscalls::membarrier_cpu(cmd, cpu) + backend::process::syscalls::membarrier_cpu(cmd, cpu) } diff --git a/vendor/rustix/src/process/mod.rs b/vendor/rustix/src/process/mod.rs index 45673c0ea..e6baa1935 100644 --- a/vendor/rustix/src/process/mod.rs +++ b/vendor/rustix/src/process/mod.rs @@ -9,8 +9,12 @@ mod id; mod kill; #[cfg(any(target_os = "android", target_os = "linux"))] mod membarrier; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod prctl; #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] // WASI doesn't have [gs]etpriority. mod priority; +#[cfg(target_os = "freebsd")] +mod procctl; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] mod rlimit; #[cfg(any( @@ -39,8 +43,8 @@ pub use exit::{EXIT_FAILURE, EXIT_SUCCESS}; pub use id::Cpuid; #[cfg(not(target_os = "wasi"))] pub use id::{ - getegid, geteuid, getgid, getpid, getppid, getuid, setsid, Gid, Pid, RawGid, RawNonZeroPid, - RawPid, RawUid, Uid, + getegid, geteuid, getgid, getpgid, getpgrp, getpid, getppid, getuid, setsid, Gid, Pid, RawGid, + RawNonZeroPid, RawPid, RawUid, Uid, }; #[cfg(not(target_os = "wasi"))] pub use kill::{kill_current_process_group, kill_process, kill_process_group, Signal}; @@ -48,6 +52,8 @@ pub use kill::{kill_current_process_group, kill_process, kill_process_group, Sig pub use membarrier::{ membarrier, membarrier_cpu, membarrier_query, MembarrierCommand, MembarrierQuery, }; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use prctl::*; #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] pub use priority::nice; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] @@ -55,6 +61,8 @@ pub use priority::{ getpriority_pgrp, getpriority_process, getpriority_user, setpriority_pgrp, setpriority_process, setpriority_user, }; +#[cfg(target_os = "freebsd")] +pub use procctl::*; #[cfg(any(target_os = "android", target_os = "linux"))] pub use rlimit::prlimit; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] @@ -73,4 +81,5 @@ pub use uname::{uname, Uname}; pub use wait::{wait, waitpid, WaitOptions, WaitStatus}; #[cfg(not(target_os = "wasi"))] +#[cfg(feature = "fs")] pub(crate) use id::translate_fchown_args; diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs new file mode 100644 index 000000000..49927be25 --- /dev/null +++ b/vendor/rustix/src/process/prctl.rs @@ -0,0 +1,1120 @@ +//! Bindings for the Linux `prctl` system call. +//! +//! There are similarities (but also differences) with FreeBSD's `procctl` system call, whose +//! interface is located in the `procctl.rs` file. + +#![allow(unsafe_code)] + +use core::convert::{TryFrom, TryInto}; +use core::mem::MaybeUninit; +use core::ptr::NonNull; +use core::{mem, ptr}; + +use bitflags::bitflags; + +use crate::backend::c::{c_int, c_uint, c_void}; +use crate::backend::process::syscalls; +use crate::backend::process::types::Signal; +use crate::fd::{AsRawFd, BorrowedFd}; +use crate::ffi::CStr; +use crate::io; +use crate::process::{Pid, RawPid}; + +// +// Helper functions. +// + +#[inline] +pub(crate) unsafe fn prctl_1arg(option: c_int) -> io::Result { + const NULL: *mut c_void = ptr::null_mut(); + syscalls::prctl(option, NULL, NULL, NULL, NULL) +} + +#[inline] +pub(crate) unsafe fn prctl_2args(option: c_int, arg2: *mut c_void) -> io::Result { + const NULL: *mut c_void = ptr::null_mut(); + syscalls::prctl(option, arg2, NULL, NULL, NULL) +} + +#[inline] +pub(crate) unsafe fn prctl_3args( + option: c_int, + arg2: *mut c_void, + arg3: *mut c_void, +) -> io::Result { + syscalls::prctl(option, arg2, arg3, ptr::null_mut(), ptr::null_mut()) +} + +#[inline] +pub(crate) unsafe fn prctl_get_at_arg2_optional

(option: i32) -> io::Result

{ + let mut value: MaybeUninit

= MaybeUninit::uninit(); + prctl_2args(option, value.as_mut_ptr().cast())?; + Ok(value.assume_init()) +} + +#[inline] +pub(crate) unsafe fn prctl_get_at_arg2(option: i32) -> io::Result +where + P: Default, + T: TryFrom, +{ + let mut value: P = Default::default(); + prctl_2args(option, ((&mut value) as *mut P).cast())?; + TryFrom::try_from(value) +} + +// +// PR_GET_PDEATHSIG/PR_SET_PDEATHSIG +// + +const PR_GET_PDEATHSIG: c_int = 2; + +/// Get the current value of the parent process death signal. +/// +/// # References +/// - [Linux: `prctl(PR_GET_PDEATHSIG,...)`] +/// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`] +/// +/// [Linux: `prctl(PR_GET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn parent_process_death_signal() -> io::Result> { + unsafe { prctl_get_at_arg2_optional::(PR_GET_PDEATHSIG) }.map(Signal::from_raw) +} + +const PR_SET_PDEATHSIG: c_int = 1; + +/// Set the parent-death signal of the calling process. +/// +/// # References +/// - [Linux: `prctl(PR_SET_PDEATHSIG,...)`] +/// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`] +/// +/// [Linux: `prctl(PR_SET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn set_parent_process_death_signal(signal: Option) -> io::Result<()> { + let signal = signal.map_or(0_usize, |signal| signal as usize); + unsafe { prctl_2args(PR_SET_PDEATHSIG, signal as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_DUMPABLE/PR_SET_DUMPABLE +// + +const PR_GET_DUMPABLE: c_int = 3; + +const SUID_DUMP_DISABLE: i32 = 0; +const SUID_DUMP_USER: i32 = 1; +const SUID_DUMP_ROOT: i32 = 2; + +/// `SUID_DUMP_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum DumpableBehavior { + /// Not dumpable. + NotDumpable = SUID_DUMP_DISABLE, + /// Dumpable. + Dumpable = SUID_DUMP_USER, + /// Dumpable but only readable by root. + DumpableReadableOnlyByRoot = SUID_DUMP_ROOT, +} + +impl TryFrom for DumpableBehavior { + type Error = io::Errno; + + fn try_from(value: i32) -> Result { + match value { + SUID_DUMP_DISABLE => Ok(Self::NotDumpable), + SUID_DUMP_USER => Ok(Self::Dumpable), + SUID_DUMP_ROOT => Ok(Self::DumpableReadableOnlyByRoot), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get the current state of the calling process's `dumpable` attribute. +/// +/// # References +/// - [`prctl(PR_GET_DUMPABLE,...)`] +/// +/// [`prctl(PR_GET_DUMPABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn dumpable_behavior() -> io::Result { + unsafe { prctl_1arg(PR_GET_DUMPABLE) }.and_then(TryInto::try_into) +} + +const PR_SET_DUMPABLE: c_int = 4; + +/// Set the state of the `dumpable` attribute, which determines whether the process can be traced +/// and whether core dumps are produced for the calling process upon delivery of a signal whose +/// default behavior is to produce a core dump. +/// +/// A similar function with the same name is available on FreeBSD (as part of the `procctl` +/// interface), but it has an extra argument which allows to select a process other then the +/// current process. +/// +/// # References +/// - [`prctl(PR_SET_DUMPABLE,...)`] +/// +/// [`prctl(PR_SET_DUMPABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_dumpable_behavior(config: DumpableBehavior) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_DUMPABLE, config as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_UNALIGN/PR_SET_UNALIGN +// + +const PR_GET_UNALIGN: c_int = 5; + +bitflags! { + /// `PR_UNALIGN_*`. + pub struct UnalignedAccessControl: u32 { + /// Silently fix up unaligned user accesses. + const NO_PRINT = 1; + /// Generate `SIGBUS` on unaligned user access. + const SIGBUS = 2; + } +} + +/// Get unaligned access control bits. +/// +/// # References +/// - [`prctl(PR_GET_UNALIGN,...)`] +/// +/// [`prctl(PR_GET_UNALIGN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn unaligned_access_control() -> io::Result { + let r = unsafe { prctl_get_at_arg2_optional::(PR_GET_UNALIGN)? }; + UnalignedAccessControl::from_bits(r).ok_or(io::Errno::RANGE) +} + +const PR_SET_UNALIGN: c_int = 6; + +/// Set unaligned access control bits. +/// +/// # References +/// - [`prctl(PR_SET_UNALIGN,...)`] +/// +/// [`prctl(PR_SET_UNALIGN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_unaligned_access_control(config: UnalignedAccessControl) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_UNALIGN, config.bits() as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_FPEMU/PR_SET_FPEMU +// + +const PR_GET_FPEMU: c_int = 9; + +bitflags! { + /// `PR_FPEMU_*`. + pub struct FloatingPointEmulationControl: u32 { + /// Silently emulate floating point operations accesses. + const NO_PRINT = 1; + /// Don't emulate floating point operations, send `SIGFPE` instead. + const SIGFPE = 2; + } +} + +/// Get floating point emulation control bits. +/// +/// # References +/// - [`prctl(PR_GET_FPEMU,...)`] +/// +/// [`prctl(PR_GET_FPEMU,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn floating_point_emulation_control() -> io::Result { + let r = unsafe { prctl_get_at_arg2_optional::(PR_GET_FPEMU)? }; + FloatingPointEmulationControl::from_bits(r).ok_or(io::Errno::RANGE) +} + +const PR_SET_FPEMU: c_int = 10; + +/// Set floating point emulation control bits. +/// +/// # References +/// - [`prctl(PR_SET_FPEMU,...)`] +/// +/// [`prctl(PR_SET_FPEMU,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_floating_point_emulation_control( + config: FloatingPointEmulationControl, +) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_FPEMU, config.bits() as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_FPEXC/PR_SET_FPEXC +// + +const PR_GET_FPEXC: c_int = 11; + +bitflags! { + /// Zero means floating point exceptions are disabled. + pub struct FloatingPointExceptionMode: u32 { + /// Async non-recoverable exception mode. + const NONRECOV = 1; + /// Async recoverable exception mode. + const ASYNC = 2; + /// Precise exception mode. + const PRECISE = 3; + + /// Use FPEXC for floating point exception enables. + const SW_ENABLE = 0x80; + /// Floating point divide by zero. + const DIV = 0x01_0000; + /// Floating point overflow. + const OVF = 0x02_0000; + /// Floating point underflow. + const UND = 0x04_0000; + /// Floating point inexact result. + const RES = 0x08_0000; + /// Floating point invalid operation. + const INV = 0x10_0000; + } +} + +/// Get floating point exception mode. +/// +/// # References +/// - [`prctl(PR_GET_FPEXC,...)`] +/// +/// [`prctl(PR_GET_FPEXC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn floating_point_exception_mode() -> io::Result> { + unsafe { prctl_get_at_arg2_optional::(PR_GET_FPEXC) } + .map(FloatingPointExceptionMode::from_bits) +} + +const PR_SET_FPEXC: c_int = 12; + +/// Set floating point exception mode. +/// +/// # References +/// - [`prctl(PR_SET_FPEXC,...)`] +/// +/// [`prctl(PR_SET_FPEXC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_floating_point_exception_mode( + config: Option, +) -> io::Result<()> { + let config = config.as_ref().map_or(0, FloatingPointExceptionMode::bits); + unsafe { prctl_2args(PR_SET_FPEXC, config as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_TIMING/PR_SET_TIMING +// + +const PR_GET_TIMING: c_int = 13; + +const PR_TIMING_STATISTICAL: i32 = 0; +const PR_TIMING_TIMESTAMP: i32 = 1; + +/// `PR_TIMING_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum TimingMethod { + /// Normal, traditional, statistical process timing. + Statistical = PR_TIMING_STATISTICAL, + /// Accurate timestamp based process timing. + TimeStamp = PR_TIMING_TIMESTAMP, +} + +impl TryFrom for TimingMethod { + type Error = io::Errno; + + fn try_from(value: i32) -> Result { + match value { + PR_TIMING_STATISTICAL => Ok(Self::Statistical), + PR_TIMING_TIMESTAMP => Ok(Self::TimeStamp), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get which process timing method is currently in use. +/// +/// # References +/// - [`prctl(PR_GET_TIMING,...)`] +/// +/// [`prctl(PR_GET_TIMING,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn timing_method() -> io::Result { + unsafe { prctl_1arg(PR_GET_TIMING) }.and_then(TryInto::try_into) +} + +const PR_SET_TIMING: c_int = 14; + +/// Set whether to use (normal, traditional) statistical process timing or accurate +/// timestamp-based process timing. +/// +/// # References +/// - [`prctl(PR_SET_TIMING,...)`] +/// +/// [`prctl(PR_SET_TIMING,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_timing_method(method: TimingMethod) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_TIMING, method as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_ENDIAN/PR_SET_ENDIAN +// + +const PR_GET_ENDIAN: c_int = 19; + +const PR_ENDIAN_BIG: u32 = 0; +const PR_ENDIAN_LITTLE: u32 = 1; +const PR_ENDIAN_PPC_LITTLE: u32 = 2; + +/// `PR_ENDIAN_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum EndianMode { + /// Big endian mode. + Big = PR_ENDIAN_BIG, + /// True little endian mode. + Little = PR_ENDIAN_LITTLE, + /// `PowerPC` pseudo little endian. + PowerPCLittle = PR_ENDIAN_PPC_LITTLE, +} + +impl TryFrom for EndianMode { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + match value { + PR_ENDIAN_BIG => Ok(Self::Big), + PR_ENDIAN_LITTLE => Ok(Self::Little), + PR_ENDIAN_PPC_LITTLE => Ok(Self::PowerPCLittle), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get the endianness of the calling process. +/// +/// # References +/// - [`prctl(PR_GET_ENDIAN,...)`] +/// +/// [`prctl(PR_GET_ENDIAN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn endian_mode() -> io::Result { + unsafe { prctl_get_at_arg2::(PR_GET_ENDIAN) } +} + +const PR_SET_ENDIAN: c_int = 20; + +/// Set the endianness of the calling process. +/// +/// # References +/// - [`prctl(PR_SET_ENDIAN,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_ENDIAN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn set_endian_mode(mode: EndianMode) -> io::Result<()> { + prctl_2args(PR_SET_ENDIAN, mode as usize as *mut _).map(|_r| ()) +} + +// +// PR_GET_TSC/PR_SET_TSC +// + +const PR_GET_TSC: c_int = 25; + +const PR_TSC_ENABLE: u32 = 1; +const PR_TSC_SIGSEGV: u32 = 2; + +/// `PR_TSC_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum TimeStampCounterReadability { + /// Allow the use of the timestamp counter. + Readable = PR_TSC_ENABLE, + /// Throw a `SIGSEGV` instead of reading the TSC. + RaiseSIGSEGV = PR_TSC_SIGSEGV, +} + +impl TryFrom for TimeStampCounterReadability { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + match value { + PR_TSC_ENABLE => Ok(Self::Readable), + PR_TSC_SIGSEGV => Ok(Self::RaiseSIGSEGV), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get the state of the flag determining if the timestamp counter can be read. +/// +/// # References +/// - [`prctl(PR_GET_TSC,...)`] +/// +/// [`prctl(PR_GET_TSC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn time_stamp_counter_readability() -> io::Result { + unsafe { prctl_get_at_arg2::(PR_GET_TSC) } +} + +const PR_SET_TSC: c_int = 26; + +/// Set the state of the flag determining if the timestamp counter can be read by the process. +/// +/// # References +/// - [`prctl(PR_SET_TSC,...)`] +/// +/// [`prctl(PR_SET_TSC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_time_stamp_counter_readability( + readability: TimeStampCounterReadability, +) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_TSC, readability as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_TASK_PERF_EVENTS_DISABLE/PR_TASK_PERF_EVENTS_ENABLE +// + +const PR_TASK_PERF_EVENTS_DISABLE: c_int = 31; +const PR_TASK_PERF_EVENTS_ENABLE: c_int = 32; + +/// Enable or disable all performance counters attached to the calling process. +/// +/// # References +/// - [`prctl(PR_TASK_PERF_EVENTS_ENABLE,...)`] +/// - [`prctl(PR_TASK_PERF_EVENTS_DISABLE,...)`] +/// +/// [`prctl(PR_TASK_PERF_EVENTS_ENABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +/// [`prctl(PR_TASK_PERF_EVENTS_DISABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn configure_performance_counters(enable: bool) -> io::Result<()> { + let option = if enable { + PR_TASK_PERF_EVENTS_ENABLE + } else { + PR_TASK_PERF_EVENTS_DISABLE + }; + + unsafe { prctl_1arg(option) }.map(|_r| ()) +} + +// +// PR_MCE_KILL_GET/PR_MCE_KILL +// + +const PR_MCE_KILL_GET: c_int = 34; + +const PR_MCE_KILL_LATE: u32 = 0; +const PR_MCE_KILL_EARLY: u32 = 1; +const PR_MCE_KILL_DEFAULT: u32 = 2; + +/// `PR_MCE_KILL_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum MachineCheckMemoryCorruptionKillPolicy { + /// Late kill policy. + Late = PR_MCE_KILL_LATE, + /// Early kill policy. + Early = PR_MCE_KILL_EARLY, + /// System-wide default policy. + Default = PR_MCE_KILL_DEFAULT, +} + +impl TryFrom for MachineCheckMemoryCorruptionKillPolicy { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + match value { + PR_MCE_KILL_LATE => Ok(Self::Late), + PR_MCE_KILL_EARLY => Ok(Self::Early), + PR_MCE_KILL_DEFAULT => Ok(Self::Default), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get the current per-process machine check kill policy. +/// +/// # References +/// - [`prctl(PR_MCE_KILL_GET,...)`] +/// +/// [`prctl(PR_MCE_KILL_GET,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn machine_check_memory_corruption_kill_policy( +) -> io::Result { + let r = unsafe { prctl_1arg(PR_MCE_KILL_GET)? } as c_uint; + MachineCheckMemoryCorruptionKillPolicy::try_from(r) +} + +const PR_MCE_KILL: c_int = 33; + +const PR_MCE_KILL_CLEAR: usize = 0; +const PR_MCE_KILL_SET: usize = 1; + +/// Set the machine check memory corruption kill policy for the calling thread. +/// +/// # References +/// - [`prctl(PR_MCE_KILL,...)`] +/// +/// [`prctl(PR_MCE_KILL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_machine_check_memory_corruption_kill_policy( + policy: Option, +) -> io::Result<()> { + let (sub_operation, policy) = if let Some(policy) = policy { + (PR_MCE_KILL_SET, policy as usize as *mut _) + } else { + (PR_MCE_KILL_CLEAR, ptr::null_mut()) + }; + + unsafe { prctl_3args(PR_MCE_KILL, sub_operation as *mut _, policy) }.map(|_r| ()) +} + +// +// PR_SET_MM +// + +const PR_SET_MM: c_int = 35; + +const PR_SET_MM_START_CODE: u32 = 1; +const PR_SET_MM_END_CODE: u32 = 2; +const PR_SET_MM_START_DATA: u32 = 3; +const PR_SET_MM_END_DATA: u32 = 4; +const PR_SET_MM_START_STACK: u32 = 5; +const PR_SET_MM_START_BRK: u32 = 6; +const PR_SET_MM_BRK: u32 = 7; +const PR_SET_MM_ARG_START: u32 = 8; +const PR_SET_MM_ARG_END: u32 = 9; +const PR_SET_MM_ENV_START: u32 = 10; +const PR_SET_MM_ENV_END: u32 = 11; +const PR_SET_MM_AUXV: usize = 12; +const PR_SET_MM_EXE_FILE: usize = 13; +const PR_SET_MM_MAP: usize = 14; +const PR_SET_MM_MAP_SIZE: usize = 15; + +/// `PR_SET_MM_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum VirtualMemoryMapAddress { + /// Set the address above which the program text can run. + CodeStart = PR_SET_MM_START_CODE, + /// Set the address below which the program text can run. + CodeEnd = PR_SET_MM_END_CODE, + /// Set the address above which initialized and uninitialized (bss) data are placed. + DataStart = PR_SET_MM_START_DATA, + /// Set the address below which initialized and uninitialized (bss) data are placed. + DataEnd = PR_SET_MM_END_DATA, + /// Set the start address of the stack. + StackStart = PR_SET_MM_START_STACK, + /// Set the address above which the program heap can be expanded with `brk` call. + BrkStart = PR_SET_MM_START_BRK, + /// Set the current `brk` value. + BrkCurrent = PR_SET_MM_BRK, + /// Set the address above which the program command line is placed. + ArgStart = PR_SET_MM_ARG_START, + /// Set the address below which the program command line is placed. + ArgEnd = PR_SET_MM_ARG_END, + /// Set the address above which the program environment is placed. + EnvironmentStart = PR_SET_MM_ENV_START, + /// Set the address below which the program environment is placed. + EnvironmentEnd = PR_SET_MM_ENV_END, +} + +/// Modify certain kernel memory map descriptor addresses of the calling process. +/// +/// # References +/// - [`prctl(PR_SET_MM,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_MM,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn set_virtual_memory_map_address( + option: VirtualMemoryMapAddress, + address: Option>, +) -> io::Result<()> { + let address = address.map_or_else(ptr::null_mut, NonNull::as_ptr); + prctl_3args(PR_SET_MM, option as usize as *mut _, address).map(|_r| ()) +} + +/// Supersede the `/proc/pid/exe` symbolic link with a new one pointing to a new executable file. +/// +/// # References +/// - [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,...)`] +/// +/// [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_executable_file(fd: BorrowedFd) -> io::Result<()> { + let fd = usize::try_from(fd.as_raw_fd()).map_err(|_r| io::Errno::RANGE)?; + unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_EXE_FILE as *mut _, fd as *mut _) }.map(|_r| ()) +} + +/// Set a new auxiliary vector. +/// +/// # References +/// - [`prctl(PR_SET_MM,PR_SET_MM_AUXV,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_MM,PR_SET_MM_AUXV,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn set_auxiliary_vector(auxv: &[*const c_void]) -> io::Result<()> { + syscalls::prctl( + PR_SET_MM, + PR_SET_MM_AUXV as *mut _, + auxv.as_ptr() as *mut _, + auxv.len() as *mut _, + ptr::null_mut(), + ) + .map(|_r| ()) +} + +/// Get the size of the [`PrctlMmMap`] the kernel expects. +/// +/// # References +/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,...)`] +/// +/// [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn virtual_memory_map_config_struct_size() -> io::Result { + let mut value: c_uint = 0; + let value_ptr = (&mut value) as *mut c_uint; + unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_MAP_SIZE as *mut _, value_ptr.cast())? }; + Ok(value as usize) +} + +/// This structure provides new memory descriptor map which mostly modifies `/proc/pid/stat[m]` +/// output for a task. +/// This mostly done in a sake of checkpoint/restore functionality. +#[repr(C)] +#[derive(Debug, Clone)] +pub struct PrctlMmMap { + /// Code section start address. + pub start_code: u64, + /// Code section end address. + pub end_code: u64, + /// Data section start address. + pub start_data: u64, + /// Data section end address. + pub end_data: u64, + /// brk() start address. + pub start_brk: u64, + /// brk() current address. + pub brk: u64, + /// Stack start address. + pub start_stack: u64, + /// Program command line start address. + pub arg_start: u64, + /// Program command line end address. + pub arg_end: u64, + /// Program environment start address. + pub env_start: u64, + /// Program environment end address. + pub env_end: u64, + /// Auxiliary vector start address. + pub auxv: *mut u64, + /// Auxiliary vector size. + pub auxv_size: u32, + /// File descriptor of executable file that was used to create this process. + pub exe_fd: u32, +} + +/// Provides one-shot access to all the addresses by passing in a [`PrctlMmMap`]. +/// +/// # References +/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_MM,PR_SET_MM_MAP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn configure_virtual_memory_map(config: &PrctlMmMap) -> io::Result<()> { + syscalls::prctl( + PR_SET_MM, + PR_SET_MM_MAP as *mut _, + config as *const PrctlMmMap as *mut _, + mem::size_of::() as *mut _, + ptr::null_mut(), + ) + .map(|_r| ()) +} + +// +// PR_SET_PTRACER +// + +const PR_SET_PTRACER: c_int = 0x59_61_6d_61; + +const PR_SET_PTRACER_ANY: usize = usize::MAX; + +/// Process ptracer. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum PTracer { + /// None. + None, + /// Disable `ptrace` restrictions for the calling process. + Any, + /// Specific process. + ProcessID(Pid), +} + +/// Declare that the ptracer process can `ptrace` the calling process as if it were a direct +/// process ancestor. +/// +/// # References +/// - [`prctl(PR_SET_PTRACER,...)`] +/// +/// [`prctl(PR_SET_PTRACER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_ptracer(tracer: PTracer) -> io::Result<()> { + let pid = match tracer { + PTracer::None => ptr::null_mut(), + PTracer::Any => PR_SET_PTRACER_ANY as *mut _, + PTracer::ProcessID(pid) => pid.as_raw_nonzero().get() as usize as *mut _, + }; + + unsafe { prctl_2args(PR_SET_PTRACER, pid) }.map(|_r| ()) +} + +// +// PR_GET_CHILD_SUBREAPER/PR_SET_CHILD_SUBREAPER +// + +const PR_GET_CHILD_SUBREAPER: c_int = 37; + +/// Get the `child subreaper` setting of the calling process. +/// +/// # References +/// - [`prctl(PR_GET_CHILD_SUBREAPER,...)`] +/// +/// [`prctl(PR_GET_CHILD_SUBREAPER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn child_subreaper() -> io::Result> { + unsafe { + let r = prctl_get_at_arg2_optional::(PR_GET_CHILD_SUBREAPER)?; + Ok(Pid::from_raw(r as RawPid)) + } +} + +const PR_SET_CHILD_SUBREAPER: c_int = 36; + +/// Set the `child subreaper` attribute of the calling process. +/// +/// # References +/// - [`prctl(PR_SET_CHILD_SUBREAPER,...)`] +/// +/// [`prctl(PR_SET_CHILD_SUBREAPER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_child_subreaper(pid: Option) -> io::Result<()> { + let pid = pid.map_or(0_usize, |pid| pid.as_raw_nonzero().get() as usize); + unsafe { prctl_2args(PR_SET_CHILD_SUBREAPER, pid as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_FP_MODE/PR_SET_FP_MODE +// + +const PR_GET_FP_MODE: c_int = 46; + +const PR_FP_MODE_FR: u32 = 1_u32 << 0; +const PR_FP_MODE_FRE: u32 = 1_u32 << 1; + +/// `PR_FP_MODE_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum FloatingPointMode { + /// 64-bit floating point registers. + FloatingPointRegisters = PR_FP_MODE_FR, + /// Enable emulation of 32-bit floating-point mode. + FloatingPointEmulation = PR_FP_MODE_FRE, +} + +impl TryFrom for FloatingPointMode { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + match value { + PR_FP_MODE_FR => Ok(Self::FloatingPointRegisters), + PR_FP_MODE_FRE => Ok(Self::FloatingPointEmulation), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get the current floating point mode. +/// +/// # References +/// - [`prctl(PR_GET_FP_MODE,...)`] +/// +/// [`prctl(PR_GET_FP_MODE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn floating_point_mode() -> io::Result { + let r = unsafe { prctl_1arg(PR_GET_FP_MODE)? } as c_uint; + FloatingPointMode::try_from(r) +} + +const PR_SET_FP_MODE: c_int = 45; + +/// Allow control of the floating point mode from user space. +/// +/// # References +/// - [`prctl(PR_SET_FP_MODE,...)`] +/// +/// [`prctl(PR_SET_FP_MODE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_floating_point_mode(mode: FloatingPointMode) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_FP_MODE, mode as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_SPECULATION_CTRL/PR_SET_SPECULATION_CTRL +// + +const PR_GET_SPECULATION_CTRL: c_int = 52; + +const PR_SPEC_STORE_BYPASS: u32 = 0; +const PR_SPEC_INDIRECT_BRANCH: u32 = 1; +const PR_SPEC_L1D_FLUSH: u32 = 2; + +/// `PR_SPEC_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum SpeculationFeature { + /// Set the state of the speculative store bypass misfeature. + SpeculativeStoreBypass = PR_SPEC_STORE_BYPASS, + /// Set the state of the indirect branch speculation misfeature. + IndirectBranchSpeculation = PR_SPEC_INDIRECT_BRANCH, + /// Flush L1D Cache on context switch out of the task. + FlushL1DCacheOnContextSwitchOutOfTask = PR_SPEC_L1D_FLUSH, +} + +impl TryFrom for SpeculationFeature { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + match value { + PR_SPEC_STORE_BYPASS => Ok(Self::SpeculativeStoreBypass), + PR_SPEC_INDIRECT_BRANCH => Ok(Self::IndirectBranchSpeculation), + PR_SPEC_L1D_FLUSH => Ok(Self::FlushL1DCacheOnContextSwitchOutOfTask), + _ => Err(io::Errno::RANGE), + } + } +} + +bitflags! { + /// `PR_SPEC_*`. + pub struct SpeculationFeatureControl: u32 { + /// The speculation feature is enabled, mitigation is disabled. + const ENABLE = 1_u32 << 1; + /// The speculation feature is disabled, mitigation is enabled. + const DISABLE = 1_u32 << 2; + /// The speculation feature is disabled, mitigation is enabled, and it cannot be undone. + const FORCE_DISABLE = 1_u32 << 3; + /// The speculation feature is disabled, mitigation is enabled, and the state will be cleared on `execve`. + const DISABLE_NOEXEC = 1_u32 << 4; + } +} + +bitflags! { + /// Zero means the processors are not vulnerable. + pub struct SpeculationFeatureState: u32 { + /// Mitigation can be controlled per thread by `PR_SET_SPECULATION_CTRL`. + const PRCTL = 1_u32 << 0; + /// The speculation feature is enabled, mitigation is disabled. + const ENABLE = 1_u32 << 1; + /// The speculation feature is disabled, mitigation is enabled. + const DISABLE = 1_u32 << 2; + /// The speculation feature is disabled, mitigation is enabled, and it cannot be undone. + const FORCE_DISABLE = 1_u32 << 3; + /// The speculation feature is disabled, mitigation is enabled, and the state will be cleared on `execve`. + const DISABLE_NOEXEC = 1_u32 << 4; + } +} + +/// Get the state of the speculation misfeature. +/// +/// # References +/// - [`prctl(PR_GET_SPECULATION_CTRL,...)`] +/// +/// [`prctl(PR_GET_SPECULATION_CTRL,...)`]: https://www.kernel.org/doc/html/v5.18/userspace-api/spec_ctrl.html +#[inline] +pub fn speculative_feature_state( + feature: SpeculationFeature, +) -> io::Result> { + let r = unsafe { prctl_2args(PR_GET_SPECULATION_CTRL, feature as usize as *mut _)? } as c_uint; + Ok(SpeculationFeatureState::from_bits(r)) +} + +const PR_SET_SPECULATION_CTRL: c_int = 53; + +/// Sets the state of the speculation misfeature. +/// +/// # References +/// - [`prctl(PR_SET_SPECULATION_CTRL,...)`] +/// +/// [`prctl(PR_SET_SPECULATION_CTRL,...)`]: https://www.kernel.org/doc/html/v5.18/userspace-api/spec_ctrl.html +#[inline] +pub fn control_speculative_feature( + feature: SpeculationFeature, + config: SpeculationFeatureControl, +) -> io::Result<()> { + let feature = feature as usize as *mut _; + let config = config.bits() as usize as *mut _; + unsafe { prctl_3args(PR_SET_SPECULATION_CTRL, feature, config) }.map(|_r| ()) +} + +// +// PR_GET_IO_FLUSHER/PR_SET_IO_FLUSHER +// + +const PR_GET_IO_FLUSHER: c_int = 58; + +/// Get the `IO_FLUSHER` state of the caller. +/// +/// # References +/// - [`prctl(PR_GET_IO_FLUSHER,...)`] +/// +/// [`prctl(PR_GET_IO_FLUSHER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn is_io_flusher() -> io::Result { + unsafe { prctl_1arg(PR_GET_IO_FLUSHER) }.map(|r| r != 0) +} + +const PR_SET_IO_FLUSHER: c_int = 57; + +/// Put the process in the `IO_FLUSHER` state, allowing it to make progress when +/// allocating memory. +/// +/// # References +/// - [`prctl(PR_SET_IO_FLUSHER,...)`] +/// +/// [`prctl(PR_SET_IO_FLUSHER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn configure_io_flusher_behavior(enable: bool) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_IO_FLUSHER, enable as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_PAC_GET_ENABLED_KEYS/PR_PAC_SET_ENABLED_KEYS +// + +const PR_PAC_GET_ENABLED_KEYS: c_int = 61; + +bitflags! { + /// `PR_PAC_AP*`. + pub struct PointerAuthenticationKeys: u32 { + /// Instruction authentication key `A`. + const INSTRUCTION_AUTHENTICATION_KEY_A = 1_u32 << 0; + /// Instruction authentication key `B`. + const INSTRUCTION_AUTHENTICATION_KEY_B = 1_u32 << 1; + /// Data authentication key `A`. + const DATA_AUTHENTICATION_KEY_A = 1_u32 << 2; + /// Data authentication key `B`. + const DATA_AUTHENTICATION_KEY_B = 1_u32 << 3; + /// Generic authentication `A` key. + const GENERIC_AUTHENTICATION_KEY_A = 1_u32 << 4; + } +} + +/// Get enabled pointer authentication keys. +/// +/// # References +/// - [`prctl(PR_PAC_GET_ENABLED_KEYS,...)`] +/// +/// [`prctl(PR_PAC_GET_ENABLED_KEYS,...)`]: https://www.kernel.org/doc/html/v5.18/arm64/pointer-authentication.html +#[inline] +pub fn enabled_pointer_authentication_keys() -> io::Result { + let r = unsafe { prctl_1arg(PR_PAC_GET_ENABLED_KEYS)? } as c_uint; + PointerAuthenticationKeys::from_bits(r).ok_or(io::Errno::RANGE) +} + +const PR_PAC_SET_ENABLED_KEYS: c_int = 60; + +/// Set enabled pointer authentication keys. +/// +/// # References +/// - [`prctl(PR_PAC_SET_ENABLED_KEYS,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_PAC_SET_ENABLED_KEYS,...)`]: https://www.kernel.org/doc/html/v5.18/arm64/pointer-authentication.html +#[inline] +pub unsafe fn configure_pointer_authentication_keys( + config: impl Iterator, +) -> io::Result<()> { + let mut affected_keys: u32 = 0; + let mut enabled_keys: u32 = 0; + + for (key, enable) in config { + let key = key.bits(); + affected_keys |= key; + + if enable { + enabled_keys |= key; + } else { + enabled_keys &= !key; + } + } + + if affected_keys == 0 { + return Ok(()); // Nothing to do. + } + + prctl_3args( + PR_PAC_SET_ENABLED_KEYS, + affected_keys as usize as *mut _, + enabled_keys as usize as *mut _, + ) + .map(|_r| ()) +} + +// +// PR_SET_VMA +// + +const PR_SET_VMA: c_int = 0x53_56_4d_41; + +const PR_SET_VMA_ANON_NAME: usize = 0; + +/// Set the name for a virtual memory region. +/// +/// # References +/// - [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,...)`] +/// +/// [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,...)`]: https://lwn.net/Articles/867818/ +#[inline] +pub fn set_virtual_memory_region_name(region: &[u8], name: Option<&CStr>) -> io::Result<()> { + unsafe { + syscalls::prctl( + PR_SET_VMA, + PR_SET_VMA_ANON_NAME as *mut _, + region.as_ptr() as *mut _, + region.len() as *mut _, + name.map_or_else(ptr::null, CStr::as_ptr) as *mut _, + ) + .map(|_r| ()) + } +} diff --git a/vendor/rustix/src/process/priority.rs b/vendor/rustix/src/process/priority.rs index ae43a0b75..4835ceaa2 100644 --- a/vendor/rustix/src/process/priority.rs +++ b/vendor/rustix/src/process/priority.rs @@ -1,5 +1,5 @@ use crate::process::{Pid, Uid}; -use crate::{imp, io}; +use crate::{backend, io}; /// `nice()`—Adjust the scheduling priority of the current process. /// @@ -11,7 +11,7 @@ use crate::{imp, io}; /// [Linux]: https://man7.org/linux/man-pages/man2/nice.2.html #[inline] pub fn nice(inc: i32) -> io::Result { - imp::process::syscalls::nice(inc) + backend::process::syscalls::nice(inc) } /// `getpriority(PRIO_USER, uid)`—Get the scheduling priority of the given @@ -29,7 +29,7 @@ pub fn nice(inc: i32) -> io::Result { #[inline] #[doc(alias = "getpriority")] pub fn getpriority_user(uid: Uid) -> io::Result { - imp::process::syscalls::getpriority_user(uid) + backend::process::syscalls::getpriority_user(uid) } /// `getpriority(PRIO_PGRP, gid)`—Get the scheduling priority of the given @@ -49,7 +49,7 @@ pub fn getpriority_user(uid: Uid) -> io::Result { #[inline] #[doc(alias = "getpriority")] pub fn getpriority_pgrp(pgid: Option) -> io::Result { - imp::process::syscalls::getpriority_pgrp(pgid) + backend::process::syscalls::getpriority_pgrp(pgid) } /// `getpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given @@ -69,7 +69,7 @@ pub fn getpriority_pgrp(pgid: Option) -> io::Result { #[inline] #[doc(alias = "getpriority")] pub fn getpriority_process(pid: Option) -> io::Result { - imp::process::syscalls::getpriority_process(pid) + backend::process::syscalls::getpriority_process(pid) } /// `setpriority(PRIO_USER, uid)`—Get the scheduling priority of the given @@ -87,7 +87,7 @@ pub fn getpriority_process(pid: Option) -> io::Result { #[inline] #[doc(alias = "setpriority")] pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - imp::process::syscalls::setpriority_user(uid, priority) + backend::process::syscalls::setpriority_user(uid, priority) } /// `setpriority(PRIO_PGRP, pgid)`—Get the scheduling priority of the given @@ -107,7 +107,7 @@ pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { #[inline] #[doc(alias = "setpriority")] pub fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { - imp::process::syscalls::setpriority_pgrp(pgid, priority) + backend::process::syscalls::setpriority_pgrp(pgid, priority) } /// `setpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given @@ -127,5 +127,5 @@ pub fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { #[inline] #[doc(alias = "setpriority")] pub fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { - imp::process::syscalls::setpriority_process(pid, priority) + backend::process::syscalls::setpriority_process(pid, priority) } diff --git a/vendor/rustix/src/process/procctl.rs b/vendor/rustix/src/process/procctl.rs new file mode 100644 index 000000000..ff842513f --- /dev/null +++ b/vendor/rustix/src/process/procctl.rs @@ -0,0 +1,180 @@ +//! Bindings for the FreeBSD `procctl` system call. +//! +//! There are similarities (but also differences) with Linux's `prctl` system call, whose interface +//! is located in the `prctl.rs` file. + +#![allow(unsafe_code)] + +use core::mem::MaybeUninit; + +use crate::backend::c::{c_int, c_uint, c_void}; +use crate::backend::process::syscalls; +use crate::backend::process::types::{RawId, Signal}; +use crate::io; +use crate::process::{Pid, RawPid}; + +// +// Helper functions. +// + +/// Subset of `idtype_t` C enum, with only the values allowed by `procctl`. +#[repr(i32)] +pub enum IdType { + /// Process id. + Pid = 0, + /// Process group id. + Pgid = 2, +} + +/// A process selector for use with the `procctl` interface. +/// +/// `None` represents the current process. `Some((IdType::Pid, pid))` represents the process +/// with pid `pid`. `Some((IdType::Pgid, pgid))` represents the control processes belonging to +/// the process group with id `pgid`. +pub type ProcSelector = Option<(IdType, Pid)>; +fn proc_selector_to_raw(selector: ProcSelector) -> (IdType, RawPid) { + match selector { + Some((idtype, id)) => (idtype, id.as_raw_nonzero().get()), + None => (IdType::Pid, 0), + } +} + +#[inline] +pub(crate) unsafe fn procctl( + option: c_int, + process: ProcSelector, + data: *mut c_void, +) -> io::Result<()> { + let (idtype, id) = proc_selector_to_raw(process); + syscalls::procctl(idtype as c_uint, id as RawId, option, data) +} + +#[inline] +pub(crate) unsafe fn procctl_set

( + option: c_int, + process: ProcSelector, + data: &P, +) -> io::Result<()> { + procctl(option, process, (data as *const P as *mut P).cast()) +} + +#[inline] +pub(crate) unsafe fn procctl_get_optional

( + option: c_int, + process: ProcSelector, +) -> io::Result

{ + let mut value: MaybeUninit

= MaybeUninit::uninit(); + procctl(option, process, value.as_mut_ptr().cast())?; + Ok(value.assume_init()) +} + +// +// PROC_PDEATHSIG_STATUS/PROC_PDEATHSIG_CTL +// + +const PROC_PDEATHSIG_STATUS: c_int = 12; + +/// Get the current value of the parent process death signal. +/// +/// # References +/// - [Linux: `prctl(PR_GET_PDEATHSIG,...)`] +/// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`] +/// +/// [Linux: `prctl(PR_GET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn parent_process_death_signal() -> io::Result> { + unsafe { procctl_get_optional::(PROC_PDEATHSIG_STATUS, None) }.map(Signal::from_raw) +} + +const PROC_PDEATHSIG_CTL: c_int = 11; + +/// Set the parent-death signal of the calling process. +/// +/// # References +/// - [Linux: `prctl(PR_SET_PDEATHSIG,...)`] +/// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`] +/// +/// [Linux: `prctl(PR_SET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn set_parent_process_death_signal(signal: Option) -> io::Result<()> { + let signal = signal.map_or(0, |signal| signal as c_int); + unsafe { procctl_set::(PROC_PDEATHSIG_CTL, None, &signal) } +} + +// +// PROC_TRACE_CTL +// + +const PROC_TRACE_CTL: c_int = 7; + +const PROC_TRACE_CTL_ENABLE: i32 = 1; +const PROC_TRACE_CTL_DISABLE: i32 = 2; +const PROC_TRACE_CTL_DISABLE_EXEC: i32 = 3; + +/// `PROC_TRACE_CTL_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum DumpableBehavior { + /// Not dumpable. + NotDumpable = PROC_TRACE_CTL_DISABLE, + /// Dumpable. + Dumpable = PROC_TRACE_CTL_ENABLE, + /// Not dumpable, and this behaviour is preserved across `execve` calls. + NotDumpableExecPreserved = PROC_TRACE_CTL_DISABLE_EXEC, +} + +/// Set the state of the `dumpable` attribute for the process indicated by `idtype` and `id`. +/// This determines whether the process can be traced and whether core dumps are produced for +/// the process upon delivery of a signal whose default behavior is to produce a core dump. +/// +/// This is similar to `set_dumpable_behavior` on Linux, with the exception that on FreeBSD +/// there is an extra argument `process`. When `process` is set to `None`, the operation is +/// performed for the current process, like on Linux. +/// +/// # References +/// - [`procctl(PROC_TRACE_CTL,...)`] +/// +/// [`procctl(PROC_TRACE_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn set_dumpable_behavior(process: ProcSelector, config: DumpableBehavior) -> io::Result<()> { + unsafe { procctl(PROC_TRACE_CTL, process, config as usize as *mut _) } +} + +// +// PROC_TRACE_STATUS +// + +const PROC_TRACE_STATUS: c_int = 8; + +/// Tracing status as returned by [`trace_status`]. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum TracingStatus { + /// Tracing is disabled for the process. + NotTraceble, + /// Tracing is not disabled for the process, but not debugger/tracer is attached. + Tracable, + /// The process is being traced by the process whose pid is stored in the first + /// component of this variant. + BeingTraced(Pid), +} + +/// Get the tracing status of the process indicated by `idtype` and `id`. +/// +/// # References +/// - [`procctl(PROC_TRACE_STATUS,...)`] +/// +/// [`procctl(PROC_TRACE_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn trace_status(process: ProcSelector) -> io::Result { + let val = unsafe { procctl_get_optional::(PROC_TRACE_STATUS, process) }?; + match val { + -1 => Ok(TracingStatus::NotTraceble), + 0 => Ok(TracingStatus::Tracable), + pid => { + let pid = unsafe { Pid::from_raw(pid as RawPid) }.ok_or(io::Errno::RANGE)?; + Ok(TracingStatus::BeingTraced(pid)) + } + } +} diff --git a/vendor/rustix/src/process/rlimit.rs b/vendor/rustix/src/process/rlimit.rs index ffb22d2ae..e8216af79 100644 --- a/vendor/rustix/src/process/rlimit.rs +++ b/vendor/rustix/src/process/rlimit.rs @@ -1,8 +1,8 @@ #[cfg(any(target_os = "android", target_os = "linux"))] use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::process::types::Resource; +pub use backend::process::types::Resource; /// `struct rlimit`—Current and maximum values used in [`getrlimit`], /// [`setrlimit`], and [`prlimit`]. @@ -24,7 +24,7 @@ pub struct Rlimit { /// [Linux]: https://man7.org/linux/man-pages/man2/getrlimit.2.html #[inline] pub fn getrlimit(resource: Resource) -> Rlimit { - imp::process::syscalls::getrlimit(resource) + backend::process::syscalls::getrlimit(resource) } /// `setrlimit(resource, new)`—Set a process resource limit value. @@ -37,7 +37,7 @@ pub fn getrlimit(resource: Resource) -> Rlimit { /// [Linux]: https://man7.org/linux/man-pages/man2/setrlimit.2.html #[inline] pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { - imp::process::syscalls::setrlimit(resource, new) + backend::process::syscalls::setrlimit(resource, new) } /// `prlimit(pid, resource, new)`—Get and set a process resource limit value. @@ -49,5 +49,5 @@ pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { #[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub fn prlimit(pid: Option, resource: Resource, new: Rlimit) -> io::Result { - imp::process::syscalls::prlimit(pid, resource, new) + backend::process::syscalls::prlimit(pid, resource, new) } diff --git a/vendor/rustix/src/process/sched.rs b/vendor/rustix/src/process/sched.rs index 56ba95a6b..88e661670 100644 --- a/vendor/rustix/src/process/sched.rs +++ b/vendor/rustix/src/process/sched.rs @@ -1,5 +1,5 @@ use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; /// `CpuSet` represents a bit-mask of CPUs. /// @@ -15,18 +15,18 @@ use crate::{imp, io}; #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct CpuSet { - cpu_set: imp::process::types::RawCpuSet, + cpu_set: backend::process::types::RawCpuSet, } impl CpuSet { /// The maximum number of CPU in `CpuSet`. - pub const MAX_CPU: usize = imp::process::types::CPU_SETSIZE; + pub const MAX_CPU: usize = backend::process::types::CPU_SETSIZE; /// Create a new and empty `CpuSet`. #[inline] pub fn new() -> Self { Self { - cpu_set: imp::process::types::raw_cpu_set_new(), + cpu_set: backend::process::types::raw_cpu_set_new(), } } @@ -35,7 +35,7 @@ impl CpuSet { /// `field` is the CPU id to test. #[inline] pub fn is_set(&self, field: usize) -> bool { - imp::process::cpu_set::CPU_ISSET(field, &self.cpu_set) + backend::process::cpu_set::CPU_ISSET(field, &self.cpu_set) } /// Add a CPU to `CpuSet`. @@ -43,7 +43,7 @@ impl CpuSet { /// `field` is the CPU id to add. #[inline] pub fn set(&mut self, field: usize) { - imp::process::cpu_set::CPU_SET(field, &mut self.cpu_set) + backend::process::cpu_set::CPU_SET(field, &mut self.cpu_set) } /// Remove a CPU from `CpuSet`. @@ -51,20 +51,20 @@ impl CpuSet { /// `field` is the CPU id to remove. #[inline] pub fn unset(&mut self, field: usize) { - imp::process::cpu_set::CPU_CLR(field, &mut self.cpu_set) + backend::process::cpu_set::CPU_CLR(field, &mut self.cpu_set) } /// Count the number of CPUs set in the `CpuSet`. #[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub fn count(&self) -> u32 { - imp::process::cpu_set::CPU_COUNT(&self.cpu_set) + backend::process::cpu_set::CPU_COUNT(&self.cpu_set) } /// Zeroes the `CpuSet`. #[inline] pub fn clear(&mut self) { - imp::process::cpu_set::CPU_ZERO(&mut self.cpu_set) + backend::process::cpu_set::CPU_ZERO(&mut self.cpu_set) } } @@ -89,7 +89,7 @@ impl Default for CpuSet { /// [Linux]: https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html #[inline] pub fn sched_setaffinity(pid: Option, cpuset: &CpuSet) -> io::Result<()> { - imp::process::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) + backend::process::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) } /// `sched_getaffinity(pid)`—Get a thread's CPU affinity mask. @@ -106,5 +106,5 @@ pub fn sched_setaffinity(pid: Option, cpuset: &CpuSet) -> io::Result<()> { #[inline] pub fn sched_getaffinity(pid: Option) -> io::Result { let mut cpuset = CpuSet::new(); - imp::process::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) + backend::process::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) } diff --git a/vendor/rustix/src/process/sched_yield.rs b/vendor/rustix/src/process/sched_yield.rs index 24367773f..0324f67cb 100644 --- a/vendor/rustix/src/process/sched_yield.rs +++ b/vendor/rustix/src/process/sched_yield.rs @@ -1,4 +1,4 @@ -use crate::imp; +use crate::backend; /// `sched_yield()`—Hints to the OS that other processes should run. /// @@ -12,5 +12,5 @@ use crate::imp; /// [Linux]: https://man7.org/linux/man-pages/man2/sched_yield.2.html #[inline] pub fn sched_yield() { - imp::process::syscalls::sched_yield() + backend::process::syscalls::sched_yield() } diff --git a/vendor/rustix/src/process/uname.rs b/vendor/rustix/src/process/uname.rs index a17d0be7a..95dec2699 100644 --- a/vendor/rustix/src/process/uname.rs +++ b/vendor/rustix/src/process/uname.rs @@ -6,20 +6,20 @@ //! kernel into `&str` references, which assumes that they're NUL-terminated. #![allow(unsafe_code)] +use crate::backend; use crate::ffi::CStr; -use crate::imp; use core::fmt; /// `uname()`—Returns high-level information about the runtime OS and /// hardware. #[inline] pub fn uname() -> Uname { - Uname(imp::process::syscalls::uname()) + Uname(backend::process::syscalls::uname()) } /// `struct utsname`—Return type for [`uname`]. #[doc(alias = "utsname")] -pub struct Uname(imp::process::types::RawUname); +pub struct Uname(backend::process::types::RawUname); impl Uname { /// `sysname`—Operating system release name diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs index 383b34d06..a4bd1b528 100644 --- a/vendor/rustix/src/process/wait.rs +++ b/vendor/rustix/src/process/wait.rs @@ -1,16 +1,16 @@ use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; use bitflags::bitflags; bitflags! { /// Options for modifying the behavior of wait/waitpid pub struct WaitOptions: u32 { /// Return immediately if no child has exited. - const NOHANG = imp::process::wait::WNOHANG as _; + const NOHANG = backend::process::wait::WNOHANG as _; /// Return if a child has stopped (but not traced via `ptrace(2)`) - const UNTRACED = imp::process::wait::WUNTRACED as _; + const UNTRACED = backend::process::wait::WUNTRACED as _; /// Return if a stopped child has been resumed by delivery of `SIGCONT` - const CONTINUED = imp::process::wait::WCONTINUED as _; + const CONTINUED = backend::process::wait::WCONTINUED as _; } } @@ -34,13 +34,13 @@ impl WaitStatus { /// Returns whether the process is currently stopped. #[inline] pub fn stopped(self) -> bool { - imp::process::wait::WIFSTOPPED(self.0 as _) + backend::process::wait::WIFSTOPPED(self.0 as _) } /// Returns whether the process has continued from a job control stop. #[inline] pub fn continued(self) -> bool { - imp::process::wait::WIFCONTINUED(self.0 as _) + backend::process::wait::WIFCONTINUED(self.0 as _) } /// Returns the number of the signal that stopped the process, @@ -48,7 +48,7 @@ impl WaitStatus { #[inline] pub fn stopping_signal(self) -> Option { if self.stopped() { - Some(imp::process::wait::WSTOPSIG(self.0 as _) as _) + Some(backend::process::wait::WSTOPSIG(self.0 as _) as _) } else { None } @@ -58,8 +58,8 @@ impl WaitStatus { /// if it exited normally. #[inline] pub fn exit_status(self) -> Option { - if imp::process::wait::WIFEXITED(self.0 as _) { - Some(imp::process::wait::WEXITSTATUS(self.0 as _) as _) + if backend::process::wait::WIFEXITED(self.0 as _) { + Some(backend::process::wait::WEXITSTATUS(self.0 as _) as _) } else { None } @@ -69,8 +69,8 @@ impl WaitStatus { /// if the process was terminated by a signal. #[inline] pub fn terminating_signal(self) -> Option { - if imp::process::wait::WIFSIGNALED(self.0 as _) { - Some(imp::process::wait::WTERMSIG(self.0 as _) as _) + if backend::process::wait::WIFSIGNALED(self.0 as _) { + Some(backend::process::wait::WTERMSIG(self.0 as _) as _) } else { None } @@ -104,7 +104,7 @@ impl WaitStatus { #[cfg(not(target_os = "wasi"))] #[inline] pub fn waitpid(pid: Option, waitopts: WaitOptions) -> io::Result> { - Ok(imp::process::syscalls::waitpid(pid, waitopts)?.map(|(_, status)| status)) + Ok(backend::process::syscalls::waitpid(pid, waitopts)?.map(|(_, status)| status)) } /// `wait(waitopts)`—Wait for any of the children of calling process to @@ -125,5 +125,5 @@ pub fn waitpid(pid: Option, waitopts: WaitOptions) -> io::Result io::Result> { - imp::process::syscalls::wait(waitopts) + backend::process::syscalls::wait(waitopts) } diff --git a/vendor/rustix/src/rand/getrandom.rs b/vendor/rustix/src/rand/getrandom.rs index f5d7e365d..83043800d 100644 --- a/vendor/rustix/src/rand/getrandom.rs +++ b/vendor/rustix/src/rand/getrandom.rs @@ -1,7 +1,7 @@ -use crate::{imp, io}; +use crate::{backend, io}; /// `GRND_*` -pub use imp::rand::types::GetRandomFlags; +pub use backend::rand::types::GetRandomFlags; /// `getrandom(buf, flags)`—Reads a sequence of random bytes. /// @@ -17,5 +17,5 @@ pub use imp::rand::types::GetRandomFlags; /// [Linux]: https://man7.org/linux/man-pages/man2/getrandom.2.html #[inline] pub fn getrandom(buf: &mut [u8], flags: GetRandomFlags) -> io::Result { - imp::rand::syscalls::getrandom(buf, flags) + backend::rand::syscalls::getrandom(buf, flags) } diff --git a/vendor/rustix/src/runtime.rs b/vendor/rustix/src/runtime.rs index 187da6341..84baeb463 100644 --- a/vendor/rustix/src/runtime.rs +++ b/vendor/rustix/src/runtime.rs @@ -19,45 +19,47 @@ //! serious problems. #![allow(unsafe_code)] +use crate::backend; #[cfg(linux_raw)] use crate::ffi::CStr; #[cfg(linux_raw)] +#[cfg(feature = "fs")] use crate::fs::AtFlags; -use crate::imp; #[cfg(linux_raw)] use crate::io; #[cfg(linux_raw)] use crate::process::Pid; #[cfg(linux_raw)] -use core::ffi::c_void; +#[cfg(feature = "fs")] +use backend::fd::AsFd; #[cfg(linux_raw)] -use imp::fd::AsFd; +use core::ffi::c_void; #[cfg(linux_raw)] #[cfg(target_arch = "x86")] #[inline] pub unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { - imp::runtime::syscalls::tls::set_thread_area(u_info) + backend::runtime::syscalls::tls::set_thread_area(u_info) } #[cfg(linux_raw)] #[cfg(target_arch = "arm")] #[inline] pub unsafe fn arm_set_tls(data: *mut c_void) -> io::Result<()> { - imp::runtime::syscalls::tls::arm_set_tls(data) + backend::runtime::syscalls::tls::arm_set_tls(data) } #[cfg(linux_raw)] #[cfg(target_arch = "x86_64")] #[inline] pub unsafe fn set_fs(data: *mut c_void) { - imp::runtime::syscalls::tls::set_fs(data) + backend::runtime::syscalls::tls::set_fs(data) } #[cfg(linux_raw)] #[inline] pub unsafe fn set_tid_address(data: *mut c_void) -> Pid { - imp::runtime::syscalls::tls::set_tid_address(data) + backend::runtime::syscalls::tls::set_tid_address(data) } /// `prctl(PR_SET_NAME, name)` @@ -74,12 +76,12 @@ pub unsafe fn set_tid_address(data: *mut c_void) -> Pid { #[cfg(linux_raw)] #[inline] pub unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { - imp::runtime::syscalls::tls::set_thread_name(name) + backend::runtime::syscalls::tls::set_thread_name(name) } #[cfg(linux_raw)] #[cfg(target_arch = "x86")] -pub use imp::runtime::tls::UserDesc; +pub use backend::runtime::tls::UserDesc; /// `syscall(SYS_exit, status)`—Exit the current thread. /// @@ -89,7 +91,7 @@ pub use imp::runtime::tls::UserDesc; #[cfg(linux_raw)] #[inline] pub unsafe fn exit_thread(status: i32) -> ! { - imp::runtime::syscalls::tls::exit_thread(status) + backend::runtime::syscalls::tls::exit_thread(status) } /// Exit all the threads in the current process' thread group. @@ -112,7 +114,7 @@ pub unsafe fn exit_thread(status: i32) -> ! { #[doc(alias = "_Exit")] #[inline] pub fn exit_group(status: i32) -> ! { - imp::process::syscalls::exit_group(status) + backend::process::syscalls::exit_group(status) } /// Return fields from the main executable segment headers ("phdrs") relevant @@ -120,7 +122,7 @@ pub fn exit_group(status: i32) -> ! { #[cfg(linux_raw)] #[inline] pub fn startup_tls_info() -> StartupTlsInfo { - imp::runtime::tls::startup_tls_info() + backend::runtime::tls::startup_tls_info() } /// `(getauxval(AT_PHDR), getauxval(AT_PHNUM))`—Returns the address and @@ -134,11 +136,11 @@ pub fn startup_tls_info() -> StartupTlsInfo { #[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub fn exe_phdrs() -> (*const c_void, usize) { - imp::param::auxv::exe_phdrs() + backend::param::auxv::exe_phdrs() } #[cfg(linux_raw)] -pub use imp::runtime::tls::StartupTlsInfo; +pub use backend::runtime::tls::StartupTlsInfo; /// `fork()`—Creates a new process by duplicating the calling process. /// @@ -219,7 +221,7 @@ pub use imp::runtime::tls::StartupTlsInfo; /// [async-signal-safe]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03 #[cfg(linux_raw)] pub unsafe fn fork() -> io::Result> { - imp::runtime::syscalls::fork() + backend::runtime::syscalls::fork() } /// `execveat(dirfd, path.as_c_str(), argv, envp, flags)`—Execute a new @@ -236,6 +238,8 @@ pub unsafe fn fork() -> io::Result> { /// [Linux]: https://man7.org/linux/man-pages/man2/execveat.2.html #[cfg(linux_raw)] #[inline] +#[cfg(feature = "fs")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "fs")))] pub unsafe fn execveat( dirfd: Fd, path: &CStr, @@ -243,7 +247,7 @@ pub unsafe fn execveat( envp: *const *const u8, flags: AtFlags, ) -> io::Errno { - imp::runtime::syscalls::execveat(dirfd.as_fd(), path, argv, envp, flags) + backend::runtime::syscalls::execveat(dirfd.as_fd(), path, argv, envp, flags) } /// `execve(path.as_c_str(), argv, envp)`—Execute a new command using the @@ -261,5 +265,5 @@ pub unsafe fn execveat( #[cfg(linux_raw)] #[inline] pub unsafe fn execve(path: &CStr, argv: *const *const u8, envp: *const *const u8) -> io::Errno { - imp::runtime::syscalls::execve(path, argv, envp) + backend::runtime::syscalls::execve(path, argv, envp) } diff --git a/vendor/rustix/src/termios/cf.rs b/vendor/rustix/src/termios/cf.rs index d28b65e03..d79eab5c8 100644 --- a/vendor/rustix/src/termios/cf.rs +++ b/vendor/rustix/src/termios/cf.rs @@ -1,40 +1,40 @@ use crate::termios::{Speed, Termios}; -use crate::{imp, io}; +use crate::{backend, io}; /// `cfgetospeed(termios)` #[inline] #[must_use] pub fn cfgetospeed(termios: &Termios) -> Speed { - imp::termios::syscalls::cfgetospeed(termios) + backend::termios::syscalls::cfgetospeed(termios) } /// `cfgetispeed(termios)` #[inline] #[must_use] pub fn cfgetispeed(termios: &Termios) -> Speed { - imp::termios::syscalls::cfgetispeed(termios) + backend::termios::syscalls::cfgetispeed(termios) } /// `cfmakeraw(termios)` #[inline] pub fn cfmakeraw(termios: &mut Termios) { - imp::termios::syscalls::cfmakeraw(termios) + backend::termios::syscalls::cfmakeraw(termios) } /// `cfsetospeed(termios, speed)` #[inline] pub fn cfsetospeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - imp::termios::syscalls::cfsetospeed(termios, speed) + backend::termios::syscalls::cfsetospeed(termios, speed) } /// `cfsetispeed(termios, speed)` #[inline] pub fn cfsetispeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - imp::termios::syscalls::cfsetispeed(termios, speed) + backend::termios::syscalls::cfsetispeed(termios, speed) } /// `cfsetspeed(termios, speed)` #[inline] pub fn cfsetspeed(termios: &mut Termios, speed: Speed) -> io::Result<()> { - imp::termios::syscalls::cfsetspeed(termios, speed) + backend::termios::syscalls::cfsetspeed(termios, speed) } diff --git a/vendor/rustix/src/termios/constants.rs b/vendor/rustix/src/termios/constants.rs index 5c10c12ed..e96f139eb 100644 --- a/vendor/rustix/src/termios/constants.rs +++ b/vendor/rustix/src/termios/constants.rs @@ -1,102 +1,142 @@ -use crate::imp; +use crate::backend; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B1000000; +pub use backend::termios::types::B1000000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B1152000; +pub use backend::termios::types::B1152000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B1500000; +pub use backend::termios::types::B1500000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B2000000; +pub use backend::termios::types::B2000000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B2500000; +pub use backend::termios::types::B2500000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B3000000; +pub use backend::termios::types::B3000000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B3500000; +pub use backend::termios::types::B3500000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B4000000; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] -pub use imp::termios::types::B460800; +pub use backend::termios::types::B4000000; +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" +)))] +pub use backend::termios::types::B460800; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B500000; +pub use backend::termios::types::B500000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::B576000; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] -pub use imp::termios::types::B921600; +pub use backend::termios::types::B576000; +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" +)))] +pub use backend::termios::types::B921600; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::BRKINT; +pub use backend::termios::types::BRKINT; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -107,8 +147,9 @@ pub use imp::termios::types::BRKINT; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::BS0; +pub use backend::termios::types::BS0; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -121,8 +162,9 @@ pub use imp::termios::types::BS0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::BS1; +pub use backend::termios::types::BS1; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -132,54 +174,61 @@ pub use imp::termios::types::BS1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::BSDLY; +pub use backend::termios::types::BSDLY; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", )))] -pub use imp::termios::types::CBAUD; +pub use backend::termios::types::CBAUD; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CBAUDEX; +pub use backend::termios::types::CBAUDEX; #[cfg(not(any( target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", )))] -pub use imp::termios::types::CIBAUD; +pub use backend::termios::types::CIBAUD; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CLOCAL; +pub use backend::termios::types::CLOCAL; #[cfg(not(any( target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CMSPAR; +pub use backend::termios::types::CMSPAR; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -190,8 +239,9 @@ pub use imp::termios::types::CMSPAR; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CR0; +pub use backend::termios::types::CR0; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -204,8 +254,9 @@ pub use imp::termios::types::CR0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CR1; +pub use backend::termios::types::CR1; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -218,8 +269,9 @@ pub use imp::termios::types::CR1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CR2; +pub use backend::termios::types::CR2; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -232,8 +284,9 @@ pub use imp::termios::types::CR2; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CR3; +pub use backend::termios::types::CR3; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -243,56 +296,66 @@ pub use imp::termios::types::CR3; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::CRDLY; +pub use backend::termios::types::CRDLY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CREAD; +pub use backend::termios::types::CREAD; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::CRTSCTS; +pub use backend::termios::types::CRTSCTS; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CS5; +pub use backend::termios::types::CS5; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CS6; +pub use backend::termios::types::CS6; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CS7; +pub use backend::termios::types::CS7; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CS8; +pub use backend::termios::types::CS8; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CSIZE; +pub use backend::termios::types::CSIZE; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::CSTOPB; +pub use backend::termios::types::CSTOPB; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ECHO; +pub use backend::termios::types::ECHO; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::ECHOCTL; +pub use backend::termios::types::ECHOCTL; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ECHOE; +pub use backend::termios::types::ECHOE; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ECHOK; +pub use backend::termios::types::ECHOK; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::ECHOKE; +pub use backend::termios::types::ECHOKE; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ECHONL; +pub use backend::termios::types::ECHONL; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::ECHOPRT; +pub use backend::termios::types::ECHOPRT; #[cfg(not(any( target_os = "emscripten", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::EXTA; +pub use backend::termios::types::EXTA; #[cfg(not(any( target_os = "emscripten", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::EXTB; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::EXTPROC; +pub use backend::termios::types::EXTB; +#[cfg(not(any( + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox" +)))] +pub use backend::termios::types::EXTPROC; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -303,8 +366,9 @@ pub use imp::termios::types::EXTPROC; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::FF0; +pub use backend::termios::types::FF0; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -317,8 +381,9 @@ pub use imp::termios::types::FF0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::FF1; +pub use backend::termios::types::FF1; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -329,32 +394,38 @@ pub use imp::termios::types::FF1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::FFDLY; +pub use backend::termios::types::FFDLY; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::FLUSHO; +pub use backend::termios::types::FLUSHO; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::HUPCL; +pub use backend::termios::types::HUPCL; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ICRNL; +pub use backend::termios::types::ICRNL; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::IEXTEN; +pub use backend::termios::types::IEXTEN; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::IGNBRK; +pub use backend::termios::types::IGNBRK; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::IGNCR; +pub use backend::termios::types::IGNCR; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::IGNPAR; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::IMAXBEL; +pub use backend::termios::types::IGNPAR; +#[cfg(not(any( + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox" +)))] +pub use backend::termios::types::IMAXBEL; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::INLCR; +pub use backend::termios::types::INLCR; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::INPCK; +pub use backend::termios::types::INPCK; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ISIG; +pub use backend::termios::types::ISIG; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ISTRIP; +pub use backend::termios::types::ISTRIP; #[cfg(any( linux_raw, all( @@ -362,25 +433,27 @@ pub use imp::termios::types::ISTRIP; any(target_os = "haiku", target_os = "illumos", target_os = "solaris"), ) ))] -pub use imp::termios::types::IUCLC; +pub use backend::termios::types::IUCLC; #[cfg(not(any( target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::IUTF8; +pub use backend::termios::types::IUTF8; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::IXANY; +pub use backend::termios::types::IXANY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::IXOFF; +pub use backend::termios::types::IXOFF; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::IXON; +pub use backend::termios::types::IXON; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -391,8 +464,9 @@ pub use imp::termios::types::IXON; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::NL0; +pub use backend::termios::types::NL0; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -403,8 +477,9 @@ pub use imp::termios::types::NL0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::NL1; +pub use backend::termios::types::NL1; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -414,12 +489,13 @@ pub use imp::termios::types::NL1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::NLDLY; +pub use backend::termios::types::NLDLY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::NOFLSH; +pub use backend::termios::types::NOFLSH; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::OCRNL; +pub use backend::termios::types::OCRNL; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -428,7 +504,7 @@ pub use imp::termios::types::OCRNL; target_os = "netbsd", target_os = "openbsd", )))] -pub use imp::termios::types::OFDEL; +pub use backend::termios::types::OFDEL; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -437,7 +513,7 @@ pub use imp::termios::types::OFDEL; target_os = "netbsd", target_os = "openbsd", )))] -pub use imp::termios::types::OFILL; +pub use backend::termios::types::OFILL; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -446,24 +522,25 @@ pub use imp::termios::types::OFILL; target_os = "netbsd", target_os = "redox", )))] -pub use imp::termios::types::OLCUC; +pub use backend::termios::types::OLCUC; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ONLCR; +pub use backend::termios::types::ONLCR; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ONLRET; +pub use backend::termios::types::ONLRET; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::ONOCR; +pub use backend::termios::types::ONOCR; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::OPOST; +pub use backend::termios::types::OPOST; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::PARENB; +pub use backend::termios::types::PARENB; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::PARMRK; +pub use backend::termios::types::PARMRK; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::PARODD; +pub use backend::termios::types::PARODD; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] -pub use imp::termios::types::PENDIN; +pub use backend::termios::types::PENDIN; #[cfg(not(any( + target_os = "dragonfly", target_os = "fuchsia", target_os = "illumos", target_os = "ios", @@ -471,8 +548,9 @@ pub use imp::termios::types::PENDIN; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::TAB0; +pub use backend::termios::types::TAB0; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -485,8 +563,9 @@ pub use imp::termios::types::TAB0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::TAB1; +pub use backend::termios::types::TAB1; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -499,10 +578,12 @@ pub use imp::termios::types::TAB1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::TAB2; +pub use backend::termios::types::TAB2; #[cfg(not(any( all(libc, target_env = "musl"), + target_os = "dragonfly", target_os = "emscripten", target_os = "fuchsia", target_os = "illumos", @@ -511,29 +592,34 @@ pub use imp::termios::types::TAB2; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::TAB3; +pub use backend::termios::types::TAB3; #[cfg(not(any( + target_os = "dragonfly", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "illumos", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::TABDLY; +pub use backend::termios::types::TABDLY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] -pub use imp::termios::types::TOSTOP; +pub use backend::termios::types::TOSTOP; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] -pub use imp::termios::types::VSWTC; +pub use backend::termios::types::VSWTC; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", @@ -544,8 +630,9 @@ pub use imp::termios::types::VSWTC; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::VT0; +pub use backend::termios::types::VT0; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -558,8 +645,9 @@ pub use imp::termios::types::VT0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::VT1; +pub use backend::termios::types::VT1; #[cfg(not(any( all(libc, target_env = "musl"), target_os = "dragonfly", @@ -570,26 +658,31 @@ pub use imp::termios::types::VT1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::VTDLY; +pub use backend::termios::types::VTDLY; #[cfg(any(linux_raw, all(libc, any(target_arch = "s390x", target_os = "haiku"))))] -pub use imp::termios::types::XCASE; +pub use backend::termios::types::XCASE; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] -pub use imp::termios::types::XTABS; -pub use imp::termios::types::{ +pub use backend::termios::types::XTABS; +pub use backend::termios::types::{ B0, B110, B115200, B1200, B134, B150, B1800, B19200, B200, B230400, B2400, B300, B38400, B4800, - B50, B57600, B600, B75, B9600, ICANON, VDISCARD, VEOF, VEOL, VEOL2, VERASE, VINTR, VKILL, - VLNEXT, VMIN, VQUIT, VREPRINT, VSTART, VSTOP, VSUSP, VTIME, VWERASE, + B50, B57600, B600, B75, B9600, ICANON, VEOF, VEOL, VEOL2, VERASE, VINTR, VKILL, VMIN, VQUIT, + VSTART, VSTOP, VSUSP, VTIME, }; +#[cfg(not(target_os = "haiku"))] +pub use backend::termios::types::{VDISCARD, VLNEXT, VREPRINT, VWERASE}; /// Translate from a `Speed` code to a speed value `u32`. /// @@ -597,123 +690,163 @@ pub use imp::termios::types::{ /// let speed = rustix::termios::speed_value(rustix::termios::B57600); /// assert_eq!(speed, Some(57600)); /// ``` -pub fn speed_value(speed: imp::termios::types::Speed) -> Option { +pub fn speed_value(speed: backend::termios::types::Speed) -> Option { match speed { - imp::termios::types::B0 => Some(0), - imp::termios::types::B50 => Some(50), - imp::termios::types::B75 => Some(75), - imp::termios::types::B110 => Some(110), - imp::termios::types::B134 => Some(134), - imp::termios::types::B150 => Some(150), - imp::termios::types::B200 => Some(200), - imp::termios::types::B300 => Some(300), - imp::termios::types::B600 => Some(600), - imp::termios::types::B1200 => Some(1200), - imp::termios::types::B1800 => Some(1800), - imp::termios::types::B2400 => Some(2400), - imp::termios::types::B4800 => Some(4800), - imp::termios::types::B9600 => Some(9600), - imp::termios::types::B19200 => Some(19200), - imp::termios::types::B38400 => Some(38400), - imp::termios::types::B57600 => Some(57600), - imp::termios::types::B115200 => Some(115_200), - imp::termios::types::B230400 => Some(230_400), - #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] - imp::termios::types::B460800 => Some(460_800), + backend::termios::types::B0 => Some(0), + backend::termios::types::B50 => Some(50), + backend::termios::types::B75 => Some(75), + backend::termios::types::B110 => Some(110), + backend::termios::types::B134 => Some(134), + backend::termios::types::B150 => Some(150), + backend::termios::types::B200 => Some(200), + backend::termios::types::B300 => Some(300), + backend::termios::types::B600 => Some(600), + backend::termios::types::B1200 => Some(1200), + backend::termios::types::B1800 => Some(1800), + backend::termios::types::B2400 => Some(2400), + backend::termios::types::B4800 => Some(4800), + backend::termios::types::B9600 => Some(9600), + backend::termios::types::B19200 => Some(19200), + backend::termios::types::B38400 => Some(38400), + backend::termios::types::B57600 => Some(57600), + backend::termios::types::B115200 => Some(115_200), + backend::termios::types::B230400 => Some(230_400), + #[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" + )))] + backend::termios::types::B460800 => Some(460_800), #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B500000 => Some(500_000), + backend::termios::types::B500000 => Some(500_000), #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", + )))] + backend::termios::types::B576000 => Some(576_000), + #[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" )))] - imp::termios::types::B576000 => Some(576_000), - #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] - imp::termios::types::B921600 => Some(921_600), + backend::termios::types::B921600 => Some(921_600), #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B1000000 => Some(1_000_000), + backend::termios::types::B1000000 => Some(1_000_000), #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B1152000 => Some(1_152_000), + backend::termios::types::B1152000 => Some(1_152_000), #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B1500000 => Some(1_500_000), + backend::termios::types::B1500000 => Some(1_500_000), #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B2000000 => Some(2_000_000), + backend::termios::types::B2000000 => Some(2_000_000), #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B2500000 => Some(2_500_000), + backend::termios::types::B2500000 => Some(2_500_000), #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B3000000 => Some(3_000_000), + backend::termios::types::B3000000 => Some(3_000_000), #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B3500000 => Some(3_500_000), + backend::termios::types::B3500000 => Some(3_500_000), #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] - imp::termios::types::B4000000 => Some(4_000_000), + backend::termios::types::B4000000 => Some(4_000_000), _ => None, } } diff --git a/vendor/rustix/src/termios/mod.rs b/vendor/rustix/src/termios/mod.rs index 79f2f6b38..ec35f96fb 100644 --- a/vendor/rustix/src/termios/mod.rs +++ b/vendor/rustix/src/termios/mod.rs @@ -10,98 +10,138 @@ pub use cf::{cfgetispeed, cfgetospeed, cfmakeraw, cfsetispeed, cfsetospeed, cfse #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B1000000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B1152000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B1500000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B2000000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B2500000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B3000000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B3500000; #[cfg(not(any( + target_arch = "sparc", + target_arch = "sparc64", target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B4000000; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" +)))] pub use constants::B460800; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B500000; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::B576000; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "openbsd")))] +#[cfg(not(any( + target_os = "dragonfly", + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "openbsd" +)))] pub use constants::B921600; #[cfg(not(any(target_os = "ios", target_os = "macos")))] pub use constants::BRKINT; @@ -115,6 +155,7 @@ pub use constants::BRKINT; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::BS0; #[cfg(not(any( @@ -129,6 +170,7 @@ pub use constants::BS0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::BS1; #[cfg(not(any( @@ -140,11 +182,13 @@ pub use constants::BS1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::BSDLY; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", @@ -155,18 +199,21 @@ pub use constants::CBAUD; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CBAUDEX; #[cfg(not(any( target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "netbsd", @@ -180,12 +227,14 @@ pub use constants::CLOCAL; target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CMSPAR; #[cfg(not(any( @@ -198,6 +247,7 @@ pub use constants::CMSPAR; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CR0; #[cfg(not(any( @@ -212,6 +262,7 @@ pub use constants::CR0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CR1; #[cfg(not(any( @@ -226,6 +277,7 @@ pub use constants::CR1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CR2; #[cfg(not(any( @@ -240,6 +292,7 @@ pub use constants::CR2; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CR3; #[cfg(not(any( @@ -251,6 +304,7 @@ pub use constants::CR3; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::CRDLY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] @@ -285,21 +339,30 @@ pub use constants::ECHONL; pub use constants::ECHOPRT; #[cfg(not(any( target_os = "emscripten", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "redox", + target_os = "solaris", )))] pub use constants::EXTA; #[cfg(not(any( target_os = "emscripten", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "redox", + target_os = "solaris", )))] pub use constants::EXTB; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +#[cfg(not(any( + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox" +)))] pub use constants::EXTPROC; #[cfg(not(any( target_os = "dragonfly", @@ -311,6 +374,7 @@ pub use constants::EXTPROC; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::FF0; #[cfg(not(any( @@ -325,6 +389,7 @@ pub use constants::FF0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::FF1; #[cfg(not(any( @@ -337,6 +402,7 @@ pub use constants::FF1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::FFDLY; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] @@ -353,7 +419,12 @@ pub use constants::IGNBRK; pub use constants::IGNCR; #[cfg(not(any(target_os = "ios", target_os = "macos")))] pub use constants::IGNPAR; -#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +#[cfg(not(any( + target_os = "haiku", + target_os = "ios", + target_os = "macos", + target_os = "redox" +)))] pub use constants::IMAXBEL; #[cfg(not(any(target_os = "ios", target_os = "macos")))] pub use constants::INLCR; @@ -375,12 +446,14 @@ pub use constants::IUCLC; target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::IUTF8; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] @@ -399,6 +472,7 @@ pub use constants::IXON; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::NL0; #[cfg(not(any( @@ -411,6 +485,7 @@ pub use constants::NL0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::NL1; #[cfg(not(any( @@ -422,6 +497,7 @@ pub use constants::NL1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::NLDLY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] @@ -472,6 +548,7 @@ pub use constants::PARODD; #[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] pub use constants::PENDIN; #[cfg(not(any( + target_os = "dragonfly", target_os = "fuchsia", target_os = "illumos", target_os = "ios", @@ -479,6 +556,7 @@ pub use constants::PENDIN; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::TAB0; #[cfg(not(any( @@ -493,6 +571,7 @@ pub use constants::TAB0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::TAB1; #[cfg(not(any( @@ -507,10 +586,12 @@ pub use constants::TAB1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::TAB2; #[cfg(not(any( all(libc, target_env = "musl"), + target_os = "dragonfly", target_os = "emscripten", target_os = "fuchsia", target_os = "illumos", @@ -519,15 +600,18 @@ pub use constants::TAB2; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::TAB3; #[cfg(not(any( + target_os = "dragonfly", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "illumos", target_os = "redox", + target_os = "solaris", )))] pub use constants::TABDLY; #[cfg(not(any(target_os = "ios", target_os = "macos")))] @@ -535,11 +619,13 @@ pub use constants::TOSTOP; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", + target_os = "solaris", )))] pub use constants::VSWTC; #[cfg(not(any( @@ -552,6 +638,7 @@ pub use constants::VSWTC; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::VT0; #[cfg(not(any( @@ -566,6 +653,7 @@ pub use constants::VT0; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::VT1; #[cfg(not(any( @@ -578,6 +666,7 @@ pub use constants::VT1; target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::VTDLY; #[cfg(any(linux_raw, all(libc, any(target_arch = "s390x", target_os = "haiku"))))] @@ -585,19 +674,23 @@ pub use constants::XCASE; #[cfg(not(any( target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "illumos", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd", target_os = "redox", + target_os = "solaris", )))] pub use constants::XTABS; pub use constants::{ speed_value, B0, B110, B115200, B1200, B134, B150, B1800, B19200, B200, B230400, B2400, B300, - B38400, B4800, B50, B57600, B600, B75, B9600, ICANON, VDISCARD, VEOF, VEOL, VEOL2, VERASE, - VINTR, VKILL, VLNEXT, VMIN, VQUIT, VREPRINT, VSTART, VSTOP, VSUSP, VTIME, VWERASE, + B38400, B4800, B50, B57600, B600, B75, B9600, ICANON, VEOF, VEOL, VEOL2, VERASE, VINTR, VKILL, + VMIN, VQUIT, VSTART, VSTOP, VSUSP, VTIME, }; +#[cfg(not(target_os = "haiku"))] +pub use constants::{VDISCARD, VLNEXT, VREPRINT, VWERASE}; pub use tc::{ tcdrain, tcflow, tcflush, tcgetattr, tcgetpgrp, tcgetsid, tcgetwinsize, tcsendbreak, tcsetattr, tcsetpgrp, tcsetwinsize, Action, OptionalActions, QueueSelector, Speed, Tcflag, Termios, diff --git a/vendor/rustix/src/termios/tc.rs b/vendor/rustix/src/termios/tc.rs index b44eafde3..e1a87b623 100644 --- a/vendor/rustix/src/termios/tc.rs +++ b/vendor/rustix/src/termios/tc.rs @@ -1,8 +1,8 @@ use crate::fd::AsFd; use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::termios::types::{ +pub use backend::termios::types::{ Action, OptionalActions, QueueSelector, Speed, Tcflag, Termios, Winsize, }; @@ -22,7 +22,7 @@ pub use imp::termios::types::{ #[inline] #[doc(alias = "TCGETS")] pub fn tcgetattr(fd: Fd) -> io::Result { - imp::termios::syscalls::tcgetattr(fd.as_fd()) + backend::termios::syscalls::tcgetattr(fd.as_fd()) } /// `tcgetwinsize(fd)`—Get the current terminal window size. @@ -37,7 +37,7 @@ pub fn tcgetattr(fd: Fd) -> io::Result { #[inline] #[doc(alias = "TIOCGWINSZ")] pub fn tcgetwinsize(fd: Fd) -> io::Result { - imp::termios::syscalls::tcgetwinsize(fd.as_fd()) + backend::termios::syscalls::tcgetwinsize(fd.as_fd()) } /// `tcgetpgrp(fd)`—Get the terminal foreground process group. @@ -54,7 +54,7 @@ pub fn tcgetwinsize(fd: Fd) -> io::Result { #[inline] #[doc(alias = "TIOCGPGRP")] pub fn tcgetpgrp(fd: Fd) -> io::Result { - imp::termios::syscalls::tcgetpgrp(fd.as_fd()) + backend::termios::syscalls::tcgetpgrp(fd.as_fd()) } /// `tcsetpgrp(fd, pid)`—Set the terminal foreground process group. @@ -71,7 +71,7 @@ pub fn tcgetpgrp(fd: Fd) -> io::Result { #[inline] #[doc(alias = "TIOCSPGRP")] pub fn tcsetpgrp(fd: Fd, pid: Pid) -> io::Result<()> { - imp::termios::syscalls::tcsetpgrp(fd.as_fd(), pid) + backend::termios::syscalls::tcsetpgrp(fd.as_fd(), pid) } /// `tcsetattr(fd)`—Set terminal attributes. @@ -93,7 +93,7 @@ pub fn tcsetattr( optional_actions: OptionalActions, termios: &Termios, ) -> io::Result<()> { - imp::termios::syscalls::tcsetattr(fd.as_fd(), optional_actions, termios) + backend::termios::syscalls::tcsetattr(fd.as_fd(), optional_actions, termios) } /// `tcsendbreak(fd, 0)`—Transmit zero-valued bits. @@ -115,7 +115,7 @@ pub fn tcsetattr( #[inline] #[doc(alias = "TCSBRK")] pub fn tcsendbreak(fd: Fd) -> io::Result<()> { - imp::termios::syscalls::tcsendbreak(fd.as_fd()) + backend::termios::syscalls::tcsendbreak(fd.as_fd()) } /// `tcdrain(fd, duration)`—Wait until all pending output has been written. @@ -130,7 +130,7 @@ pub fn tcsendbreak(fd: Fd) -> io::Result<()> { /// [Linux `termios`]: https://man7.org/linux/man-pages/man3/termios.3.html #[inline] pub fn tcdrain(fd: Fd) -> io::Result<()> { - imp::termios::syscalls::tcdrain(fd.as_fd()) + backend::termios::syscalls::tcdrain(fd.as_fd()) } /// `tcflush(fd, queue_selector)`—Wait until all pending output has been @@ -147,7 +147,7 @@ pub fn tcdrain(fd: Fd) -> io::Result<()> { #[inline] #[doc(alias = "TCFLSH")] pub fn tcflush(fd: Fd, queue_selector: QueueSelector) -> io::Result<()> { - imp::termios::syscalls::tcflush(fd.as_fd(), queue_selector) + backend::termios::syscalls::tcflush(fd.as_fd(), queue_selector) } /// `tcflow(fd, action)`—Suspend or resume transmission or reception. @@ -163,7 +163,7 @@ pub fn tcflush(fd: Fd, queue_selector: QueueSelector) -> io::Result<() #[inline] #[doc(alias = "TCXONC")] pub fn tcflow(fd: Fd, action: Action) -> io::Result<()> { - imp::termios::syscalls::tcflow(fd.as_fd(), action) + backend::termios::syscalls::tcflow(fd.as_fd(), action) } /// `tcgetsid(fd)`—Return the session ID of the current session with `fd` as @@ -178,7 +178,7 @@ pub fn tcflow(fd: Fd, action: Action) -> io::Result<()> { #[inline] #[doc(alias = "TIOCGSID")] pub fn tcgetsid(fd: Fd) -> io::Result { - imp::termios::syscalls::tcgetsid(fd.as_fd()) + backend::termios::syscalls::tcgetsid(fd.as_fd()) } /// `tcsetwinsize(fd)`—Set the current terminal window size. @@ -192,5 +192,5 @@ pub fn tcgetsid(fd: Fd) -> io::Result { #[inline] #[doc(alias = "TIOCSWINSZ")] pub fn tcsetwinsize(fd: Fd, winsize: Winsize) -> io::Result<()> { - imp::termios::syscalls::tcsetwinsize(fd.as_fd(), winsize) + backend::termios::syscalls::tcsetwinsize(fd.as_fd(), winsize) } diff --git a/vendor/rustix/src/termios/tty.rs b/vendor/rustix/src/termios/tty.rs index 1651a3c3b..9a1692330 100644 --- a/vendor/rustix/src/termios/tty.rs +++ b/vendor/rustix/src/termios/tty.rs @@ -1,19 +1,20 @@ //! Functions which operate on file descriptors which might be terminals. -use crate::imp; +use crate::backend; #[cfg(any( all(linux_raw, feature = "procfs"), all(libc, not(any(target_os = "fuchsia", target_os = "wasi"))), ))] #[cfg_attr(doc_cfg, doc(cfg(feature = "procfs")))] use crate::io; -use imp::fd::AsFd; +use backend::fd::AsFd; #[cfg(any( all(linux_raw, feature = "procfs"), all(libc, not(any(target_os = "fuchsia", target_os = "wasi"))), ))] use { - crate::ffi::CString, crate::path::SMALL_PATH_BUFFER_SIZE, alloc::vec::Vec, imp::fd::BorrowedFd, + crate::ffi::CString, crate::path::SMALL_PATH_BUFFER_SIZE, alloc::vec::Vec, + backend::fd::BorrowedFd, }; /// `isatty(fd)`—Tests whether a file descriptor refers to a terminal. @@ -26,7 +27,7 @@ use { /// [Linux]: https://man7.org/linux/man-pages/man3/isatty.3.html #[inline] pub fn isatty(fd: Fd) -> bool { - imp::termios::syscalls::isatty(fd.as_fd()) + backend::termios::syscalls::isatty(fd.as_fd()) } /// `ttyname_r(fd)` @@ -57,7 +58,7 @@ fn _ttyname(dirfd: BorrowedFd<'_>, mut buffer: Vec) -> io::Result { buffer.resize(buffer.capacity(), 0_u8); loop { - match imp::termios::syscalls::ttyname(dirfd, &mut buffer) { + match backend::termios::syscalls::ttyname(dirfd, &mut buffer) { Err(io::Errno::RANGE) => { buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially buffer.resize(buffer.capacity(), 0_u8); diff --git a/vendor/rustix/src/thread/clock.rs b/vendor/rustix/src/thread/clock.rs index 206703088..57672fa17 100644 --- a/vendor/rustix/src/thread/clock.rs +++ b/vendor/rustix/src/thread/clock.rs @@ -1,6 +1,6 @@ -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::time::types::Timespec; +pub use backend::time::types::Timespec; #[cfg(not(any( target_os = "dragonfly", @@ -12,7 +12,7 @@ pub use imp::time::types::Timespec; target_os = "redox", target_os = "wasi", )))] -pub use imp::time::types::ClockId; +pub use backend::time::types::ClockId; /// `clock_nanosleep(id, 0, request, remain)`—Sleeps for a duration on a /// given clock. @@ -30,6 +30,7 @@ pub use imp::time::types::ClockId; target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "openbsd", @@ -38,7 +39,7 @@ pub use imp::time::types::ClockId; )))] #[inline] pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRelativeResult { - imp::thread::syscalls::clock_nanosleep_relative(id, request) + backend::thread::syscalls::clock_nanosleep_relative(id, request) } /// `clock_nanosleep(id, TIMER_ABSTIME, request, NULL)`—Sleeps until an @@ -57,6 +58,7 @@ pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRel target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", // FreeBSD 12 has clock_nanosleep, but libc targets FreeBSD 11. + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "openbsd", @@ -65,7 +67,7 @@ pub fn clock_nanosleep_relative(id: ClockId, request: &Timespec) -> NanosleepRel )))] #[inline] pub fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<()> { - imp::thread::syscalls::clock_nanosleep_absolute(id, request) + backend::thread::syscalls::clock_nanosleep_absolute(id, request) } /// `nanosleep(request, remain)`—Sleeps for a duration. @@ -80,7 +82,7 @@ pub fn clock_nanosleep_absolute(id: ClockId, request: &Timespec) -> io::Result<( /// [Linux]: https://man7.org/linux/man-pages/man2/nanosleep.2.html #[inline] pub fn nanosleep(request: &Timespec) -> NanosleepRelativeResult { - imp::thread::syscalls::nanosleep(request) + backend::thread::syscalls::nanosleep(request) } /// A return type for `nanosleep` and `clock_nanosleep_relative`. diff --git a/vendor/rustix/src/thread/futex.rs b/vendor/rustix/src/thread/futex.rs index df5b561f1..7c4399f7a 100644 --- a/vendor/rustix/src/thread/futex.rs +++ b/vendor/rustix/src/thread/futex.rs @@ -7,9 +7,9 @@ #![allow(unsafe_code)] use crate::thread::Timespec; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::thread::{FutexFlags, FutexOperation}; +pub use backend::thread::{FutexFlags, FutexOperation}; /// `futex(uaddr, op, val, utime, uaddr2, val3)` /// @@ -34,5 +34,5 @@ pub unsafe fn futex( uaddr2: *mut u32, val3: u32, ) -> io::Result { - imp::thread::syscalls::futex(uaddr, op, flags, val, utime, uaddr2, val3) + backend::thread::syscalls::futex(uaddr, op, flags, val, utime, uaddr2, val3) } diff --git a/vendor/rustix/src/thread/id.rs b/vendor/rustix/src/thread/id.rs index 964d2654c..0d2fef026 100644 --- a/vendor/rustix/src/thread/id.rs +++ b/vendor/rustix/src/thread/id.rs @@ -1,4 +1,4 @@ -use crate::imp; +use crate::backend; use crate::process::Pid; /// `gettid()`—Returns the thread ID. @@ -13,5 +13,5 @@ use crate::process::Pid; #[inline] #[must_use] pub fn gettid() -> Pid { - imp::thread::syscalls::gettid() + backend::thread::syscalls::gettid() } diff --git a/vendor/rustix/src/thread/mod.rs b/vendor/rustix/src/thread/mod.rs index ac48b435b..b1dc849d9 100644 --- a/vendor/rustix/src/thread/mod.rs +++ b/vendor/rustix/src/thread/mod.rs @@ -6,11 +6,16 @@ mod clock; mod futex; #[cfg(any(target_os = "android", target_os = "linux"))] mod id; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod prctl; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod setns; #[cfg(not(any( target_os = "dragonfly", target_os = "emscripten", target_os = "freebsd", + target_os = "haiku", target_os = "ios", target_os = "macos", target_os = "openbsd", @@ -24,3 +29,7 @@ pub use clock::{nanosleep, NanosleepRelativeResult, Timespec}; pub use futex::{futex, FutexFlags, FutexOperation}; #[cfg(any(target_os = "android", target_os = "linux"))] pub use id::gettid; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use prctl::*; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use setns::*; diff --git a/vendor/rustix/src/thread/prctl.rs b/vendor/rustix/src/thread/prctl.rs new file mode 100644 index 000000000..a2191f7c3 --- /dev/null +++ b/vendor/rustix/src/thread/prctl.rs @@ -0,0 +1,989 @@ +#![allow(unsafe_code)] + +use core::convert::TryFrom; +use core::mem::MaybeUninit; +use core::num::NonZeroU64; +use core::ptr; +use core::ptr::NonNull; +use core::sync::atomic::AtomicU8; + +use bitflags::bitflags; + +use crate::backend::c::{c_int, c_uint, c_void}; +use crate::backend::process::syscalls; +use crate::ffi::{CStr, CString}; +use crate::io; +use crate::process::{ + prctl_1arg, prctl_2args, prctl_3args, prctl_get_at_arg2_optional, Pid, + PointerAuthenticationKeys, +}; + +// +// PR_GET_KEEPCAPS/PR_SET_KEEPCAPS +// + +const PR_GET_KEEPCAPS: c_int = 7; + +/// Get the current state of the calling thread's `keep capabilities` flag. +/// +/// # References +/// - [`prctl(PR_GET_KEEPCAPS,...)`] +/// +/// [`prctl(PR_GET_KEEPCAPS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn get_keep_capabilities() -> io::Result { + unsafe { prctl_1arg(PR_GET_KEEPCAPS) }.map(|r| r != 0) +} + +const PR_SET_KEEPCAPS: c_int = 8; + +/// Set the state of the calling thread's `keep capabilities` flag. +/// +/// # References +/// - [`prctl(PR_SET_KEEPCAPS,...)`] +/// +/// [`prctl(PR_SET_KEEPCAPS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_keep_capabilities(enable: bool) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_KEEPCAPS, enable as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_NAME/PR_SET_NAME +// + +const PR_GET_NAME: c_int = 16; + +/// Get the name of the calling thread. +/// +/// # References +/// - [`prctl(PR_GET_NAME,...)`] +/// +/// [`prctl(PR_GET_NAME,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn name() -> io::Result { + let mut buffer = [0_u8; 16]; + unsafe { prctl_2args(PR_GET_NAME, buffer.as_mut_ptr().cast())? }; + + let len = buffer.iter().position(|&x| x == 0_u8).unwrap_or(0); + CString::new(&buffer[..len]).map_err(|_r| io::Errno::ILSEQ) +} + +const PR_SET_NAME: c_int = 15; + +/// Set the name of the calling thread. +/// +/// # References +/// - [`prctl(PR_SET_NAME,...)`] +/// +/// [`prctl(PR_SET_NAME,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_name(name: &CStr) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_NAME, name.as_ptr() as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_SECCOMP/PR_SET_SECCOMP +// + +//const PR_GET_SECCOMP: c_int = 21; + +const SECCOMP_MODE_DISABLED: i32 = 0; +const SECCOMP_MODE_STRICT: i32 = 1; +const SECCOMP_MODE_FILTER: i32 = 2; + +/// `SECCOMP_MODE_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum SecureComputingMode { + /// Secure computing is not in use. + Disabled = SECCOMP_MODE_DISABLED, + /// Use hard-coded filter. + Strict = SECCOMP_MODE_STRICT, + /// Use user-supplied filter. + Filter = SECCOMP_MODE_FILTER, +} + +impl TryFrom for SecureComputingMode { + type Error = io::Errno; + + fn try_from(value: i32) -> Result { + match value { + SECCOMP_MODE_DISABLED => Ok(Self::Disabled), + SECCOMP_MODE_STRICT => Ok(Self::Strict), + SECCOMP_MODE_FILTER => Ok(Self::Filter), + _ => Err(io::Errno::RANGE), + } + } +} + +/* +/// Get the secure computing mode of the calling thread. +/// +/// If the caller is not in secure computing mode, this returns [`SecureComputingMode::Disabled`]. +/// If the caller is in strict secure computing mode, then this call will cause a `SIGKILL` signal +/// to be sent to the process. +/// If the caller is in filter mode, and this system call is allowed by the seccomp filters, +/// it returns [`SecureComputingMode::Filter`]; otherwise, the process is killed with +/// a `SIGKILL` signal. +/// +/// Since Linux 3.8, the Seccomp field of the `/proc/[pid]/status` file provides a method +/// of obtaining the same information, without the risk that the process is killed; see `proc(5)`. +/// +/// # References +/// - [`prctl(PR_GET_SECCOMP,...)`] +/// +/// [`prctl(PR_GET_SECCOMP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn secure_computing_mode() -> io::Result { + unsafe { prctl_1arg(PR_GET_SECCOMP) }.and_then(TryInto::try_into) +} +*/ + +const PR_SET_SECCOMP: c_int = 22; + +/// Set the secure computing mode for the calling thread, to limit the available system calls. +/// +/// # References +/// - [`prctl(PR_SET_SECCOMP,...)`] +/// +/// [`prctl(PR_SET_SECCOMP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_secure_computing_mode(mode: SecureComputingMode) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_SECCOMP, mode as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_CAPBSET_READ/PR_CAPBSET_DROP +// + +const PR_CAPBSET_READ: c_int = 23; + +const CAP_CHOWN: u32 = 0; +const CAP_DAC_OVERRIDE: u32 = 1; +const CAP_DAC_READ_SEARCH: u32 = 2; +const CAP_FOWNER: u32 = 3; +const CAP_FSETID: u32 = 4; +const CAP_KILL: u32 = 5; +const CAP_SETGID: u32 = 6; +const CAP_SETUID: u32 = 7; +const CAP_SETPCAP: u32 = 8; +const CAP_LINUX_IMMUTABLE: u32 = 9; +const CAP_NET_BIND_SERVICE: u32 = 10; +const CAP_NET_BROADCAST: u32 = 11; +const CAP_NET_ADMIN: u32 = 12; +const CAP_NET_RAW: u32 = 13; +const CAP_IPC_LOCK: u32 = 14; +const CAP_IPC_OWNER: u32 = 15; +const CAP_SYS_MODULE: u32 = 16; +const CAP_SYS_RAWIO: u32 = 17; +const CAP_SYS_CHROOT: u32 = 18; +const CAP_SYS_PTRACE: u32 = 19; +const CAP_SYS_PACCT: u32 = 20; +const CAP_SYS_ADMIN: u32 = 21; +const CAP_SYS_BOOT: u32 = 22; +const CAP_SYS_NICE: u32 = 23; +const CAP_SYS_RESOURCE: u32 = 24; +const CAP_SYS_TIME: u32 = 25; +const CAP_SYS_TTY_CONFIG: u32 = 26; +const CAP_MKNOD: u32 = 27; +const CAP_LEASE: u32 = 28; +const CAP_AUDIT_WRITE: u32 = 29; +const CAP_AUDIT_CONTROL: u32 = 30; +const CAP_SETFCAP: u32 = 31; +const CAP_MAC_OVERRIDE: u32 = 32; +const CAP_MAC_ADMIN: u32 = 33; +const CAP_SYSLOG: u32 = 34; +const CAP_WAKE_ALARM: u32 = 35; +const CAP_BLOCK_SUSPEND: u32 = 36; +const CAP_AUDIT_READ: u32 = 37; +const CAP_PERFMON: u32 = 38; +const CAP_BPF: u32 = 39; +const CAP_CHECKPOINT_RESTORE: u32 = 40; + +/// Linux per-thread capability. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum Capability { + /// In a system with the `_POSIX_CHOWN_RESTRICTED` option defined, this overrides + /// the restriction of changing file ownership and group ownership. + ChangeOwnership = CAP_CHOWN, + /// Override all DAC access, including ACL execute access if `_POSIX_ACL` is defined. + /// Excluding DAC access covered by [`Capability::LinuxImmutable`]. + DACOverride = CAP_DAC_OVERRIDE, + /// Overrides all DAC restrictions regarding read and search on files and directories, + /// including ACL restrictions if `_POSIX_ACL` is defined. Excluding DAC access covered + /// by [`Capability::LinuxImmutable`]. + DACReadSearch = CAP_DAC_READ_SEARCH, + /// Overrides all restrictions about allowed operations on files, where file owner ID must be + /// equal to the user ID, except where [`Capability::FileSetID`] is applicable. + /// It doesn't override MAC and DAC restrictions. + FileOwner = CAP_FOWNER, + /// Overrides the following restrictions that the effective user ID shall match the file owner + /// ID when setting the `S_ISUID` and `S_ISGID` bits on that file; that the effective group ID + /// (or one of the supplementary group IDs) shall match the file owner ID when setting the + /// `S_ISGID` bit on that file; that the `S_ISUID` and `S_ISGID` bits are cleared on successful + /// return from `chown` (not implemented). + FileSetID = CAP_FSETID, + /// Overrides the restriction that the real or effective user ID of a process sending a signal + /// must match the real or effective user ID of the process receiving the signal. + Kill = CAP_KILL, + /// Allows `setgid` manipulation. Allows `setgroups`. Allows forged gids on socket + /// credentials passing. + SetGroupID = CAP_SETGID, + /// Allows `set*uid` manipulation (including fsuid). Allows forged pids on socket + /// credentials passing. + SetUserID = CAP_SETUID, + /// Without VFS support for capabilities: + /// - Transfer any capability in your permitted set to any pid. + /// - remove any capability in your permitted set from any pid. + /// With VFS support for capabilities (neither of above, but) + /// - Add any capability from current's capability bounding set to the current process' + /// inheritable set. + /// - Allow taking bits out of capability bounding set. + /// - Allow modification of the securebits for a process. + SetPermittedCapabilities = CAP_SETPCAP, + /// Allow modification of `S_IMMUTABLE` and `S_APPEND` file attributes. + LinuxImmutable = CAP_LINUX_IMMUTABLE, + /// Allows binding to TCP/UDP sockets below 1024. Allows binding to ATM VCIs below 32. + NetBindService = CAP_NET_BIND_SERVICE, + /// Allow broadcasting, listen to multicast. + NetBroadcast = CAP_NET_BROADCAST, + /// Allow interface configuration. Allow administration of IP firewall, masquerading and + /// accounting. Allow setting debug option on sockets. Allow modification of routing tables. + /// Allow setting arbitrary process / process group ownership on sockets. Allow binding to any + /// address for transparent proxying (also via [`Capability::NetRaw`]). Allow setting TOS + /// (type of service). Allow setting promiscuous mode. Allow clearing driver statistics. + /// Allow multicasting. Allow read/write of device-specific registers. Allow activation of ATM + /// control sockets. + NetAdmin = CAP_NET_ADMIN, + /// Allow use of `RAW` sockets. Allow use of `PACKET` sockets. Allow binding to any address for + /// transparent proxying (also via [`Capability::NetAdmin`]). + NetRaw = CAP_NET_RAW, + /// Allow locking of shared memory segments. Allow mlock and mlockall (which doesn't really have + /// anything to do with IPC). + IPCLock = CAP_IPC_LOCK, + /// Override IPC ownership checks. + IPCOwner = CAP_IPC_OWNER, + /// Insert and remove kernel modules - modify kernel without limit. + SystemModule = CAP_SYS_MODULE, + /// Allow ioperm/iopl access. Allow sending USB messages to any device via `/dev/bus/usb`. + SystemRawIO = CAP_SYS_RAWIO, + /// Allow use of `chroot`. + SystemChangeRoot = CAP_SYS_CHROOT, + /// Allow `ptrace` of any process. + SystemProcessTrace = CAP_SYS_PTRACE, + /// Allow configuration of process accounting. + SystemProcessAccounting = CAP_SYS_PACCT, + /// Allow configuration of the secure attention key. Allow administration of the random device. + /// Allow examination and configuration of disk quotas. Allow setting the domainname. + /// Allow setting the hostname. Allow `mount` and `umount`, setting up new smb connection. + /// Allow some autofs root ioctls. Allow nfsservctl. Allow `VM86_REQUEST_IRQ`. + /// Allow to read/write pci config on alpha. Allow `irix_prctl` on mips (setstacksize). + /// Allow flushing all cache on m68k (`sys_cacheflush`). Allow removing semaphores. + /// Used instead of [`Capability::ChangeOwnership`] to "chown" IPC message queues, semaphores + /// and shared memory. Allow locking/unlocking of shared memory segment. Allow turning swap + /// on/off. Allow forged pids on socket credentials passing. Allow setting readahead and + /// flushing buffers on block devices. Allow setting geometry in floppy driver. Allow turning + /// DMA on/off in `xd` driver. Allow administration of md devices (mostly the above, but some + /// extra ioctls). Allow tuning the ide driver. Allow access to the nvram device. Allow + /// administration of `apm_bios`, serial and bttv (TV) device. Allow manufacturer commands in + /// isdn CAPI support driver. Allow reading non-standardized portions of pci configuration + /// space. Allow DDI debug ioctl on sbpcd driver. Allow setting up serial ports. Allow sending + /// raw qic-117 commands. Allow enabling/disabling tagged queuing on SCSI controllers and + /// sending arbitrary SCSI commands. Allow setting encryption key on loopback filesystem. + /// Allow setting zone reclaim policy. Allow everything under + /// [`Capability::BerkeleyPacketFilters`] and [`Capability::PerformanceMonitoring`] for backward + /// compatibility. + SystemAdmin = CAP_SYS_ADMIN, + /// Allow use of `reboot`. + SystemBoot = CAP_SYS_BOOT, + /// Allow raising priority and setting priority on other (different UID) processes. Allow use of + /// FIFO and round-robin (realtime) scheduling on own processes and setting the scheduling + /// algorithm used by another process. Allow setting cpu affinity on other processes. + /// Allow setting realtime ioprio class. Allow setting ioprio class on other processes. + SystemNice = CAP_SYS_NICE, + /// Override resource limits. Set resource limits. Override quota limits. Override reserved + /// space on ext2 filesystem. Modify data journaling mode on ext3 filesystem (uses journaling + /// resources). NOTE: ext2 honors fsuid when checking for resource overrides, so you can + /// override using fsuid too. Override size restrictions on IPC message queues. Allow more than + /// 64hz interrupts from the real-time clock. Override max number of consoles on console + /// allocation. Override max number of keymaps. Control memory reclaim behavior. + SystemResource = CAP_SYS_RESOURCE, + /// Allow manipulation of system clock. Allow `irix_stime` on mips. Allow setting the real-time + /// clock. + SystemTime = CAP_SYS_TIME, + /// Allow configuration of tty devices. Allow `vhangup` of tty. + SystemTTYConfig = CAP_SYS_TTY_CONFIG, + /// Allow the privileged aspects of `mknod`. + MakeNode = CAP_MKNOD, + /// Allow taking of leases on files. + Lease = CAP_LEASE, + /// Allow writing the audit log via unicast netlink socket. + AuditWrite = CAP_AUDIT_WRITE, + /// Allow configuration of audit via unicast netlink socket. + AuditControl = CAP_AUDIT_CONTROL, + /// Set or remove capabilities on files. Map `uid=0` into a child user namespace. + SetFileCapabilities = CAP_SETFCAP, + /// Override MAC access. The base kernel enforces no MAC policy. An LSM may enforce a MAC + /// policy, and if it does and it chooses to implement capability based overrides of that + /// policy, this is the capability it should use to do so. + MACOverride = CAP_MAC_OVERRIDE, + /// Allow MAC configuration or state changes. The base kernel requires no MAC configuration. + /// An LSM may enforce a MAC policy, and if it does and it chooses to implement capability based + /// checks on modifications to that policy or the data required to maintain it, this is the + /// capability it should use to do so. + MACAdmin = CAP_MAC_ADMIN, + /// Allow configuring the kernel's `syslog` (`printk` behaviour). + SystemLog = CAP_SYSLOG, + /// Allow triggering something that will wake the system. + WakeAlarm = CAP_WAKE_ALARM, + /// Allow preventing system suspends. + BlockSuspend = CAP_BLOCK_SUSPEND, + /// Allow reading the audit log via multicast netlink socket. + AuditRead = CAP_AUDIT_READ, + /// Allow system performance and observability privileged operations using `perf_events`, + /// `i915_perf` and other kernel subsystems. + PerformanceMonitoring = CAP_PERFMON, + /// This capability allows the following BPF operations: + /// - Creating all types of BPF maps + /// - Advanced verifier features + /// - Indirect variable access + /// - Bounded loops + /// - BPF to BPF function calls + /// - Scalar precision tracking + /// - Larger complexity limits + /// - Dead code elimination + /// - And potentially other features + /// - Loading BPF Type Format (BTF) data + /// - Retrieve `xlated` and JITed code of BPF programs + /// - Use `bpf_spin_lock` helper + /// + /// [`Capability::PerformanceMonitoring`] relaxes the verifier checks further: + /// - BPF progs can use of pointer-to-integer conversions + /// - speculation attack hardening measures are bypassed + /// - `bpf_probe_read` to read arbitrary kernel memory is allowed + /// - `bpf_trace_printk` to print kernel memory is allowed + /// + /// [`Capability::SystemAdmin`] is required to use bpf_probe_write_user. + /// + /// [`Capability::SystemAdmin`] is required to iterate system wide loaded + /// programs, maps, links, BTFs and convert their IDs to file descriptors. + /// + /// [`Capability::PerformanceMonitoring`] and [`Capability::BerkeleyPacketFilters`] are required + /// to load tracing programs. + /// [`Capability::NetAdmin`] and [`Capability::BerkeleyPacketFilters`] are required to load + /// networking programs. + BerkeleyPacketFilters = CAP_BPF, + /// Allow checkpoint/restore related operations. Allow PID selection during `clone3`. + /// Allow writing to `ns_last_pid`. + CheckpointRestore = CAP_CHECKPOINT_RESTORE, +} + +/// Check if the specified capability is in the calling thread's capability bounding set. +/// +/// # References +/// - [`prctl(PR_CAPBSET_READ,...)`] +/// +/// [`prctl(PR_CAPBSET_READ,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn is_in_capability_bounding_set(capability: Capability) -> io::Result { + unsafe { prctl_2args(PR_CAPBSET_READ, capability as usize as *mut _) }.map(|r| r != 0) +} + +const PR_CAPBSET_DROP: c_int = 24; + +/// If the calling thread has the [`Capability::SetPermittedCapabilities`] capability within its +/// user namespace, then drop the specified capability from the thread's capability bounding set. +/// +/// # References +/// - [`prctl(PR_CAPBSET_DROP,...)`] +/// +/// [`prctl(PR_CAPBSET_DROP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn remove_capability_from_capability_bounding_set(capability: Capability) -> io::Result<()> { + unsafe { prctl_2args(PR_CAPBSET_DROP, capability as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_SECUREBITS/PR_SET_SECUREBITS +// + +const PR_GET_SECUREBITS: c_int = 27; + +bitflags! { + /// `SECBIT_*`. + pub struct CapabilitiesSecureBits: u32 { + /// If this bit is set, then the kernel does not grant capabilities when + /// a `set-user-ID-root` program is executed, or when a process with an effective or real + /// UID of 0 calls `execve`. + const NO_ROOT = 1_u32 << 0; + /// Set [`NO_ROOT`] irreversibly. + const NO_ROOT_LOCKED = 1_u32 << 1; + /// Setting this flag stops the kernel from adjusting the process's permitted, effective, + /// and ambient capability sets when the thread's effective and filesystem UIDs are switched + /// between zero and nonzero values. + const NO_SETUID_FIXUP = 1_u32 << 2; + /// Set [`NO_SETUID_FIXUP`] irreversibly. + const NO_SETUID_FIXUP_LOCKED = 1_u32 << 3; + /// Setting this flag allows a thread that has one or more 0 UIDs to retain capabilities in + /// its permitted set when it switches all of its UIDs to nonzero values. + const KEEP_CAPS = 1_u32 << 4; + /// Set [`KEEP_CAPS`] irreversibly. + const KEEP_CAPS_LOCKED = 1_u32 << 5; + /// Setting this flag disallows raising ambient capabilities via the `prctl`'s + /// `PR_CAP_AMBIENT_RAISE` operation. + const NO_CAP_AMBIENT_RAISE = 1_u32 << 6; + /// Set [`NO_CAP_AMBIENT_RAISE`] irreversibly. + const NO_CAP_AMBIENT_RAISE_LOCKED = 1_u32 << 7; + } +} + +/// Get the `securebits` flags of the calling thread. +/// +/// # References +/// - [`prctl(PR_GET_SECUREBITS,...)`] +/// +/// [`prctl(PR_GET_SECUREBITS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn capabilities_secure_bits() -> io::Result { + let r = unsafe { prctl_1arg(PR_GET_SECUREBITS)? } as c_uint; + CapabilitiesSecureBits::from_bits(r).ok_or(io::Errno::RANGE) +} + +const PR_SET_SECUREBITS: c_int = 28; + +/// Set the `securebits` flags of the calling thread. +/// +/// # References +/// - [`prctl(PR_SET_SECUREBITS,...)`] +/// +/// [`prctl(PR_SET_SECUREBITS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_capabilities_secure_bits(bits: CapabilitiesSecureBits) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_SECUREBITS, bits.bits() as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_TIMERSLACK/PR_SET_TIMERSLACK +// + +const PR_GET_TIMERSLACK: c_int = 30; + +/// Get the `current` timer slack value of the calling thread. +/// +/// # References +/// - [`prctl(PR_GET_TIMERSLACK,...)`] +/// +/// [`prctl(PR_GET_TIMERSLACK,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn current_timer_slack() -> io::Result { + unsafe { prctl_1arg(PR_GET_TIMERSLACK) }.map(|r| r as u64) +} + +const PR_SET_TIMERSLACK: c_int = 29; + +/// Sets the `current` timer slack value for the calling thread. +/// +/// # References +/// - [`prctl(PR_SET_TIMERSLACK,...)`] +/// +/// [`prctl(PR_SET_TIMERSLACK,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_current_timer_slack(value: Option) -> io::Result<()> { + let value = usize::try_from(value.map_or(0, NonZeroU64::get)).map_err(|_r| io::Errno::RANGE)?; + unsafe { prctl_2args(PR_SET_TIMERSLACK, value as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_NO_NEW_PRIVS/PR_SET_NO_NEW_PRIVS +// + +const PR_GET_NO_NEW_PRIVS: c_int = 39; + +/// Get the value of the `no_new_privs` attribute for the calling thread. +/// +/// # References +/// - [`prctl(PR_GET_NO_NEW_PRIVS,...)`] +/// +/// [`prctl(PR_GET_NO_NEW_PRIVS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn no_new_privs() -> io::Result { + unsafe { prctl_1arg(PR_GET_NO_NEW_PRIVS) }.map(|r| r != 0) +} + +const PR_SET_NO_NEW_PRIVS: c_int = 38; + +/// Set the calling thread's `no_new_privs` attribute. +/// +/// # References +/// - [`prctl(PR_SET_NO_NEW_PRIVS,...)`] +/// +/// [`prctl(PR_SET_NO_NEW_PRIVS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn set_no_new_privs(no_new_privs: bool) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_NO_NEW_PRIVS, no_new_privs as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_GET_TID_ADDRESS +// + +const PR_GET_TID_ADDRESS: c_int = 40; + +/// Get the `clear_child_tid` address set by `set_tid_address` +/// and `clone`'s `CLONE_CHILD_CLEARTID` flag. +/// +/// # References +/// - [`prctl(PR_GET_TID_ADDRESS,...)`] +/// +/// [`prctl(PR_GET_TID_ADDRESS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn get_clear_child_tid_address() -> io::Result>> { + unsafe { prctl_get_at_arg2_optional::<*mut c_void>(PR_GET_TID_ADDRESS) }.map(NonNull::new) +} + +// +// PR_GET_THP_DISABLE/PR_SET_THP_DISABLE +// + +const PR_GET_THP_DISABLE: c_int = 42; + +/// Get the current setting of the `THP disable` flag for the calling thread. +/// +/// # References +/// - [`prctl(PR_GET_THP_DISABLE,...)`] +/// +/// [`prctl(PR_GET_THP_DISABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn transparent_huge_pages_are_disabled() -> io::Result { + unsafe { prctl_1arg(PR_GET_THP_DISABLE) }.map(|r| r != 0) +} + +const PR_SET_THP_DISABLE: c_int = 41; + +/// Set the state of the `THP disable` flag for the calling thread. +/// +/// # References +/// - [`prctl(PR_SET_THP_DISABLE,...)`] +/// +/// [`prctl(PR_SET_THP_DISABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn disable_transparent_huge_pages(thp_disable: bool) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_THP_DISABLE, thp_disable as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_CAP_AMBIENT +// + +const PR_CAP_AMBIENT: c_int = 47; + +const PR_CAP_AMBIENT_IS_SET: usize = 1; + +/// Check if the specified capability is in the ambient set. +/// +/// # References +/// - [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,...)`] +/// +/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn capability_is_in_ambient_capability_set(capability: Capability) -> io::Result { + let cap = capability as usize as *mut _; + unsafe { prctl_3args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET as *mut _, cap) }.map(|r| r != 0) +} + +const PR_CAP_AMBIENT_CLEAR_ALL: usize = 4; + +/// Remove all capabilities from the ambient set. +/// +/// # References +/// - [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,...)`] +/// +/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn clear_ambient_capability_set() -> io::Result<()> { + unsafe { prctl_2args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL as *mut _) }.map(|_r| ()) +} + +const PR_CAP_AMBIENT_RAISE: usize = 2; +const PR_CAP_AMBIENT_LOWER: usize = 3; + +/// Add or remove the specified capability to the ambient set. +/// +/// # References +/// - [`prctl(PR_CAP_AMBIENT,...)`] +/// +/// [`prctl(PR_CAP_AMBIENT,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn configure_capability_in_ambient_capability_set( + capability: Capability, + enable: bool, +) -> io::Result<()> { + let sub_operation = if enable { + PR_CAP_AMBIENT_RAISE + } else { + PR_CAP_AMBIENT_LOWER + }; + let cap = capability as usize as *mut _; + + unsafe { prctl_3args(PR_CAP_AMBIENT, sub_operation as *mut _, cap) }.map(|_r| ()) +} + +// +// PR_SVE_GET_VL/PR_SVE_SET_VL +// + +const PR_SVE_GET_VL: c_int = 51; + +const PR_SVE_VL_LEN_MASK: u32 = 0xffff; +const PR_SVE_VL_INHERIT: u32 = 1_u32 << 17; + +/// Scalable Vector Extension vector length configuration. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct SVEVectorLengthConfig { + /// Vector length in bytes. + pub vector_length_in_bytes: u32, + /// Vector length inherited across `execve`. + pub vector_length_inherited_across_execve: bool, +} + +/// Get the thread's current SVE vector length configuration. +/// +/// # References +/// - [`prctl(PR_SVE_GET_VL,...)`] +/// +/// [`prctl(PR_SVE_GET_VL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn sve_vector_length_configuration() -> io::Result { + let bits = unsafe { prctl_1arg(PR_SVE_GET_VL)? } as c_uint; + Ok(SVEVectorLengthConfig { + vector_length_in_bytes: bits & PR_SVE_VL_LEN_MASK, + vector_length_inherited_across_execve: (bits & PR_SVE_VL_INHERIT) != 0, + }) +} + +const PR_SVE_SET_VL: c_int = 50; + +const PR_SVE_SET_VL_ONEXEC: u32 = 1_u32 << 18; + +/// Configure the thread's vector length of Scalable Vector Extension. +/// +/// # References +/// - [`prctl(PR_SVE_SET_VL,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SVE_SET_VL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn set_sve_vector_length_configuration( + vector_length_in_bytes: usize, + vector_length_inherited_across_execve: bool, + defer_change_to_next_execve: bool, +) -> io::Result<()> { + let vector_length_in_bytes = + u32::try_from(vector_length_in_bytes).map_err(|_r| io::Errno::RANGE)?; + + let mut bits = vector_length_in_bytes & PR_SVE_VL_LEN_MASK; + + if vector_length_inherited_across_execve { + bits |= PR_SVE_VL_INHERIT; + } + + if defer_change_to_next_execve { + bits |= PR_SVE_SET_VL_ONEXEC; + } + + prctl_2args(PR_SVE_SET_VL, bits as usize as *mut _).map(|_r| ()) +} + +// +// PR_PAC_RESET_KEYS +// + +const PR_PAC_RESET_KEYS: c_int = 54; + +/// Securely reset the thread's pointer authentication keys to fresh random values generated +/// by the kernel. +/// +/// # References +/// - [`prctl(PR_PAC_RESET_KEYS,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_PAC_RESET_KEYS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn reset_pointer_authentication_keys( + keys: Option, +) -> io::Result<()> { + let keys = keys.as_ref().map_or(0_u32, PointerAuthenticationKeys::bits); + prctl_2args(PR_PAC_RESET_KEYS, keys as usize as *mut _).map(|_r| ()) +} + +// +// PR_GET_TAGGED_ADDR_CTRL/PR_SET_TAGGED_ADDR_CTRL +// + +const PR_GET_TAGGED_ADDR_CTRL: c_int = 56; + +const PR_MTE_TAG_SHIFT: u32 = 3; +const PR_MTE_TAG_MASK: u32 = 0xffff_u32 << PR_MTE_TAG_SHIFT; + +bitflags! { + /// Zero means addresses that are passed for the purpose of being dereferenced by the kernel must be untagged. + pub struct TaggedAddressMode: u32 { + /// Addresses that are passed for the purpose of being dereferenced by the kernel may be tagged. + const ENABLED = 1_u32 << 0; + /// Synchronous tag check fault mode. + const TCF_SYNC = 1_u32 << 1; + /// Asynchronous tag check fault mode. + const TCF_ASYNC = 1_u32 << 2; + } +} + +/// Get the current tagged address mode for the calling thread. +/// +/// # References +/// - [`prctl(PR_GET_TAGGED_ADDR_CTRL,...)`] +/// +/// [`prctl(PR_GET_TAGGED_ADDR_CTRL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn current_tagged_address_mode() -> io::Result<(Option, u32)> { + let r = unsafe { prctl_1arg(PR_GET_TAGGED_ADDR_CTRL)? } as c_uint; + let mode = r & 0b111_u32; + let mte_tag = (r & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT; + Ok((TaggedAddressMode::from_bits(mode), mte_tag)) +} + +const PR_SET_TAGGED_ADDR_CTRL: c_int = 55; + +/// Controls support for passing tagged user-space addresses to the kernel. +/// +/// # References +/// - [`prctl(PR_SET_TAGGED_ADDR_CTRL,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_TAGGED_ADDR_CTRL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn set_current_tagged_address_mode( + mode: Option, + mte_tag: u32, +) -> io::Result<()> { + let config = mode.as_ref().map_or(0_u32, TaggedAddressMode::bits) + | ((mte_tag << PR_MTE_TAG_SHIFT) & PR_MTE_TAG_MASK); + prctl_2args(PR_SET_TAGGED_ADDR_CTRL, config as usize as *mut _).map(|_r| ()) +} + +// +// PR_SET_SYSCALL_USER_DISPATCH +// + +const PR_SET_SYSCALL_USER_DISPATCH: c_int = 59; + +const PR_SYS_DISPATCH_OFF: usize = 0; + +/// Disable Syscall User Dispatch mechanism. +/// +/// # References +/// - [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn disable_syscall_user_dispatch() -> io::Result<()> { + prctl_2args(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_OFF as *mut _).map(|_r| ()) +} + +const PR_SYS_DISPATCH_ON: usize = 1; + +/// Allow system calls to be executed. +const SYSCALL_DISPATCH_FILTER_ALLOW: u8 = 0; +/// Block system calls from executing. +const SYSCALL_DISPATCH_FILTER_BLOCK: u8 = 1; + +/// Value of the fast switch flag controlling system calls user dispatch mechanism without the need +/// to issue a syscall. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u8)] +pub enum SysCallUserDispatchFastSwitch { + /// System calls are allowed to execute. + Allow = SYSCALL_DISPATCH_FILTER_ALLOW, + /// System calls are blocked from executing. + Block = SYSCALL_DISPATCH_FILTER_BLOCK, +} + +impl TryFrom for SysCallUserDispatchFastSwitch { + type Error = io::Errno; + + fn try_from(value: u8) -> Result { + match value { + SYSCALL_DISPATCH_FILTER_ALLOW => Ok(Self::Allow), + SYSCALL_DISPATCH_FILTER_BLOCK => Ok(Self::Block), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Enable Syscall User Dispatch mechanism. +/// +/// # References +/// - [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,...)`] +/// +/// # Safety +/// +/// Please ensure the conditions necessary to safely call this function, +/// as detailed in the references above. +/// +/// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub unsafe fn enable_syscall_user_dispatch( + always_allowed_region: &[u8], + fast_switch_flag: &AtomicU8, +) -> io::Result<()> { + syscalls::prctl( + PR_SET_SYSCALL_USER_DISPATCH, + PR_SYS_DISPATCH_ON as *mut _, + always_allowed_region.as_ptr() as *mut _, + always_allowed_region.len() as *mut _, + fast_switch_flag as *const AtomicU8 as *mut _, + ) + .map(|_r| ()) +} + +// +// PR_SCHED_CORE +// + +const PR_SCHED_CORE: c_int = 62; + +const PR_SCHED_CORE_GET: usize = 0; + +const PR_SCHED_CORE_SCOPE_THREAD: u32 = 0; +const PR_SCHED_CORE_SCOPE_THREAD_GROUP: u32 = 1; +const PR_SCHED_CORE_SCOPE_PROCESS_GROUP: u32 = 2; + +/// `PR_SCHED_CORE_SCOPE_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum CoreSchedulingScope { + /// Operation will be performed for the thread. + Thread = PR_SCHED_CORE_SCOPE_THREAD, + /// Operation will be performed for all tasks in the task group of the process. + ThreadGroup = PR_SCHED_CORE_SCOPE_THREAD_GROUP, + /// Operation will be performed for all processes in the process group. + ProcessGroup = PR_SCHED_CORE_SCOPE_PROCESS_GROUP, +} + +impl TryFrom for CoreSchedulingScope { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + match value { + PR_SCHED_CORE_SCOPE_THREAD => Ok(Self::Thread), + PR_SCHED_CORE_SCOPE_THREAD_GROUP => Ok(Self::ThreadGroup), + PR_SCHED_CORE_SCOPE_PROCESS_GROUP => Ok(Self::ProcessGroup), + _ => Err(io::Errno::RANGE), + } + } +} + +/// Get core scheduling cookie of a process. +/// +/// # References +/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_GET,...)`] +/// +/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_GET,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html +#[inline] +pub fn core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result { + let mut value: MaybeUninit = MaybeUninit::uninit(); + unsafe { + syscalls::prctl( + PR_SCHED_CORE, + PR_SCHED_CORE_GET as *mut _, + pid.as_raw_nonzero().get() as usize as *mut _, + scope as usize as *mut _, + value.as_mut_ptr().cast(), + )?; + Ok(value.assume_init()) + } +} + +const PR_SCHED_CORE_CREATE: usize = 1; + +/// Create unique core scheduling cookie. +/// +/// # References +/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_CREATE,...)`] +/// +/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_CREATE,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html +#[inline] +pub fn create_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> { + unsafe { + syscalls::prctl( + PR_SCHED_CORE, + PR_SCHED_CORE_CREATE as *mut _, + pid.as_raw_nonzero().get() as usize as *mut _, + scope as usize as *mut _, + ptr::null_mut(), + ) + .map(|_r| ()) + } +} + +const PR_SCHED_CORE_SHARE_TO: usize = 2; + +/// Push core scheduling cookie to a process. +/// +/// # References +/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_TO,...)`] +/// +/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_TO,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html +#[inline] +pub fn push_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> { + unsafe { + syscalls::prctl( + PR_SCHED_CORE, + PR_SCHED_CORE_SHARE_TO as *mut _, + pid.as_raw_nonzero().get() as usize as *mut _, + scope as usize as *mut _, + ptr::null_mut(), + ) + .map(|_r| ()) + } +} + +const PR_SCHED_CORE_SHARE_FROM: usize = 3; + +/// Pull core scheduling cookie from a process. +/// +/// # References +/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_FROM,...)`] +/// +/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_FROM,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html +#[inline] +pub fn pull_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> { + unsafe { + syscalls::prctl( + PR_SCHED_CORE, + PR_SCHED_CORE_SHARE_FROM as *mut _, + pid.as_raw_nonzero().get() as usize as *mut _, + scope as usize as *mut _, + ptr::null_mut(), + ) + .map(|_r| ()) + } +} diff --git a/vendor/rustix/src/thread/setns.rs b/vendor/rustix/src/thread/setns.rs new file mode 100644 index 000000000..0a5564ae1 --- /dev/null +++ b/vendor/rustix/src/thread/setns.rs @@ -0,0 +1,89 @@ +#![allow(unsafe_code)] + +use bitflags::bitflags; +use linux_raw_sys::general::{ + CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWTIME, + CLONE_NEWUSER, CLONE_NEWUTS, +}; + +use crate::backend::c::c_int; +use crate::backend::thread::syscalls; +use crate::fd::BorrowedFd; +use crate::io; + +bitflags! { + /// Thread name space type. + pub struct ThreadNameSpaceType: u32 { + /// Time name space. + const TIME = CLONE_NEWTIME; + /// Mount name space. + const MOUNT = CLONE_NEWNS; + /// Control group (CGroup) name space. + const CONTROL_GROUP = CLONE_NEWCGROUP; + /// `Host name` and `NIS domain name` (UTS) name space. + const HOST_NAME_AND_NIS_DOMAIN_NAME = CLONE_NEWUTS; + /// Inter-process communication (IPC) name space. + const INTER_PROCESS_COMMUNICATION = CLONE_NEWIPC; + /// User name space. + const USER = CLONE_NEWUSER; + /// Process ID name space. + const PROCESS_ID = CLONE_NEWPID; + /// Network name space. + const NETWORK = CLONE_NEWNET; + } +} + +/// Type of name space referred to by a link. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum LinkNameSpaceType { + /// Time name space. + Time = CLONE_NEWTIME, + /// Mount name space. + Mount = CLONE_NEWNS, + /// Control group (CGroup) name space. + ControlGroup = CLONE_NEWCGROUP, + /// `Host name` and `NIS domain name` (UTS) name space. + HostNameAndNISDomainName = CLONE_NEWUTS, + /// Inter-process communication (IPC) name space. + InterProcessCommunication = CLONE_NEWIPC, + /// User name space. + User = CLONE_NEWUSER, + /// Process ID name space. + ProcessID = CLONE_NEWPID, + /// Network name space. + Network = CLONE_NEWNET, +} + +/// Reassociate the calling thread with the namespace associated with link referred to by `fd`. +/// +/// `fd` must refer to one of the magic links in a `/proc/[pid]/ns/` directory, or a bind mount +/// to such a link. +/// +/// # References +/// - [`setns`] +/// +/// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html +pub fn move_into_link_name_space( + fd: BorrowedFd, + allowed_type: Option, +) -> io::Result<()> { + let allowed_type = allowed_type.map_or(0, |t| t as c_int); + syscalls::setns(fd, allowed_type).map(|_r| ()) +} + +/// Atomically move the calling thread into one or more of the same namespaces as the thread +/// referred to by `fd`. +/// +/// `fd` must refer to a thread ID. See: `pidfd_open` and `clone`. +/// +/// # References +/// - [`setns`] +/// +/// [`setns`]: https://man7.org/linux/man-pages/man2/setns.2.html +pub fn move_into_thread_name_spaces( + fd: BorrowedFd, + allowed_types: ThreadNameSpaceType, +) -> io::Result<()> { + syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r| ()) +} diff --git a/vendor/rustix/src/time/clock.rs b/vendor/rustix/src/time/clock.rs index 32d888749..2e23f91b8 100644 --- a/vendor/rustix/src/time/clock.rs +++ b/vendor/rustix/src/time/clock.rs @@ -1,10 +1,10 @@ -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::time::types::{Nsecs, Secs, Timespec}; +pub use backend::time::types::{Nsecs, Secs, Timespec}; /// `clockid_t` #[cfg(any(not(target_os = "wasi")))] -pub use imp::time::types::{ClockId, DynamicClockId}; +pub use backend::time::types::{ClockId, DynamicClockId}; /// `clock_getres(id)`—Returns the resolution of a clock. /// @@ -18,7 +18,7 @@ pub use imp::time::types::{ClockId, DynamicClockId}; #[inline] #[must_use] pub fn clock_getres(id: ClockId) -> Timespec { - imp::time::syscalls::clock_getres(id) + backend::time::syscalls::clock_getres(id) } /// `clock_gettime(id)`—Returns the current value of a clock. @@ -38,7 +38,7 @@ pub fn clock_getres(id: ClockId) -> Timespec { #[inline] #[must_use] pub fn clock_gettime(id: ClockId) -> Timespec { - imp::time::syscalls::clock_gettime(id) + backend::time::syscalls::clock_gettime(id) } /// Like [`clock_gettime`] but with support for dynamic clocks. @@ -52,5 +52,5 @@ pub fn clock_gettime(id: ClockId) -> Timespec { #[cfg(not(target_os = "wasi"))] #[inline] pub fn clock_gettime_dynamic(id: DynamicClockId<'_>) -> io::Result { - imp::time::syscalls::clock_gettime_dynamic(id) + backend::time::syscalls::clock_gettime_dynamic(id) } diff --git a/vendor/rustix/src/time/timerfd.rs b/vendor/rustix/src/time/timerfd.rs index 5abe6ff52..7f661f7d9 100644 --- a/vendor/rustix/src/time/timerfd.rs +++ b/vendor/rustix/src/time/timerfd.rs @@ -1,8 +1,7 @@ -use crate::fd::AsFd; -use crate::imp; -use crate::io::{self, OwnedFd}; +use crate::fd::{AsFd, OwnedFd}; +use crate::{backend, io}; -pub use imp::time::types::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; +pub use backend::time::types::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTimerFlags}; /// `timerfd_create(clockid, flags)`—Create a timer. /// @@ -12,7 +11,7 @@ pub use imp::time::types::{Itimerspec, TimerfdClockId, TimerfdFlags, TimerfdTime /// [Linux]: https://man7.org/linux/man-pages/man2/timerfd_create.2.html #[inline] pub fn timerfd_create(clockid: TimerfdClockId, flags: TimerfdFlags) -> io::Result { - imp::time::syscalls::timerfd_create(clockid, flags) + backend::time::syscalls::timerfd_create(clockid, flags) } /// `timerfd_settime(clockid, flags, new_value)`—Set the time on a timer. @@ -27,7 +26,7 @@ pub fn timerfd_settime( flags: TimerfdTimerFlags, new_value: &Itimerspec, ) -> io::Result { - imp::time::syscalls::timerfd_settime(fd.as_fd(), flags, new_value) + backend::time::syscalls::timerfd_settime(fd.as_fd(), flags, new_value) } /// `timerfd_gettime(clockid, flags)`—Query a timer. @@ -38,5 +37,5 @@ pub fn timerfd_settime( /// [Linux]: https://man7.org/linux/man-pages/man2/timerfd_gettime.2.html #[inline] pub fn timerfd_gettime(fd: Fd) -> io::Result { - imp::time::syscalls::timerfd_gettime(fd.as_fd()) + backend::time::syscalls::timerfd_gettime(fd.as_fd()) } diff --git a/vendor/rustix/src/utils.rs b/vendor/rustix/src/utils.rs index efbbe81aa..dcbadb260 100644 --- a/vendor/rustix/src/utils.rs +++ b/vendor/rustix/src/utils.rs @@ -11,3 +11,19 @@ pub(crate) const fn as_ptr(t: &T) -> *const T { pub(crate) fn as_mut_ptr(t: &mut T) -> *mut T { t } + +/// Convert a `*mut c_void` to a `*mut T`, checking that it is not null, +/// misaligned, or pointing to a region of memory that wraps around the address +/// space. +#[allow(dead_code)] +pub(crate) fn check_raw_pointer(value: *mut core::ffi::c_void) -> Option> { + if (value as usize) + .checked_add(core::mem::size_of::()) + .is_none() + || (value as usize) % core::mem::align_of::() != 0 + { + return None; + } + + core::ptr::NonNull::new(value.cast()) +} diff --git a/vendor/rustix/tests/backends.rs b/vendor/rustix/tests/backends.rs deleted file mode 100644 index 4b88bd11c..000000000 --- a/vendor/rustix/tests/backends.rs +++ /dev/null @@ -1,109 +0,0 @@ -use std::process::Command; - -#[test] -fn test_backends() { - // Pick an arbitrary platform where linux_raw is enabled by default and - // ensure that the use-default crate uses it. - #[cfg(all(target_os = "linux", target_arch = "aarch64"))] - { - assert!( - !has_dependency("test-crates/use-default", &[], &[], &["RUSTFLAGS"], "libc"), - "use-default depends on libc" - ); - assert!( - has_dependency( - "test-crates/use-default", - &[], - &[], - &["RUSTFLAGS"], - "linux-raw-sys" - ), - "use-default does not depend on linux-raw-sys" - ); - } - - #[cfg(windows)] - let libc_dep = "windows-sys"; - #[cfg(unix)] - let libc_dep = "libc"; - - // Test the use-libc crate, which enables the "use-libc" cargo feature. - assert!( - has_dependency("test-crates/use-libc", &[], &[], &["RUSTFLAGS"], libc_dep), - "use-libc doesn't depend on {}", - libc_dep - ); - - // Test the use-default crate with `--cfg=rustix_use_libc`. - assert!( - has_dependency( - "test-crates/use-default", - &[], - &[("RUSTFLAGS", "--cfg=rustix_use_libc")], - &[], - libc_dep - ), - "use-default with --cfg=rustix_use_libc does not depend on {}", - libc_dep - ); - assert!( - !has_dependency( - "test-crates/use-default", - &[], - &[("RUSTFLAGS", "--cfg=rustix_use_libc")], - &[], - "linux-raw-sys" - ), - "use-default with --cfg=rustix_use_libc depends on linux-raw-sys" - ); - - // Test the use-default crate with `--features=rustix/use-libc`. - assert!( - has_dependency( - "test-crates/use-default", - &["--features=rustix/use-libc"], - &[], - &[], - libc_dep - ), - "use-default with --features=rustix/use-libc does not depend on {}", - libc_dep - ); -} - -/// Test whether the crate at directory `dir` has a dependency on `dependency`, -/// setting the environment variables `envs` and unsetting the environment -/// variables `remove_envs` when running `cargo`. -fn has_dependency( - dir: &str, - args: &[&str], - envs: &[(&str, &str)], - remove_envs: &[&str], - dependency: &str, -) -> bool { - let mut command = Command::new("cargo"); - - command - .arg("tree") - .arg("--quiet") - .arg("--edges=normal") - .arg(&format!("--invert={}", dependency)) - .current_dir(dir); - - command.args(args); - for (key, value) in envs { - command.env(key, value); - } - for key in remove_envs { - command.env_remove(key); - } - - let child = command.output().unwrap(); - - // `cargo tree --invert=foo` can fail in two different ways: it exits with - // a non-zero status if the dependency is not present in the Cargo.toml - // configuration, and it exists with a zero status and prints nothing if - // the dependency is present but optional and not enabled. So we check for - // both here. - child.status.success() && !child.stdout.is_empty() -} diff --git a/vendor/rustix/tests/fs/cwd.rs b/vendor/rustix/tests/fs/cwd.rs deleted file mode 100644 index 749c84f24..000000000 --- a/vendor/rustix/tests/fs/cwd.rs +++ /dev/null @@ -1,3 +0,0 @@ -/// Make sure we can use `cwd` in const contexts. -#[allow(dead_code)] -const CWD: rustix::fd::BorrowedFd<'static> = rustix::fs::cwd(); diff --git a/vendor/rustix/tests/fs/dir.rs b/vendor/rustix/tests/fs/dir.rs deleted file mode 100644 index f5120be96..000000000 --- a/vendor/rustix/tests/fs/dir.rs +++ /dev/null @@ -1,37 +0,0 @@ -#[test] -fn test_dir() { - let t = rustix::fs::openat( - rustix::fs::cwd(), - rustix::cstr!("."), - rustix::fs::OFlags::RDONLY | rustix::fs::OFlags::CLOEXEC, - rustix::fs::Mode::empty(), - ) - .unwrap(); - - let dir = rustix::fs::Dir::read_from(&t).unwrap(); - - let _file = rustix::fs::openat( - &t, - rustix::cstr!("Cargo.toml"), - rustix::fs::OFlags::RDONLY | rustix::fs::OFlags::CLOEXEC, - rustix::fs::Mode::empty(), - ) - .unwrap(); - - let mut saw_dot = false; - let mut saw_dotdot = false; - let mut saw_cargo_toml = false; - for entry in dir { - let entry = entry.unwrap(); - if entry.file_name() == rustix::cstr!(".") { - saw_dot = true; - } else if entry.file_name() == rustix::cstr!("..") { - saw_dotdot = true; - } else if entry.file_name() == rustix::cstr!("Cargo.toml") { - saw_cargo_toml = true; - } - } - assert!(saw_dot); - assert!(saw_dotdot); - assert!(saw_cargo_toml); -} diff --git a/vendor/rustix/tests/fs/fcntl.rs b/vendor/rustix/tests/fs/fcntl.rs deleted file mode 100644 index 1f8b78387..000000000 --- a/vendor/rustix/tests/fs/fcntl.rs +++ /dev/null @@ -1,17 +0,0 @@ -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_fcntl_dupfd_cloexec() { - use rustix::fd::AsFd; - use std::os::unix::io::AsRawFd; - - let file = rustix::fs::openat( - rustix::fs::cwd(), - "Cargo.toml", - rustix::fs::OFlags::RDONLY, - rustix::fs::Mode::empty(), - ) - .unwrap(); - - let new = rustix::fs::fcntl_dupfd_cloexec(&file, 700).unwrap(); - assert_eq!(new.as_fd().as_raw_fd(), 700); -} diff --git a/vendor/rustix/tests/fs/file.rs b/vendor/rustix/tests/fs/file.rs deleted file mode 100644 index 5c09f640d..000000000 --- a/vendor/rustix/tests/fs/file.rs +++ /dev/null @@ -1,83 +0,0 @@ -#[cfg(not(target_os = "redox"))] -#[test] -fn test_file() { - #[cfg(not(target_os = "illumos"))] - rustix::fs::accessat( - rustix::fs::cwd(), - "Cargo.toml", - rustix::fs::Access::READ_OK, - rustix::fs::AtFlags::empty(), - ) - .unwrap(); - - assert_eq!( - rustix::fs::openat( - rustix::fs::cwd(), - "Cagro.motl", - rustix::fs::OFlags::RDONLY, - rustix::fs::Mode::empty(), - ) - .unwrap_err(), - rustix::io::Errno::NOENT - ); - - let file = rustix::fs::openat( - rustix::fs::cwd(), - "Cargo.toml", - rustix::fs::OFlags::RDONLY, - rustix::fs::Mode::empty(), - ) - .unwrap(); - - assert_eq!( - rustix::fs::openat( - &file, - "Cargo.toml", - rustix::fs::OFlags::RDONLY, - rustix::fs::Mode::empty(), - ) - .unwrap_err(), - rustix::io::Errno::NOTDIR - ); - - #[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - )))] - rustix::fs::fadvise(&file, 0, 10, rustix::fs::Advice::Normal).unwrap(); - - assert_eq!( - rustix::fs::fcntl_getfd(&file).unwrap(), - rustix::fs::FdFlags::empty() - ); - assert_eq!( - rustix::fs::fcntl_getfl(&file).unwrap(), - rustix::fs::OFlags::empty() - ); - - let stat = rustix::fs::fstat(&file).unwrap(); - assert!(stat.st_size > 0); - assert!(stat.st_blocks > 0); - - #[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", - )))] - // not implemented in libc for netbsd yet - { - let statfs = rustix::fs::fstatfs(&file).unwrap(); - assert!(statfs.f_blocks > 0); - } - - #[cfg(feature = "net")] - assert_eq!(rustix::io::is_read_write(&file).unwrap(), (true, false)); - - assert_ne!(rustix::io::ioctl_fionread(&file).unwrap(), 0); -} diff --git a/vendor/rustix/tests/fs/flock.rs b/vendor/rustix/tests/fs/flock.rs deleted file mode 100644 index 1b7df6ffd..000000000 --- a/vendor/rustix/tests/fs/flock.rs +++ /dev/null @@ -1,34 +0,0 @@ -#[cfg(not(target_os = "redox"))] -#[test] -fn test_flock() { - use rustix::fs::{cwd, flock, openat, FlockOperation, Mode, OFlags}; - - let f = openat(cwd(), "Cargo.toml", OFlags::RDONLY, Mode::empty()).unwrap(); - flock(&f, FlockOperation::LockExclusive).unwrap(); - flock(&f, FlockOperation::Unlock).unwrap(); - let g = openat(cwd(), "Cargo.toml", OFlags::RDONLY, Mode::empty()).unwrap(); - flock(&g, FlockOperation::LockExclusive).unwrap(); - flock(&g, FlockOperation::Unlock).unwrap(); - drop(f); - drop(g); - - let f = openat(cwd(), "Cargo.toml", OFlags::RDONLY, Mode::empty()).unwrap(); - flock(&f, FlockOperation::LockShared).unwrap(); - let g = openat(cwd(), "Cargo.toml", OFlags::RDONLY, Mode::empty()).unwrap(); - flock(&g, FlockOperation::LockShared).unwrap(); - flock(&f, FlockOperation::Unlock).unwrap(); - flock(&g, FlockOperation::Unlock).unwrap(); - drop(f); - drop(g); - - let f = openat(cwd(), "Cargo.toml", OFlags::RDONLY, Mode::empty()).unwrap(); - flock(&f, FlockOperation::LockShared).unwrap(); - flock(&f, FlockOperation::LockExclusive).unwrap(); - flock(&f, FlockOperation::Unlock).unwrap(); - let g = openat(cwd(), "Cargo.toml", OFlags::RDONLY, Mode::empty()).unwrap(); - flock(&g, FlockOperation::LockShared).unwrap(); - flock(&g, FlockOperation::LockExclusive).unwrap(); - flock(&g, FlockOperation::Unlock).unwrap(); - drop(f); - drop(g); -} diff --git a/vendor/rustix/tests/fs/futimens.rs b/vendor/rustix/tests/fs/futimens.rs deleted file mode 100644 index 81f8b8a27..000000000 --- a/vendor/rustix/tests/fs/futimens.rs +++ /dev/null @@ -1,42 +0,0 @@ -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_futimens() { - use rustix::fs::{cwd, fstat, futimens, openat, Mode, OFlags, Timespec, Timestamps}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - let foo = openat( - &dir, - "foo", - OFlags::CREATE | OFlags::WRONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - - let times = Timestamps { - last_access: Timespec { - tv_sec: 44000, - tv_nsec: 45000, - }, - last_modification: Timespec { - tv_sec: 46000, - tv_nsec: 47000, - }, - }; - futimens(&foo, ×).unwrap(); - - let after = fstat(&foo).unwrap(); - - assert_eq!(times.last_modification.tv_sec as u64, after.st_mtime as u64); - #[cfg(not(target_os = "netbsd"))] - assert_eq!( - times.last_modification.tv_nsec as u64, - after.st_mtime_nsec as u64 - ); - #[cfg(target_os = "netbsd")] - assert_eq!( - times.last_modification.tv_nsec as u64, - after.st_mtimensec as u64 - ); -} diff --git a/vendor/rustix/tests/fs/invalid_offset.rs b/vendor/rustix/tests/fs/invalid_offset.rs deleted file mode 100644 index 995e302a1..000000000 --- a/vendor/rustix/tests/fs/invalid_offset.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Tests for extreme `u64` file offsets. -//! -//! POSIX-ish interfaces tend to use signed integers for file offsets, while -//! Rust APIs tend to use `u64`. Test that extreme `u64` values in APIs that -//! take file offsets are properly diagnosed. -//! -//! These tests are disabled on ios/macos since those platforms kill the -//! process with `SIGXFSZ` instead of returning an error. - -#![cfg(not(any(target_os = "redox", target_os = "wasi")))] - -use rustix::io::SeekFrom; - -#[test] -fn invalid_offset_seek() { - use rustix::fs::{cwd, openat, seek, Mode, OFlags}; - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let file = openat( - &dir, - "foo", - OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - seek(&file, SeekFrom::Start(u64::MAX)).unwrap_err(); - seek(&file, SeekFrom::Start(i64::MAX as u64 + 1)).unwrap_err(); - seek(&file, SeekFrom::End(-1)).unwrap_err(); - seek(&file, SeekFrom::End(i64::MIN)).unwrap_err(); - seek(&file, SeekFrom::Current(-1)).unwrap_err(); - seek(&file, SeekFrom::Current(i64::MIN)).unwrap_err(); -} - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -#[test] -fn invalid_offset_fallocate() { - use rustix::fs::{cwd, fallocate, openat, FallocateFlags, Mode, OFlags}; - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let file = openat( - &dir, - "foo", - OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - fallocate(&file, FallocateFlags::empty(), u64::MAX, 1).unwrap_err(); - fallocate(&file, FallocateFlags::empty(), i64::MAX as u64 + 1, 1).unwrap_err(); - fallocate(&file, FallocateFlags::empty(), 0, u64::MAX).unwrap_err(); - fallocate(&file, FallocateFlags::empty(), 0, i64::MAX as u64 + 1).unwrap_err(); -} - -#[cfg(not(any( - target_os = "dragonfly", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", -)))] -#[test] -fn invalid_offset_fadvise() { - use rustix::fs::{cwd, fadvise, openat, Advice, Mode, OFlags}; - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let file = openat( - &dir, - "foo", - OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - // `fadvise` never fails on invalid offsets. - fadvise(&file, i64::MAX as u64, i64::MAX as u64, Advice::Normal).unwrap(); - fadvise(&file, u64::MAX, 0, Advice::Normal).unwrap(); - fadvise(&file, i64::MAX as u64, 1, Advice::Normal).unwrap(); - fadvise(&file, 1, i64::MAX as u64, Advice::Normal).unwrap(); - fadvise(&file, i64::MAX as u64 + 1, 0, Advice::Normal).unwrap(); - fadvise(&file, u64::MAX, i64::MAX as u64, Advice::Normal).unwrap(); - - // `fadvise` fails on invalid lengths. - fadvise(&file, u64::MAX, u64::MAX, Advice::Normal).unwrap_err(); - fadvise(&file, i64::MAX as u64, u64::MAX, Advice::Normal).unwrap_err(); - fadvise(&file, 0, u64::MAX, Advice::Normal).unwrap_err(); - fadvise(&file, u64::MAX, i64::MAX as u64 + 1, Advice::Normal).unwrap_err(); - fadvise(&file, i64::MAX as u64 + 1, u64::MAX, Advice::Normal).unwrap_err(); - fadvise(&file, i64::MAX as u64, i64::MAX as u64 + 1, Advice::Normal).unwrap_err(); - fadvise(&file, 0, i64::MAX as u64 + 1, Advice::Normal).unwrap_err(); -} - -#[test] -fn invalid_offset_pread() { - use rustix::fs::{cwd, openat, Mode, OFlags}; - use rustix::io::pread; - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let file = openat( - &dir, - "foo", - OFlags::RDWR | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - let mut buf = [0_u8; 1]; - pread(&file, &mut buf, u64::MAX).unwrap_err(); - pread(&file, &mut buf, i64::MAX as u64 + 1).unwrap_err(); -} - -#[cfg(not(any(target_os = "ios", target_os = "macos")))] -#[test] -fn invalid_offset_pwrite() { - use rustix::fs::{cwd, openat, Mode, OFlags}; - use rustix::io::pwrite; - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let file = openat( - &dir, - "foo", - OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - let buf = [0_u8; 1]; - pwrite(&file, &buf, u64::MAX).unwrap_err(); - pwrite(&file, &buf, i64::MAX as u64 + 1).unwrap_err(); -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn invalid_offset_copy_file_range() { - use rustix::fs::{copy_file_range, cwd, openat, Mode, OFlags}; - use rustix::io::write; - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let foo = openat( - &dir, - "foo", - OFlags::RDWR | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - let bar = openat( - &dir, - "bar", - OFlags::WRONLY | OFlags::TRUNC | OFlags::CREATE, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - write(&foo, b"a").unwrap(); - - let mut off_in = u64::MAX; - let mut off_out = 0; - copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err(); - - let mut off_in = i64::MAX as u64 + 1; - let mut off_out = 0; - copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err(); - - let mut off_in = 0; - let mut off_out = u64::MAX; - copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err(); - - let mut off_in = 0; - let mut off_out = i64::MAX as u64; - copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err(); - - let mut off_in = 0; - let mut off_out = i64::MAX as u64 + 1; - copy_file_range(&foo, Some(&mut off_in), &bar, Some(&mut off_out), 1).unwrap_err(); -} diff --git a/vendor/rustix/tests/fs/long_paths.rs b/vendor/rustix/tests/fs/long_paths.rs deleted file mode 100644 index dbc2fa6ea..000000000 --- a/vendor/rustix/tests/fs/long_paths.rs +++ /dev/null @@ -1,28 +0,0 @@ -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_long_paths() { - use rustix::fs::{cwd, mkdirat, openat, Mode, OFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - #[cfg(libc)] - const PATH_MAX: usize = libc::PATH_MAX as usize; - #[cfg(linux_raw)] - const PATH_MAX: usize = linux_raw_sys::general::PATH_MAX as usize; - - mkdirat(&dir, "a", Mode::RUSR | Mode::XUSR | Mode::WUSR).unwrap(); - - let mut long_path = String::new(); - for _ in 0..PATH_MAX / 5 { - long_path.push_str("a/../"); - } - - let mut too_long_path = String::new(); - for _ in 0..PATH_MAX / 4 { - too_long_path.push_str("a/../"); - } - - let _ = openat(&dir, &long_path, OFlags::RDONLY, Mode::empty()).unwrap(); - let _ = openat(&dir, &too_long_path, OFlags::RDONLY, Mode::empty()).unwrap_err(); -} diff --git a/vendor/rustix/tests/fs/main.rs b/vendor/rustix/tests/fs/main.rs deleted file mode 100644 index 23928a6ba..000000000 --- a/vendor/rustix/tests/fs/main.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! Tests for [`rustix::fs`]. - -#![cfg(feature = "fs")] -#![cfg(not(windows))] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] -#![cfg_attr(core_c_str, feature(core_c_str))] - -mod cwd; -mod dir; -mod fcntl; -mod file; -#[cfg(not(target_os = "wasi"))] -mod flock; -mod futimens; -mod invalid_offset; -mod long_paths; -#[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -mod makedev; -mod mkdirat; -mod mknodat; -#[cfg(any(target_os = "android", target_os = "linux"))] -mod openat; -#[cfg(any(target_os = "android", target_os = "linux"))] -mod openat2; -mod readdir; -mod renameat; -#[cfg(not(any( - target_os = "illumos", - target_os = "netbsd", - target_os = "redox", - target_os = "wasi", -)))] -// not implemented in libc for netbsd yet -mod statfs; -mod utimensat; -mod y2038; diff --git a/vendor/rustix/tests/fs/makedev.rs b/vendor/rustix/tests/fs/makedev.rs deleted file mode 100644 index 79b5199e8..000000000 --- a/vendor/rustix/tests/fs/makedev.rs +++ /dev/null @@ -1,10 +0,0 @@ -use rustix::fs::{major, makedev, minor}; - -#[test] -fn makedev_roundtrip() { - let maj = 0x2324_2526; - let min = 0x6564_6361; - let dev = makedev(maj, min); - assert_eq!(maj, major(dev)); - assert_eq!(min, minor(dev)); -} diff --git a/vendor/rustix/tests/fs/mkdirat.rs b/vendor/rustix/tests/fs/mkdirat.rs deleted file mode 100644 index 884588037..000000000 --- a/vendor/rustix/tests/fs/mkdirat.rs +++ /dev/null @@ -1,33 +0,0 @@ -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_mkdirat() { - use rustix::fs::{cwd, mkdirat, openat, statat, unlinkat, AtFlags, FileType, Mode, OFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - mkdirat(&dir, "foo", Mode::RWXU).unwrap(); - let stat = statat(&dir, "foo", AtFlags::empty()).unwrap(); - assert_eq!(FileType::from_raw_mode(stat.st_mode), FileType::Directory); - unlinkat(&dir, "foo", AtFlags::REMOVEDIR).unwrap(); -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_mkdirat_with_o_path() { - use rustix::fs::{cwd, mkdirat, openat, statat, unlinkat, AtFlags, FileType, Mode, OFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::PATH, - Mode::empty(), - ) - .unwrap(); - - mkdirat(&dir, "foo", Mode::RWXU).unwrap(); - let stat = statat(&dir, "foo", AtFlags::empty()).unwrap(); - assert_eq!(FileType::from_raw_mode(stat.st_mode), FileType::Directory); - unlinkat(&dir, "foo", AtFlags::REMOVEDIR).unwrap(); -} diff --git a/vendor/rustix/tests/fs/mknodat.rs b/vendor/rustix/tests/fs/mknodat.rs deleted file mode 100644 index fa1c84f69..000000000 --- a/vendor/rustix/tests/fs/mknodat.rs +++ /dev/null @@ -1,27 +0,0 @@ -#[cfg(not(any( - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -#[test] -fn test_mknodat() { - use rustix::fs::{cwd, mknodat, openat, statat, unlinkat, AtFlags, FileType, Mode, OFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - // Create a regular file. Not supported on FreeBSD or OpenBSD. - #[cfg(not(any(target_os = "freebsd", target_os = "openbsd")))] - { - mknodat(&dir, "foo", FileType::RegularFile, Mode::empty(), 0).unwrap(); - let stat = statat(&dir, "foo", AtFlags::empty()).unwrap(); - assert_eq!(FileType::from_raw_mode(stat.st_mode), FileType::RegularFile); - unlinkat(&dir, "foo", AtFlags::empty()).unwrap(); - } - - mknodat(&dir, "foo", FileType::Fifo, Mode::empty(), 0).unwrap(); - let stat = statat(&dir, "foo", AtFlags::empty()).unwrap(); - assert_eq!(FileType::from_raw_mode(stat.st_mode), FileType::Fifo); - unlinkat(&dir, "foo", AtFlags::empty()).unwrap(); -} diff --git a/vendor/rustix/tests/fs/openat.rs b/vendor/rustix/tests/fs/openat.rs deleted file mode 100644 index 564574dc1..000000000 --- a/vendor/rustix/tests/fs/openat.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::fs::File; - -use io_lifetimes::{FromFd, IntoFd}; -use rustix::fs::{cwd, openat, Mode, OFlags}; -use std::io::Write; - -#[test] -fn test_openat_tmpfile() { - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - let f = match openat( - &dir, - ".", - OFlags::WRONLY | OFlags::CLOEXEC | OFlags::TMPFILE, - Mode::from_bits_truncate(0o644), - ) { - Ok(f) => Ok(Some(File::from_fd(f.into_fd()))), - // TODO: Factor out the `Err`, once we no longer support Rust 1.48. - Err(rustix::io::Errno::OPNOTSUPP) - | Err(rustix::io::Errno::ISDIR) - | Err(rustix::io::Errno::NOENT) => Ok(None), - Err(e) => Err(e), - }; - if let Some(mut f) = f.unwrap() { - write!(f, "hello world").unwrap(); - } -} diff --git a/vendor/rustix/tests/fs/openat2.rs b/vendor/rustix/tests/fs/openat2.rs deleted file mode 100644 index 0b1d86fe2..000000000 --- a/vendor/rustix/tests/fs/openat2.rs +++ /dev/null @@ -1,184 +0,0 @@ -use rustix::fd::AsFd; -use rustix::fs::{cwd, mkdirat, openat, openat2, symlinkat, Mode, OFlags, ResolveFlags}; -use rustix::io::OwnedFd; -use rustix::{io, path}; -use std::os::unix::io::AsRawFd; - -/// Like `openat2`, but keep retrying until it fails or succeeds. -fn openat2_more( - dirfd: Fd, - path: P, - oflags: OFlags, - mode: Mode, - resolve: ResolveFlags, -) -> io::Result { - let path = path.as_cow_c_str().unwrap().into_owned(); - loop { - match openat2(dirfd.as_fd(), &path, oflags, mode, resolve) { - Ok(file) => return Ok(file), - Err(io::Errno::AGAIN) => continue, - Err(err) => return Err(err), - } - } -} - -#[test] -fn test_openat2() { - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - // Detect whether `openat2` is available. - match openat2( - &dir, - ".", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) { - Ok(_file) => (), - Err(io::Errno::NOSYS) => return, - Err(_err) => return, - } - - // Create a file. - let _ = openat2_more( - &dir, - "test.txt", - OFlags::WRONLY | OFlags::CREATE | OFlags::TRUNC | OFlags::CLOEXEC, - Mode::RUSR, - ResolveFlags::empty(), - ) - .unwrap(); - - // Test `NO_SYMLINKS`. - symlinkat("test.txt", &dir, "symlink.txt").unwrap(); - let _ = openat2_more( - &dir, - "symlink.txt", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &dir, - "symlink.txt", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::NO_MAGICLINKS, - ) - .unwrap(); - let _ = openat2_more( - &dir, - "symlink.txt", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::NO_SYMLINKS, - ) - .unwrap_err(); - - // Test `NO_MAGICLINKS`. - let test = openat2_more( - &dir, - "test.txt", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &dir, - &format!("/proc/self/fd/{}", test.as_fd().as_raw_fd()), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &dir, - &format!("/proc/self/fd/{}", test.as_fd().as_raw_fd()), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::NO_SYMLINKS, - ) - .unwrap_err(); - let _ = openat2_more( - &dir, - &format!("/proc/self/fd/{}", test.as_fd().as_raw_fd()), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::NO_MAGICLINKS, - ) - .unwrap_err(); - - // Test `NO_XDEV`. - let root = openat2_more( - &dir, - "/", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &root, - "proc", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &root, - "proc", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::NO_XDEV, - ) - .unwrap_err(); - - // Test `BENEATH`. - let _ = openat2_more( - &dir, - "..", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &dir, - "..", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::BENEATH, - ) - .unwrap_err(); - - // Test `IN_ROOT`. - let _ = openat2_more( - &dir, - "/proc", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::empty(), - ) - .unwrap(); - let _ = openat2_more( - &dir, - "/proc", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::IN_ROOT, - ) - .unwrap_err(); - mkdirat(&dir, "proc", Mode::RUSR | Mode::XUSR).unwrap(); - let _ = openat2_more( - &dir, - "/proc", - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ResolveFlags::IN_ROOT, - ) - .unwrap(); -} diff --git a/vendor/rustix/tests/fs/readdir.rs b/vendor/rustix/tests/fs/readdir.rs deleted file mode 100644 index 8925660a9..000000000 --- a/vendor/rustix/tests/fs/readdir.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![cfg(not(target_os = "redox"))] - -use rustix::fs::{Dir, DirEntry}; -use std::collections::HashMap; - -#[test] -fn dir_entries() { - let tmpdir = tempfile::tempdir().expect("construct tempdir"); - let dirfd = std::fs::File::open(tmpdir.path()).expect("open tempdir as file"); - let mut dir = Dir::read_from(dirfd).expect("construct Dir from dirfd"); - - let entries = read_entries(&mut dir); - assert_eq!(entries.len(), 0, "no files in directory"); - - let _f1 = std::fs::File::create(tmpdir.path().join("file1")).expect("create file1"); - - let entries = read_entries(&mut dir); - assert!( - entries.get("file1").is_some(), - "directory contains `file1`: {:?}", - entries - ); - assert_eq!(entries.len(), 1); - - let _f2 = std::fs::File::create(tmpdir.path().join("file2")).expect("create file1"); - let entries = read_entries(&mut dir); - assert!( - entries.get("file1").is_some(), - "directory contains `file1`: {:?}", - entries - ); - assert!( - entries.get("file2").is_some(), - "directory contains `file2`: {:?}", - entries - ); - assert_eq!(entries.len(), 2); -} - -fn read_entries(dir: &mut Dir) -> HashMap { - dir.rewind(); - let mut out = HashMap::new(); - loop { - match dir.read() { - Some(e) => { - let e = e.expect("non-error entry"); - let name = e.file_name().to_str().expect("utf8 filename").to_owned(); - if name != "." && name != ".." { - out.insert(name, e); - } - } - None => break, - } - } - out -} - -#[test] -fn dir_from_openat() { - let dirfd = rustix::fs::openat( - rustix::fs::cwd(), - ".", - rustix::fs::OFlags::RDONLY, - rustix::fs::Mode::empty(), - ) - .expect("open cwd as file"); - let _dir = Dir::read_from(dirfd).expect("construct Dir from dirfd"); -} diff --git a/vendor/rustix/tests/fs/renameat.rs b/vendor/rustix/tests/fs/renameat.rs deleted file mode 100644 index 2eea2e77a..000000000 --- a/vendor/rustix/tests/fs/renameat.rs +++ /dev/null @@ -1,104 +0,0 @@ -#[cfg(any(target_os = "android", target_os = "linux"))] -use rustix::fs::Stat; - -#[cfg(any(target_os = "android", target_os = "linux"))] -fn same(a: &Stat, b: &Stat) -> bool { - a.st_ino == b.st_ino && a.st_dev == b.st_dev -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_renameat() { - use rustix::fs::{cwd, openat, renameat, statat, AtFlags, Mode, OFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::PATH, - Mode::empty(), - ) - .unwrap(); - - let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); - let before = statat(&dir, "foo", AtFlags::empty()).unwrap(); - renameat(&dir, "foo", &dir, "bar").unwrap(); - let renamed = statat(&dir, "bar", AtFlags::empty()).unwrap(); - assert!(same(&before, &renamed)); -} - -/// Like `test_renameat` but the file already exists, so `renameat` -/// overwrites it. -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_renameat_overwrite() { - use rustix::fs::{cwd, openat, renameat, statat, AtFlags, Mode, OFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::PATH, - Mode::empty(), - ) - .unwrap(); - - let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); - let _ = openat(&dir, "bar", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); - let before = statat(&dir, "foo", AtFlags::empty()).unwrap(); - renameat(&dir, "foo", &dir, "bar").unwrap(); - let renamed = statat(&dir, "bar", AtFlags::empty()).unwrap(); - assert!(same(&before, &renamed)); -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_renameat_with() { - use rustix::fs::{cwd, openat, renameat_with, statat, AtFlags, Mode, OFlags, RenameFlags}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::PATH, - Mode::empty(), - ) - .unwrap(); - - let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::empty()).unwrap(); - let before = statat(&dir, "foo", AtFlags::empty()).unwrap(); - - match renameat_with(&dir, "foo", &dir, "red", RenameFlags::empty()) { - Ok(()) => (), - Err(e) if e == rustix::io::Errno::NOSYS => return, - Err(e) => unreachable!("unexpected error from renameat_with: {:?}", e), - } - - let renamed = statat(&dir, "red", AtFlags::empty()).unwrap(); - assert!(same(&before, &renamed)); - - let _ = openat( - &dir, - "green", - OFlags::CREATE | OFlags::WRONLY, - Mode::empty(), - ) - .unwrap(); - - #[cfg(all(target_os = "linux", target_env = "gnu"))] - { - let green = statat(&dir, "green", AtFlags::empty()).unwrap(); - - renameat_with(&dir, "red", &dir, "green", RenameFlags::NOREPLACE).unwrap_err(); - let renamed = statat(&dir, "red", AtFlags::empty()).unwrap(); - assert!(same(&before, &renamed)); - let orig = statat(&dir, "green", AtFlags::empty()).unwrap(); - assert!(same(&green, &orig)); - - renameat_with(&dir, "red", &dir, "green", RenameFlags::EXCHANGE).unwrap(); - let renamed = statat(&dir, "red", AtFlags::empty()).unwrap(); - assert!(same(&green, &renamed)); - let orig = statat(&dir, "green", AtFlags::empty()).unwrap(); - assert!(same(&before, &orig)); - } -} diff --git a/vendor/rustix/tests/fs/statfs.rs b/vendor/rustix/tests/fs/statfs.rs deleted file mode 100644 index f8bf2e350..000000000 --- a/vendor/rustix/tests/fs/statfs.rs +++ /dev/null @@ -1,49 +0,0 @@ -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_statfs_abi() { - use rustix::fs::{FsWord, StatFs, NFS_SUPER_MAGIC, PROC_SUPER_MAGIC}; - - // Ensure these all have consistent types. - let t: StatFs = unsafe { std::mem::zeroed() }; - let _s: FsWord = t.f_type; - let _u: FsWord = PROC_SUPER_MAGIC; - let _v: FsWord = NFS_SUPER_MAGIC; - - // Ensure that after all the platform-specific dancing we have to do, this - // constant comes out with the correct value. - #[cfg(all(libc, not(target_env = "musl")))] - { - assert_eq!( - i128::from(PROC_SUPER_MAGIC), - i128::from(libc::PROC_SUPER_MAGIC) - ); - assert_eq!( - i128::from(NFS_SUPER_MAGIC), - i128::from(libc::NFS_SUPER_MAGIC) - ); - } - - #[cfg(linux_raw)] - { - assert_eq!( - i128::from(PROC_SUPER_MAGIC), - i128::from(linux_raw_sys::general::PROC_SUPER_MAGIC) - ); - assert_eq!( - i128::from(NFS_SUPER_MAGIC), - i128::from(linux_raw_sys::general::NFS_SUPER_MAGIC) - ); - } - - assert_eq!(PROC_SUPER_MAGIC, 0x0000_9fa0); - assert_eq!(NFS_SUPER_MAGIC, 0x0000_6969); -} - -#[test] -fn test_statfs() { - let statfs = rustix::fs::statfs("Cargo.toml").unwrap(); - let f_blocks = statfs.f_blocks; - assert_ne!(f_blocks, 0); - // Previously we checked f_files != 0 here, but at least btrfs doesn't set - // that. -} diff --git a/vendor/rustix/tests/fs/utimensat.rs b/vendor/rustix/tests/fs/utimensat.rs deleted file mode 100644 index f0fb7e27b..000000000 --- a/vendor/rustix/tests/fs/utimensat.rs +++ /dev/null @@ -1,127 +0,0 @@ -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_utimensat() { - use rustix::fs::{cwd, openat, statat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - - let _ = openat( - &dir, - "foo", - OFlags::CREATE | OFlags::WRONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - - let times = Timestamps { - last_access: Timespec { - tv_sec: 44000, - tv_nsec: 45000, - }, - last_modification: Timespec { - tv_sec: 46000, - tv_nsec: 47000, - }, - }; - utimensat(&dir, "foo", ×, AtFlags::empty()).unwrap(); - - let after = statat(&dir, "foo", AtFlags::empty()).unwrap(); - - assert_eq!(times.last_modification.tv_sec as u64, after.st_mtime as u64); - #[cfg(not(target_os = "netbsd"))] - assert_eq!( - times.last_modification.tv_nsec as u64, - after.st_mtime_nsec as u64 - ); - #[cfg(target_os = "netbsd")] - assert_eq!( - times.last_modification.tv_nsec as u64, - after.st_mtimensec as u64 - ); - assert!(times.last_access.tv_sec as u64 >= after.st_atime as u64); - #[cfg(not(target_os = "netbsd"))] - assert!( - times.last_access.tv_sec as u64 > after.st_atime as u64 - || times.last_access.tv_nsec as u64 >= after.st_atime_nsec as u64 - ); - #[cfg(target_os = "netbsd")] - assert!( - times.last_access.tv_sec as u64 > after.st_atime as u64 - || times.last_access.tv_nsec as u64 >= after.st_atimensec as u64 - ); -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_utimensat_noent() { - use rustix::fs::{cwd, openat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - - let times = Timestamps { - last_access: Timespec { - tv_sec: 44000, - tv_nsec: 45000, - }, - last_modification: Timespec { - tv_sec: 46000, - tv_nsec: 47000, - }, - }; - assert_eq!( - utimensat(&dir, "foo", ×, AtFlags::empty()).unwrap_err(), - rustix::io::Errno::NOENT - ); -} - -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -#[test] -fn test_utimensat_notdir() { - use rustix::fs::{cwd, openat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat( - cwd(), - tmp.path(), - OFlags::RDONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - - let foo = openat( - &dir, - "foo", - OFlags::CREATE | OFlags::WRONLY | OFlags::CLOEXEC, - Mode::empty(), - ) - .unwrap(); - - let times = Timestamps { - last_access: Timespec { - tv_sec: 44000, - tv_nsec: 45000, - }, - last_modification: Timespec { - tv_sec: 46000, - tv_nsec: 47000, - }, - }; - assert_eq!( - utimensat(&foo, "bar", ×, AtFlags::empty()).unwrap_err(), - rustix::io::Errno::NOTDIR - ); -} diff --git a/vendor/rustix/tests/fs/y2038.rs b/vendor/rustix/tests/fs/y2038.rs deleted file mode 100644 index 4299d709b..000000000 --- a/vendor/rustix/tests/fs/y2038.rs +++ /dev/null @@ -1,146 +0,0 @@ -/// Test that we can set a file timestamp to a date past the year 2038 with -/// `utimensat` and read it back again. -/// -/// See tests/time/y2038.rs for more information about y2038 testing. -#[cfg(not(all(target_env = "musl", target_pointer_width = "32")))] -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -#[cfg(not(all(target_os = "emscripten", target_pointer_width = "32")))] -#[test] -fn test_y2038_with_utimensat() { - use rustix::fs::{ - cwd, fstat, openat, statat, utimensat, AtFlags, Mode, OFlags, Timespec, Timestamps, - }; - use std::convert::TryInto; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(&cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - let m_sec = 1_u64 << 32; - let m_nsec = 17_u32; - let a_sec = m_sec + 1; - let a_nsec = m_nsec + 1; - - let timestamps = Timestamps { - last_modification: Timespec { - tv_sec: m_sec as _, - tv_nsec: m_nsec as _, - }, - last_access: Timespec { - tv_sec: a_sec as _, - tv_nsec: a_nsec as _, - }, - }; - let _ = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::RUSR).unwrap(); - - match utimensat(&dir, "foo", ×tamps, AtFlags::empty()) { - Ok(()) => (), - - // On 32-bit platforms, accept `EOVERFLOW`, meaning that y2038 support - // is not available in this version of the OS. - #[cfg(target_pointer_width = "32")] - Err(rustix::io::Errno::OVERFLOW) => return, - - Err(e) => panic!("unexpected error: {:?}", e), - } - - // Use `statat` to read back the timestamp. - let stat = statat(&dir, "foo", AtFlags::empty()).unwrap(); - - assert_eq!( - TryInto::::try_into(stat.st_mtime).unwrap() as u64, - m_sec - ); - assert_eq!(stat.st_mtime_nsec as u32, m_nsec); - assert!(TryInto::::try_into(stat.st_atime).unwrap() as u64 >= a_sec); - assert!( - TryInto::::try_into(stat.st_atime).unwrap() as u64 > a_sec - || stat.st_atime_nsec as u32 >= a_nsec - ); - - // Now test the same thing, but with `fstat`. - let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap(); - let stat = fstat(&file).unwrap(); - - assert_eq!( - TryInto::::try_into(stat.st_mtime).unwrap() as u64, - m_sec - ); - assert_eq!(stat.st_mtime_nsec as u32, m_nsec); - assert!(TryInto::::try_into(stat.st_atime).unwrap() as u64 >= a_sec); - assert!( - TryInto::::try_into(stat.st_atime).unwrap() as u64 > a_sec - || stat.st_atime_nsec as u32 >= a_nsec - ); -} - -/// Test that we can set a file timestamp to a date past the year 2038 with -/// `futimens` and read it back again. -/// -/// See tests/time/y2038.rs for more information about y2038 testing. -#[cfg(not(all(target_env = "musl", target_pointer_width = "32")))] -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -#[cfg(not(all(target_os = "emscripten", target_pointer_width = "32")))] -#[test] -fn test_y2038_with_futimens() { - use rustix::fs::{ - cwd, fstat, futimens, openat, statat, AtFlags, Mode, OFlags, Timespec, Timestamps, - }; - use std::convert::TryInto; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(&cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - let m_sec = 1_u64 << 32; - let m_nsec = 17_u32; - let a_sec = m_sec + 1; - let a_nsec = m_nsec + 1; - - let timestamps = Timestamps { - last_modification: Timespec { - tv_sec: m_sec as _, - tv_nsec: m_nsec as _, - }, - last_access: Timespec { - tv_sec: a_sec as _, - tv_nsec: a_nsec as _, - }, - }; - let file = openat(&dir, "foo", OFlags::CREATE | OFlags::WRONLY, Mode::RUSR).unwrap(); - - match futimens(&file, ×tamps) { - Ok(()) => (), - - // On 32-bit platforms, accept `EOVERFLOW`, meaning that y2038 support - // is not available in this version of the OS. - #[cfg(target_pointer_width = "32")] - Err(rustix::io::Errno::OVERFLOW) => return, - - Err(e) => panic!("unexpected error: {:?}", e), - } - - // Use `statat` to read back the timestamp. - let stat = statat(&dir, "foo", AtFlags::empty()).unwrap(); - - assert_eq!(TryInto::::try_into(stat.st_mtime).unwrap(), m_sec); - assert_eq!(stat.st_mtime_nsec as u32, m_nsec); - assert!(TryInto::::try_into(stat.st_atime).unwrap() >= a_sec); - assert!( - TryInto::::try_into(stat.st_atime).unwrap() > a_sec - || stat.st_atime_nsec as u32 >= a_nsec - ); - - // Now test the same thing, but with `fstat`. - let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap(); - let stat = fstat(&file).unwrap(); - - assert_eq!( - TryInto::::try_into(stat.st_mtime).unwrap() as u64, - m_sec - ); - assert_eq!(stat.st_mtime_nsec as u32, m_nsec); - assert!(TryInto::::try_into(stat.st_atime).unwrap() as u64 >= a_sec); - assert!( - TryInto::::try_into(stat.st_atime).unwrap() as u64 > a_sec - || stat.st_atime_nsec as u32 >= a_nsec - ); -} diff --git a/vendor/rustix/tests/io/dup2_to_replace_stdio.rs b/vendor/rustix/tests/io/dup2_to_replace_stdio.rs deleted file mode 100644 index b07ec17f0..000000000 --- a/vendor/rustix/tests/io/dup2_to_replace_stdio.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![cfg(not(target_os = "wasi"))] - -use std::env; -use std::process::Command; - -/// Use `dup2` to replace the stdin and stdout file descriptors. -#[test] -fn dup2_to_replace_stdio() { - // This test modifies the stdio file descriptors, so we run it in a - // separate process so that it doesn't interfere with the test harness. - assert!(Command::new(env::var("CARGO").unwrap()) - .arg("run") - .arg("--example") - .arg("dup2_to_replace_stdio") - .status() - .unwrap() - .success()); -} diff --git a/vendor/rustix/tests/io/epoll.rs b/vendor/rustix/tests/io/epoll.rs deleted file mode 100644 index 4cfe305fe..000000000 --- a/vendor/rustix/tests/io/epoll.rs +++ /dev/null @@ -1,103 +0,0 @@ -#![cfg(any(target_os = "android", target_os = "linux"))] - -use rustix::fd::AsFd; -use rustix::io::epoll::{self, Epoll}; -use rustix::io::{ioctl_fionbio, read, write, OwnedFd}; -use rustix::net::{ - accept, bind_v4, connect_v4, getsockname, listen, socket, AddressFamily, Ipv4Addr, Protocol, - SocketAddrAny, SocketAddrV4, SocketType, -}; -use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; -use std::sync::{Arc, Condvar, Mutex}; -use std::thread; - -const BUFFER_SIZE: usize = 20; - -fn server(ready: Arc<(Mutex, Condvar)>) { - let listen_sock = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap(); - bind_v4(&listen_sock, &SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0)).unwrap(); - listen(&listen_sock, 1).unwrap(); - - let who = match getsockname(&listen_sock).unwrap() { - SocketAddrAny::V4(addr) => addr, - _ => panic!(), - }; - - { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - *port = who.port(); - cvar.notify_all(); - } - - let epoll = Epoll::new(epoll::CreateFlags::CLOEXEC, epoll::Owning::::new()).unwrap(); - - // Test into conversions. - let fd: OwnedFd = epoll.into(); - let epoll: Epoll> = fd.into(); - let fd: RawFd = epoll.into_raw_fd(); - let epoll = unsafe { Epoll::>::from_raw_fd(fd) }; - - let raw_listen_sock = listen_sock.as_fd().as_raw_fd(); - epoll.add(listen_sock, epoll::EventFlags::IN).unwrap(); - - let mut event_list = epoll::EventVec::with_capacity(4); - loop { - epoll.wait(&mut event_list, -1).unwrap(); - for (_event_flags, target) in &event_list { - if target.as_raw_fd() == raw_listen_sock { - let conn_sock = accept(&*target).unwrap(); - ioctl_fionbio(&conn_sock, true).unwrap(); - epoll - .add(conn_sock, epoll::EventFlags::OUT | epoll::EventFlags::ET) - .unwrap(); - } else { - write(&*target, b"hello\n").unwrap(); - let _ = epoll.del(target).unwrap(); - } - } - } -} - -fn client(ready: Arc<(Mutex, Condvar)>) { - let port = { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - while *port == 0 { - port = cvar.wait(port).unwrap(); - } - *port - }; - - let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, port); - let mut buffer = vec![0; BUFFER_SIZE]; - - for _ in 0..16 { - let data_socket = - socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap(); - connect_v4(&data_socket, &addr).unwrap(); - - let nread = read(&data_socket, &mut buffer).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello\n"); - } -} - -#[test] -fn test_epoll() { - let ready = Arc::new((Mutex::new(0_u16), Condvar::new())); - let ready_clone = Arc::clone(&ready); - - let _server = thread::Builder::new() - .name("server".to_string()) - .spawn(move || { - server(ready); - }) - .unwrap(); - let client = thread::Builder::new() - .name("client".to_string()) - .spawn(move || { - client(ready_clone); - }) - .unwrap(); - client.join().unwrap(); -} diff --git a/vendor/rustix/tests/io/error.rs b/vendor/rustix/tests/io/error.rs deleted file mode 100644 index 128d3b59a..000000000 --- a/vendor/rustix/tests/io/error.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[test] -fn test_error() { - assert_eq!( - rustix::io::Errno::INVAL, - rustix::io::Errno::from_raw_os_error(rustix::io::Errno::INVAL.raw_os_error()) - ); - #[cfg(not(windows))] - assert_eq!(rustix::io::Errno::INVAL.raw_os_error(), libc::EINVAL); - #[cfg(windows)] - assert_eq!( - rustix::io::Errno::INVAL.raw_os_error(), - windows_sys::Win32::Networking::WinSock::WSAEINVAL - ); -} diff --git a/vendor/rustix/tests/io/eventfd.rs b/vendor/rustix/tests/io/eventfd.rs deleted file mode 100644 index 11bc8ae55..000000000 --- a/vendor/rustix/tests/io/eventfd.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_eventfd() { - use rustix::io::{eventfd, read, write, EventfdFlags}; - use std::mem::size_of; - use std::thread; - - let efd = eventfd(0, EventfdFlags::CLOEXEC).unwrap(); - - let child = thread::spawn(move || { - for u in [1_u64, 3, 6, 11, 5000].iter() { - assert_eq!(write(&efd, &u.to_ne_bytes()).unwrap(), size_of::()); - } - efd - }); - - let efd = child.join().unwrap(); - - let mut bytes = [0_u8; size_of::()]; - let s = read(&efd, &mut bytes).unwrap(); - assert_eq!(s, bytes.len()); - let u = u64::from_ne_bytes(bytes); - assert_eq!(u, 5021); -} diff --git a/vendor/rustix/tests/io/from_into.rs b/vendor/rustix/tests/io/from_into.rs deleted file mode 100644 index 94d915993..000000000 --- a/vendor/rustix/tests/io/from_into.rs +++ /dev/null @@ -1,28 +0,0 @@ -#[cfg(feature = "fs")] -#[cfg(not(target_os = "redox"))] -#[test] -fn test_owned() { - use rustix::fd::AsFd; - #[cfg(unix)] - use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; - #[cfg(target_os = "wasi")] - use std::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd}; - - let file = rustix::fs::openat( - rustix::fs::cwd(), - "Cargo.toml", - rustix::fs::OFlags::RDONLY, - rustix::fs::Mode::empty(), - ) - .unwrap(); - - let raw = file.as_raw_fd(); - assert_eq!(raw, file.as_fd().as_raw_fd()); - - let inner = file.into_raw_fd(); - assert_eq!(raw, inner); - - let new = unsafe { rustix::io::OwnedFd::from_raw_fd(inner) }; - let mut buf = [0_u8; 4]; - let _ = rustix::io::read(&new, &mut buf).unwrap(); -} diff --git a/vendor/rustix/tests/io/ioctl.rs b/vendor/rustix/tests/io/ioctl.rs deleted file mode 100644 index e260e4884..000000000 --- a/vendor/rustix/tests/io/ioctl.rs +++ /dev/null @@ -1,14 +0,0 @@ -// `is_read_write` is not yet implemented on Windows. And `ioctl_fionread` -// on Windows doesn't work on files. -#[cfg(not(windows))] -#[test] -fn test_ioctls() { - let file = std::fs::File::open("Cargo.toml").unwrap(); - - assert_eq!(rustix::io::is_read_write(&file).unwrap(), (true, false)); - - assert_eq!( - rustix::io::ioctl_fionread(&file).unwrap(), - file.metadata().unwrap().len() - ); -} diff --git a/vendor/rustix/tests/io/main.rs b/vendor/rustix/tests/io/main.rs deleted file mode 100644 index bdd044809..000000000 --- a/vendor/rustix/tests/io/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! Tests for [`rustix::io`]. - -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - -#[cfg(not(feature = "rustc-dep-of-std"))] -#[cfg(not(windows))] -#[cfg(not(target_os = "wasi"))] -mod dup2_to_replace_stdio; -#[cfg(not(feature = "rustc-dep-of-std"))] // TODO -#[cfg(not(windows))] -#[cfg(feature = "net")] -#[cfg(not(target_os = "wasi"))] -mod epoll; -mod error; -#[cfg(not(windows))] -#[cfg(not(target_os = "wasi"))] -mod eventfd; -#[cfg(not(windows))] -mod from_into; -#[cfg(not(target_os = "redox"))] -mod ioctl; -mod poll; -#[cfg(all(feature = "procfs", any(target_os = "android", target_os = "linux")))] -mod procfs; -#[cfg(not(windows))] -#[cfg(not(target_os = "redox"))] // redox doesn't have cwd/openat -#[cfg(not(target_os = "wasi"))] // wasi support for S_IRUSR etc. submitted to libc in #2264 -mod read_write; -#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "android"))] -mod seals; diff --git a/vendor/rustix/tests/io/poll.rs b/vendor/rustix/tests/io/poll.rs deleted file mode 100644 index ff2da695b..000000000 --- a/vendor/rustix/tests/io/poll.rs +++ /dev/null @@ -1,63 +0,0 @@ -use rustix::fd::{AsFd, AsRawFd, FromRawFd, IntoRawFd, OwnedFd}; -#[cfg(not(windows))] -use rustix::io::{poll, retry_on_intr}; -use rustix::io::{PollFd, PollFlags}; - -#[cfg(not(windows))] -#[test] -fn test_poll() { - use rustix::io::{pipe, read, write}; - - // Create a pipe. - let (reader, writer) = pipe().unwrap(); - let mut poll_fds = [PollFd::new(&reader, PollFlags::IN)]; - assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd()); - - // `poll` should say there's nothing ready to be read from the pipe. - let num = retry_on_intr(|| poll(&mut poll_fds, 0)).unwrap(); - assert_eq!(num, 0); - assert!(poll_fds[0].revents().is_empty()); - assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd()); - - // Write a byte to the pipe. - assert_eq!(retry_on_intr(|| write(&writer, b"a")).unwrap(), 1); - - // `poll` should now say there's data to be read. - let num = retry_on_intr(|| poll(&mut poll_fds, -1)).unwrap(); - assert_eq!(num, 1); - assert_eq!(poll_fds[0].revents(), PollFlags::IN); - assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd()); - - let mut temp = poll_fds[0].clone(); - assert_eq!(temp.revents(), PollFlags::IN); - temp.clear_revents(); - assert!(temp.revents().is_empty()); - - // Read the byte from the pipe. - let mut buf = [b'\0']; - assert_eq!(retry_on_intr(|| read(&reader, &mut buf)).unwrap(), 1); - assert_eq!(buf[0], b'a'); - assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd()); - - // Poll should now say there's no more data to be read. - let num = retry_on_intr(|| poll(&mut poll_fds, 0)).unwrap(); - assert_eq!(num, 0); - assert!(poll_fds[0].revents().is_empty()); - assert_eq!(poll_fds[0].as_fd().as_raw_fd(), reader.as_fd().as_raw_fd()); -} - -#[test] -fn test_poll_fd_set_fd() { - // Make up some file descriptors so that we can test that set_fd works. - let a = unsafe { OwnedFd::from_raw_fd(777) }; - let mut poll_fd = PollFd::new(&a, PollFlags::empty()); - assert_eq!(poll_fd.as_fd().as_raw_fd(), 777); - - let b = unsafe { OwnedFd::from_raw_fd(888) }; - poll_fd.set_fd(&b); - assert_eq!(poll_fd.as_fd().as_raw_fd(), 888); - - // Don't attempt to close our made-up file descriptors. - let _ = a.into_raw_fd(); - let _ = b.into_raw_fd(); -} diff --git a/vendor/rustix/tests/io/procfs.rs b/vendor/rustix/tests/io/procfs.rs deleted file mode 100644 index 4c4256bd7..000000000 --- a/vendor/rustix/tests/io/procfs.rs +++ /dev/null @@ -1,8 +0,0 @@ -use io_lifetimes::raw::AsRawFilelike; - -#[test] -fn test_proc_self() { - // Verify that this API works at all - let fd = rustix::io::proc_self_fd().unwrap(); - assert_ne!(fd.as_raw_filelike(), 0); -} diff --git a/vendor/rustix/tests/io/read_write.rs b/vendor/rustix/tests/io/read_write.rs deleted file mode 100644 index 65186bf21..000000000 --- a/vendor/rustix/tests/io/read_write.rs +++ /dev/null @@ -1,118 +0,0 @@ -#[cfg(feature = "fs")] -use std::io::{IoSlice, IoSliceMut}; - -#[cfg(feature = "fs")] -#[test] -fn test_readwrite_pv() { - use rustix::fs::{cwd, openat, Mode, OFlags}; - use rustix::io::{preadv, pwritev}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let foo = openat( - &dir, - "foo", - OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - // For most targets, just call `pwritev`. - #[cfg(not(any(target_os = "ios", target_os = "macos")))] - { - pwritev(&foo, &[IoSlice::new(b"hello")], 200).unwrap(); - } - // macOS only has pwritev in newer versions; allow it to fail with `ENOSYS`. - #[cfg(any(target_os = "ios", target_os = "macos"))] - { - match pwritev(&foo, &[IoSlice::new(b"hello")], 200) { - Ok(_) => (), - Err(rustix::io::Errno::NOSYS) => return, - Err(err) => Err(err).unwrap(), - } - } - pwritev(&foo, &[IoSlice::new(b"world")], 300).unwrap(); - let mut buf = [0_u8; 5]; - preadv(&foo, &mut [IoSliceMut::new(&mut buf)], 200).unwrap(); - assert_eq!(&buf, b"hello"); - preadv(&foo, &mut [IoSliceMut::new(&mut buf)], 300).unwrap(); - assert_eq!(&buf, b"world"); -} - -#[cfg(feature = "fs")] -#[test] -fn test_readwrite_p() { - use rustix::fs::{cwd, openat, Mode, OFlags}; - use rustix::io::{pread, pwrite}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let foo = openat( - &dir, - "foo", - OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - pwrite(&foo, b"hello", 200).unwrap(); - pwrite(&foo, b"world", 300).unwrap(); - let mut buf = [0_u8; 5]; - pread(&foo, &mut buf, 200).unwrap(); - assert_eq!(&buf, b"hello"); - pread(&foo, &mut buf, 300).unwrap(); - assert_eq!(&buf, b"world"); -} - -#[cfg(feature = "fs")] -#[test] -fn test_readwrite_v() { - use rustix::fs::{cwd, openat, seek, Mode, OFlags}; - use rustix::io::{readv, writev, SeekFrom}; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let foo = openat( - &dir, - "foo", - OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - writev(&foo, &[IoSlice::new(b"hello")]).unwrap(); - writev(&foo, &[IoSlice::new(b"world")]).unwrap(); - seek(&foo, SeekFrom::Start(0)).unwrap(); - let mut buf = [0_u8; 5]; - readv(&foo, &mut [IoSliceMut::new(&mut buf)]).unwrap(); - assert_eq!(&buf, b"hello"); - readv(&foo, &mut [IoSliceMut::new(&mut buf)]).unwrap(); - assert_eq!(&buf, b"world"); -} - -#[cfg(feature = "fs")] -#[test] -fn test_readwrite() { - use rustix::fs::{cwd, openat, seek, Mode, OFlags}; - use rustix::io::{read, write}; - use std::io::SeekFrom; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - let foo = openat( - &dir, - "foo", - OFlags::RDWR | OFlags::CREATE | OFlags::TRUNC, - Mode::RUSR | Mode::WUSR, - ) - .unwrap(); - - write(&foo, b"hello").unwrap(); - write(&foo, b"world").unwrap(); - seek(&foo, SeekFrom::Start(0)).unwrap(); - let mut buf = [0_u8; 5]; - read(&foo, &mut buf).unwrap(); - assert_eq!(&buf, b"hello"); - read(&foo, &mut buf).unwrap(); - assert_eq!(&buf, b"world"); -} diff --git a/vendor/rustix/tests/io/seals.rs b/vendor/rustix/tests/io/seals.rs deleted file mode 100644 index ff971fa75..000000000 --- a/vendor/rustix/tests/io/seals.rs +++ /dev/null @@ -1,41 +0,0 @@ -#[cfg(feature = "fs")] -#[test] -fn test_seals() { - use rustix::fd::FromFd; - use rustix::fs::{ - fcntl_add_seals, fcntl_get_seals, ftruncate, memfd_create, MemfdFlags, SealFlags, - }; - use std::fs::File; - use std::io::Write; - - let fd = match memfd_create("test", MemfdFlags::CLOEXEC | MemfdFlags::ALLOW_SEALING) { - Ok(fd) => fd, - Err(rustix::io::Errno::NOSYS) => return, - Err(err) => Err(err).unwrap(), - }; - let mut file = File::from_fd(fd.into()); - - let old = fcntl_get_seals(&file).unwrap(); - assert_eq!(old, SealFlags::empty()); - - writeln!(&mut file, "Hello!").unwrap(); - - fcntl_add_seals(&file, SealFlags::GROW).unwrap(); - - let now = fcntl_get_seals(&file).unwrap(); - assert_eq!(now, SealFlags::GROW); - - // We sealed growing, so this should fail. - writeln!(&mut file, "World?").unwrap_err(); - - // We can still shrink for now. - ftruncate(&mut file, 1).unwrap(); - - fcntl_add_seals(&file, SealFlags::SHRINK).unwrap(); - - let now = fcntl_get_seals(&file).unwrap(); - assert_eq!(now, SealFlags::GROW | SealFlags::SHRINK); - - // We sealed shrinking, so this should fail. - ftruncate(&mut file, 0).unwrap_err(); -} diff --git a/vendor/rustix/tests/mm/main.rs b/vendor/rustix/tests/mm/main.rs deleted file mode 100644 index ee746d900..000000000 --- a/vendor/rustix/tests/mm/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Tests for [`rustix::mm`]. - -#![cfg(feature = "mm")] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - -#[cfg(not(windows))] -#[cfg(not(target_os = "wasi"))] -mod mlock; -#[cfg(not(windows))] -mod mmap; -#[cfg(not(windows))] -mod prot; diff --git a/vendor/rustix/tests/mm/mlock.rs b/vendor/rustix/tests/mm/mlock.rs deleted file mode 100644 index c4a1a83b5..000000000 --- a/vendor/rustix/tests/mm/mlock.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Tests for `mlock`. -//! -//! We can't easily test that it actually locks memory, but we can test that we -//! can call it and either get success or a reasonable error message. - -use std::ffi::c_void; - -#[test] -fn test_mlock() { - let mut buf = vec![0_u8; 4096]; - - unsafe { - match rustix::mm::mlock(buf.as_mut_ptr().cast::(), buf.len()) { - Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::(), buf.len()).unwrap(), - // Tests won't always have enough memory or permissions, and that's ok. - Err(rustix::io::Errno::PERM) | Err(rustix::io::Errno::NOMEM) => {} - // But they shouldn't fail otherwise. - Err(other) => Err(other).unwrap(), - } - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_mlock_with() { - let mut buf = vec![0_u8; 4096]; - - unsafe { - match rustix::mm::mlock_with( - buf.as_mut_ptr().cast::(), - buf.len(), - rustix::mm::MlockFlags::empty(), - ) { - Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::(), buf.len()).unwrap(), - // Tests won't always have enough memory or permissions, and that's ok. - Err(rustix::io::Errno::PERM) - | Err(rustix::io::Errno::NOMEM) - | Err(rustix::io::Errno::NOSYS) => {} - // But they shouldn't fail otherwise. - Err(other) => Err(other).unwrap(), - } - } -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_mlock_with_onfault() { - // With glibc, `mlock2` with `MLOCK_ONFAULT` returns `EINVAL` if the - // `mlock2` system call returns `ENOSYS`. That's not what we want - // here though, because `ENOSYS` just means the OS doesn't have - // `mlock2`, while `EINVAL` may indicate a bug in rustix. - // - // To work around this, we use `libc::syscall` to make a `mlock2` - // syscall directly to test for `ENOSYS`, before running the main - // test below. - unsafe { - if libc::syscall(libc::SYS_mlock2, 0, 0) == -1 && libc_errno::errno().0 == libc::ENOSYS { - return; - } - } - - let mut buf = vec![0_u8; 4096]; - - unsafe { - match rustix::mm::mlock_with( - buf.as_mut_ptr().cast::(), - buf.len(), - rustix::mm::MlockFlags::ONFAULT, - ) { - Ok(()) => rustix::mm::munlock(buf.as_mut_ptr().cast::(), buf.len()).unwrap(), - // Tests won't always have enough memory or permissions, and that's ok. - Err(rustix::io::Errno::PERM) - | Err(rustix::io::Errno::NOMEM) - | Err(rustix::io::Errno::NOSYS) => {} - // But they shouldn't fail otherwise. - Err(other) => Err(other).unwrap(), - } - } -} diff --git a/vendor/rustix/tests/mm/mmap.rs b/vendor/rustix/tests/mm/mmap.rs deleted file mode 100644 index 6b27287d7..000000000 --- a/vendor/rustix/tests/mm/mmap.rs +++ /dev/null @@ -1,163 +0,0 @@ -#![cfg(not(target_os = "wasi"))] - -#[cfg(feature = "fs")] -#[cfg(not(target_os = "redox"))] -#[test] -fn test_mmap() { - use rustix::fs::{cwd, openat, Mode, OFlags}; - use rustix::io::write; - use rustix::mm::{mmap, munmap, MapFlags, ProtFlags}; - use std::ptr::null_mut; - use std::slice; - - let tmp = tempfile::tempdir().unwrap(); - let dir = openat(cwd(), tmp.path(), OFlags::RDONLY, Mode::empty()).unwrap(); - - let file = openat( - &dir, - "foo", - OFlags::CREATE | OFlags::WRONLY | OFlags::TRUNC, - Mode::RUSR, - ) - .unwrap(); - write(&file, &[b'a'; 8192]).unwrap(); - drop(file); - - let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap(); - unsafe { - let addr = mmap( - null_mut(), - 8192, - ProtFlags::READ, - MapFlags::PRIVATE, - &file, - 0, - ) - .unwrap(); - let slice = slice::from_raw_parts(addr.cast::(), 8192); - assert_eq!(slice, &[b'a'; 8192]); - - munmap(addr, 8192).unwrap(); - } - - let file = openat(&dir, "foo", OFlags::RDONLY, Mode::empty()).unwrap(); - unsafe { - assert_eq!( - mmap( - null_mut(), - 8192, - ProtFlags::READ, - MapFlags::PRIVATE, - &file, - u64::MAX, - ) - .unwrap_err() - .raw_os_error(), - libc::EINVAL - ); - } -} - -#[test] -fn test_mmap_anonymous() { - use rustix::mm::{mmap_anonymous, munmap, MapFlags, ProtFlags}; - use std::ptr::null_mut; - use std::slice; - - unsafe { - let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap(); - let slice = slice::from_raw_parts(addr.cast::(), 8192); - assert_eq!(slice, &[b'\0'; 8192]); - - munmap(addr, 8192).unwrap(); - } -} - -#[test] -fn test_mprotect() { - use rustix::mm::{mmap_anonymous, mprotect, munmap, MapFlags, MprotectFlags, ProtFlags}; - use std::ptr::null_mut; - use std::slice; - - unsafe { - let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap(); - - mprotect(addr, 8192, MprotectFlags::empty()).unwrap(); - mprotect(addr, 8192, MprotectFlags::READ).unwrap(); - - let slice = slice::from_raw_parts(addr.cast::(), 8192); - assert_eq!(slice, &[b'\0'; 8192]); - - munmap(addr, 8192).unwrap(); - } -} - -#[test] -fn test_mlock() { - use rustix::mm::{mlock, mmap_anonymous, munlock, munmap, MapFlags, ProtFlags}; - #[cfg(any(target_os = "android", target_os = "linux"))] - use rustix::mm::{mlock_with, MlockFlags}; - use std::ptr::null_mut; - - unsafe { - let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap(); - - mlock(addr, 8192).unwrap(); - munlock(addr, 8192).unwrap(); - - #[cfg(any(target_os = "android", target_os = "linux"))] - { - match mlock_with(addr, 8192, MlockFlags::empty()) { - Err(rustix::io::Errno::NOSYS) => (), - Err(err) => Err(err).unwrap(), - Ok(()) => munlock(addr, 8192).unwrap(), - } - - #[cfg(linux_raw)] // libc doesn't expose `MLOCK_UNFAULT` yet. - { - match mlock_with(addr, 8192, MlockFlags::ONFAULT) { - Err(rustix::io::Errno::NOSYS) => (), - Err(err) => Err(err).unwrap(), - Ok(()) => munlock(addr, 8192).unwrap(), - } - munlock(addr, 8192).unwrap(); - } - } - - munmap(addr, 8192).unwrap(); - } -} - -#[cfg(not(target_os = "redox"))] -#[test] -fn test_madvise() { - use rustix::mm::{madvise, mmap_anonymous, munmap, Advice, MapFlags, ProtFlags}; - use std::ptr::null_mut; - - unsafe { - let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap(); - - madvise(addr, 8192, Advice::Normal).unwrap(); - madvise(addr, 8192, Advice::DontNeed).unwrap(); - - #[cfg(any(target_os = "android", target_os = "linux"))] - madvise(addr, 8192, Advice::LinuxDontNeed).unwrap(); - - munmap(addr, 8192).unwrap(); - } -} - -#[test] -fn test_msync() { - use rustix::mm::{mmap_anonymous, msync, munmap, MapFlags, MsyncFlags, ProtFlags}; - use std::ptr::null_mut; - - unsafe { - let addr = mmap_anonymous(null_mut(), 8192, ProtFlags::READ, MapFlags::PRIVATE).unwrap(); - - msync(addr, 8192, MsyncFlags::SYNC).unwrap(); - msync(addr, 8192, MsyncFlags::ASYNC).unwrap(); - - munmap(addr, 8192).unwrap(); - } -} diff --git a/vendor/rustix/tests/mm/prot.rs b/vendor/rustix/tests/mm/prot.rs deleted file mode 100644 index 6c86a8f2a..000000000 --- a/vendor/rustix/tests/mm/prot.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[test] -fn test_prot_flags() { - assert_eq!(libc::PROT_NONE, 0); -} diff --git a/vendor/rustix/tests/net/addr.rs b/vendor/rustix/tests/net/addr.rs deleted file mode 100644 index 124413132..000000000 --- a/vendor/rustix/tests/net/addr.rs +++ /dev/null @@ -1,92 +0,0 @@ -#[test] -fn encode_decode() { - #[cfg(unix)] - use rustix::net::SocketAddrUnix; - use rustix::net::{ - Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrStorage, SocketAddrV4, SocketAddrV6, - }; - - unsafe { - let orig = SocketAddrV4::new(Ipv4Addr::new(2, 3, 5, 6), 33); - let mut encoded = std::mem::MaybeUninit::::uninit(); - let len = SocketAddrAny::V4(orig).write(encoded.as_mut_ptr()); - let decoded = SocketAddrAny::read(encoded.as_ptr(), len).unwrap(); - assert_eq!(decoded, SocketAddrAny::V4(orig)); - - let orig = SocketAddrV6::new(Ipv6Addr::new(2, 3, 5, 6, 8, 9, 11, 12), 33, 34, 36); - let mut encoded = std::mem::MaybeUninit::::uninit(); - let len = SocketAddrAny::V6(orig).write(encoded.as_mut_ptr()); - let decoded = SocketAddrAny::read(encoded.as_ptr(), len).unwrap(); - assert_eq!(decoded, SocketAddrAny::V6(orig)); - - #[cfg(not(windows))] - { - let orig = SocketAddrUnix::new("/path/to/socket").unwrap(); - let mut encoded = std::mem::MaybeUninit::::uninit(); - let len = SocketAddrAny::Unix(orig.clone()).write(encoded.as_mut_ptr()); - let decoded = SocketAddrAny::read(encoded.as_ptr(), len).unwrap(); - assert_eq!(decoded, SocketAddrAny::Unix(orig)); - } - } -} - -#[cfg(not(windows))] -#[test] -fn test_unix_addr() { - use rustix::cstr; - use rustix::net::SocketAddrUnix; - - assert_eq!( - SocketAddrUnix::new("/").unwrap().path().unwrap(), - cstr!("/") - ); - assert_eq!( - SocketAddrUnix::new("//").unwrap().path().unwrap(), - cstr!("//") - ); - assert_eq!( - SocketAddrUnix::new("/foo/bar").unwrap().path().unwrap(), - cstr!("/foo/bar") - ); - assert_eq!( - SocketAddrUnix::new("foo").unwrap().path().unwrap(), - cstr!("foo") - ); - SocketAddrUnix::new("/foo\0/bar").unwrap_err(); - assert!(SocketAddrUnix::new("").unwrap().path().is_none()); - - #[cfg(any(target_os = "android", target_os = "linux"))] - { - assert!(SocketAddrUnix::new("foo") - .unwrap() - .abstract_name() - .is_none()); - - assert_eq!( - SocketAddrUnix::new_abstract_name(b"test") - .unwrap() - .abstract_name() - .unwrap(), - b"test" - ); - assert_eq!( - SocketAddrUnix::new_abstract_name(b"") - .unwrap() - .abstract_name() - .unwrap(), - b"" - ); - assert_eq!( - SocketAddrUnix::new_abstract_name(b"this\0that") - .unwrap() - .abstract_name() - .unwrap(), - b"this\0that" - ); - SocketAddrUnix::new_abstract_name(&[b'a'; 500]).unwrap_err(); - assert!(SocketAddrUnix::new_abstract_name(b"test") - .unwrap() - .path() - .is_none()); - } -} diff --git a/vendor/rustix/tests/net/connect_bind_send.rs b/vendor/rustix/tests/net/connect_bind_send.rs deleted file mode 100644 index 84720975f..000000000 --- a/vendor/rustix/tests/net/connect_bind_send.rs +++ /dev/null @@ -1,487 +0,0 @@ -use rustix::net::{ - AddressFamily, Ipv6Addr, Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4, - SocketAddrV6, SocketType, -}; -use std::net::{IpAddr, Ipv4Addr, SocketAddr}; - -/// Test `connect_any`. -#[test] -fn net_v4_connect_any() -> std::io::Result<()> { - let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Similar, but with V6. -#[test] -fn net_v6_connect_any() -> std::io::Result<()> { - let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Test `connect` with a `SocketAddr`. -#[test] -fn net_v4_connect() -> std::io::Result<()> { - let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let local_addr = match local_addr { - SocketAddrAny::V4(v4) => SocketAddr::V4(v4), - other => panic!("unexpected socket address {:?}", other), - }; - let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::connect(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Similar, but use V6. -#[test] -fn net_v6_connect() -> std::io::Result<()> { - let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let local_addr = match local_addr { - SocketAddrAny::V6(v6) => SocketAddr::V6(v6), - other => panic!("unexpected socket address {:?}", other), - }; - let sender = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::connect(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Test `bind_any`. -#[test] -fn net_v4_bind_any() -> std::io::Result<()> { - let localhost = Ipv4Addr::LOCALHOST; - let addr = SocketAddrAny::V4(SocketAddrV4::new(localhost, 0)); - let listener = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::bind_any(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Similar, but use V6. -#[test] -fn net_v6_bind_any() -> std::io::Result<()> { - let localhost = Ipv6Addr::LOCALHOST; - let addr = SocketAddrAny::V6(SocketAddrV6::new(localhost, 0, 0, 0)); - let listener = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::bind_any(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Test `sendto`. -#[test] -fn net_v4_sendto() -> std::io::Result<()> { - let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let local_addr = match local_addr { - SocketAddrAny::V4(v4) => SocketAddr::V4(v4), - other => panic!("unexpected socket address {:?}", other), - }; - let n = rustix::net::sendto(&sender, request, SendFlags::empty(), &local_addr).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let (n, from) = - rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - assert!(from.is_none()); - - Ok(()) -} - -/// Similar, but with V6. -#[test] -fn net_v6_sendto() -> std::io::Result<()> { - let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let local_addr = match local_addr { - SocketAddrAny::V6(v6) => SocketAddr::V6(v6), - other => panic!("unexpected socket address {:?}", other), - }; - let n = rustix::net::sendto(&sender, request, SendFlags::empty(), &local_addr).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let (n, from) = - rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - assert!(from.is_none()); - - Ok(()) -} - -/// Test `sendto_any`. -#[test] -fn net_v4_sendto_any() -> std::io::Result<()> { - let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = - rustix::net::sendto_any(&sender, request, SendFlags::empty(), &local_addr).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let (n, from) = - rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - assert!(from.is_none()); - - Ok(()) -} - -/// Test `sendto_any`. -#[test] -fn net_v6_sendto_any() -> std::io::Result<()> { - let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = - rustix::net::sendto_any(&sender, request, SendFlags::empty(), &local_addr).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let accepted = rustix::net::accept(&listener).expect("accept"); - let mut response = [0_u8; 128]; - let (n, from) = - rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - assert!(from.is_none()); - - Ok(()) -} - -/// Test `acceptfrom`. -#[test] -fn net_v4_acceptfrom() -> std::io::Result<()> { - let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let (accepted, from) = rustix::net::acceptfrom(&listener).expect("accept"); - - assert_ne!(from.clone().unwrap(), local_addr); - - let from = match from.unwrap() { - SocketAddrAny::V4(v4) => v4, - other => panic!("unexpected socket address {:?}", other), - }; - let local_addr = match local_addr { - SocketAddrAny::V4(v4) => v4, - other => panic!("unexpected socket address {:?}", other), - }; - - assert_eq!(from.clone().ip(), local_addr.ip()); - assert_ne!(from.clone().port(), local_addr.port()); - - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} - -/// Similar, but with V6. -#[test] -fn net_v6_acceptfrom() -> std::io::Result<()> { - let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST); - let addr = SocketAddr::new(localhost, 0); - let listener = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::bind(&listener, &addr).expect("bind"); - rustix::net::listen(&listener, 1).expect("listen"); - - let local_addr = rustix::net::getsockname(&listener)?; - let sender = rustix::net::socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - )?; - rustix::net::connect_any(&sender, &local_addr).expect("connect"); - let request = b"Hello, World!!!"; - let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send"); - drop(sender); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - let (accepted, from) = rustix::net::acceptfrom(&listener).expect("accept"); - - assert_ne!(from.clone().unwrap(), local_addr); - - let from = match from.unwrap() { - SocketAddrAny::V6(v6) => v6, - other => panic!("unexpected socket address {:?}", other), - }; - let local_addr = match local_addr { - SocketAddrAny::V6(v6) => v6, - other => panic!("unexpected socket address {:?}", other), - }; - - assert_eq!(from.clone().ip(), local_addr.ip()); - assert_ne!(from.clone().port(), local_addr.port()); - - let mut response = [0_u8; 128]; - let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv"); - - // Not strictly required, but it makes the test simpler. - assert_eq!(n, request.len()); - - assert_eq!(request, &response[..n]); - - Ok(()) -} diff --git a/vendor/rustix/tests/net/main.rs b/vendor/rustix/tests/net/main.rs deleted file mode 100644 index 0745282aa..000000000 --- a/vendor/rustix/tests/net/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Tests for [`rustix::net`]. - -#![cfg(feature = "net")] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg(not(any(target_os = "redox", target_os = "wasi")))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] -#![cfg_attr(core_c_str, feature(core_c_str))] - -mod addr; -mod connect_bind_send; -mod poll; -mod sockopt; -#[cfg(unix)] -mod unix; -mod v4; -mod v6; - -/// Windows requires us to call a setup function before using any of the -/// socket APIs. -#[cfg(windows)] -#[ctor::ctor] -fn windows_startup() { - let _ = rustix::net::wsa_startup().unwrap(); -} - -/// Windows requires us to call a cleanup function after using any of the -/// socket APIs. -#[cfg(windows)] -#[ctor::dtor] -fn windows_shutdown() { - rustix::net::wsa_cleanup().unwrap(); -} diff --git a/vendor/rustix/tests/net/poll.rs b/vendor/rustix/tests/net/poll.rs deleted file mode 100644 index 7933983f2..000000000 --- a/vendor/rustix/tests/net/poll.rs +++ /dev/null @@ -1,119 +0,0 @@ -//! The same as v6.rs, but with `poll` calls. - -#![cfg(not(any(target_os = "redox", target_os = "wasi")))] - -use rustix::io::{poll, PollFd, PollFlags}; -use rustix::net::{ - accept, bind_v6, connect_v6, getsockname, listen, recv, send, socket, AddressFamily, Ipv6Addr, - Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV6, SocketType, -}; -use std::sync::{Arc, Condvar, Mutex}; -use std::thread; - -const BUFFER_SIZE: usize = 20; - -fn server(ready: Arc<(Mutex, Condvar)>) { - let connection_socket = socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - ) - .unwrap(); - - let name = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 0, 0, 0); - bind_v6(&connection_socket, &name).unwrap(); - - let who = match getsockname(&connection_socket).unwrap() { - SocketAddrAny::V6(addr) => addr, - _ => panic!(), - }; - - listen(&connection_socket, 1).unwrap(); - - { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - *port = who.port(); - cvar.notify_all(); - } - - let mut buffer = vec![0; BUFFER_SIZE]; - let data_socket = accept(&connection_socket).unwrap(); - - let mut fds = [PollFd::new(&data_socket, PollFlags::IN)]; - assert_eq!(poll(&mut fds, -1).unwrap(), 1); - assert!(fds[0].revents().intersects(PollFlags::IN)); - assert!(!fds[0].revents().intersects(PollFlags::OUT)); - - let expected_nread = rustix::io::ioctl_fionread(&data_socket).unwrap(); - let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world"); - assert_eq!(expected_nread, nread as u64); - - let mut fds = [PollFd::new(&data_socket, PollFlags::OUT)]; - assert_eq!(poll(&mut fds, -1).unwrap(), 1); - assert!(!fds[0].revents().intersects(PollFlags::IN)); - assert!(fds[0].revents().intersects(PollFlags::OUT)); - - send(&data_socket, b"goodnight, moon", SendFlags::empty()).unwrap(); -} - -fn client(ready: Arc<(Mutex, Condvar)>) { - let port = { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - while *port == 0 { - port = cvar.wait(port).unwrap(); - } - *port - }; - - let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0); - let mut buffer = vec![0; BUFFER_SIZE]; - - let data_socket = socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - ) - .unwrap(); - connect_v6(&data_socket, &addr).unwrap(); - - let mut fds = [PollFd::new(&data_socket, PollFlags::OUT)]; - assert_eq!(poll(&mut fds, -1).unwrap(), 1); - assert!(!fds[0].revents().intersects(PollFlags::IN)); - assert!(fds[0].revents().intersects(PollFlags::OUT)); - - send(&data_socket, b"hello, world", SendFlags::empty()).unwrap(); - - let mut fds = [PollFd::new(&data_socket, PollFlags::IN)]; - assert_eq!(poll(&mut fds, -1).unwrap(), 1); - assert!(fds[0].revents().intersects(PollFlags::IN)); - assert!(!fds[0].revents().intersects(PollFlags::OUT)); - - let expected_nread = rustix::io::ioctl_fionread(&data_socket).unwrap(); - let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon"); - assert_eq!(expected_nread, nread as u64); -} - -#[test] -fn test_poll() { - let ready = Arc::new((Mutex::new(0_u16), Condvar::new())); - let ready_clone = Arc::clone(&ready); - - let server = thread::Builder::new() - .name("server".to_string()) - .spawn(move || { - server(ready); - }) - .unwrap(); - let client = thread::Builder::new() - .name("client".to_string()) - .spawn(move || { - client(ready_clone); - }) - .unwrap(); - client.join().unwrap(); - server.join().unwrap(); -} diff --git a/vendor/rustix/tests/net/sockopt.rs b/vendor/rustix/tests/net/sockopt.rs deleted file mode 100644 index 8e4cf52e8..000000000 --- a/vendor/rustix/tests/net/sockopt.rs +++ /dev/null @@ -1,158 +0,0 @@ -#[test] -fn test_sockopts() { - use rustix::net::{AddressFamily, Protocol, SocketType}; - use std::time::Duration; - - let s = - rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap(); - - // On a new socket we shouldn't have a timeout yet. - assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) - .unwrap() - .is_none() - ); - assert_eq!( - rustix::net::sockopt::get_socket_type(&s).unwrap(), - SocketType::STREAM - ); - #[cfg(not(windows))] - assert_eq!( - rustix::net::sockopt::get_socket_broadcast(&s).unwrap(), - false - ); - // On a new socket we shouldn't have a linger yet. - assert!(rustix::net::sockopt::get_socket_linger(&s) - .unwrap() - .is_none()); - #[cfg(any(target_os = "android", target_os = "linux"))] - assert_eq!( - rustix::net::sockopt::get_socket_passcred(&s).unwrap(), - false - ); - assert_ne!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 0); - assert_ne!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 77); - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - assert_eq!( - rustix::net::sockopt::get_ip_multicast_loop(&s).unwrap(), - true - ); - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - assert_eq!(rustix::net::sockopt::get_ip_multicast_ttl(&s).unwrap(), 1); - assert_eq!(rustix::net::sockopt::get_tcp_nodelay(&s).unwrap(), false); - - // Set a timeout. - rustix::net::sockopt::set_socket_timeout( - &s, - rustix::net::sockopt::Timeout::Recv, - Some(Duration::new(1, 1)), - ) - .unwrap(); - - // Check that we have a timeout of at least the time we set. - if cfg!(not(target_os = "freebsd")) { - assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) - .unwrap() - .unwrap() - >= Duration::new(1, 1) - ); - } else { - // On FreeBSD <= 12, it appears the system rounds the timeout down. - assert!( - rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv) - .unwrap() - .unwrap() - >= Duration::new(1, 0) - ); - } - - #[cfg(not(windows))] - { - // Set the broadcast flag; - rustix::net::sockopt::set_socket_broadcast(&s, true).unwrap(); - - // Check that the broadcast flag is set. This has no effect on stream - // sockets, and not all platforms even remember the value. - #[cfg(not(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - assert_eq!( - rustix::net::sockopt::get_socket_broadcast(&s).unwrap(), - true - ); - } - - // Set a linger. - rustix::net::sockopt::set_socket_linger(&s, Some(Duration::new(1, 1))).unwrap(); - - // Check that we have a linger of at least the time we set. - assert!( - dbg!(rustix::net::sockopt::get_socket_linger(&s) - .unwrap() - .unwrap()) - >= Duration::new(1, 1) - ); - - #[cfg(any(target_os = "android", target_os = "linux"))] - { - // Set the passcred flag; - rustix::net::sockopt::set_socket_passcred(&s, true).unwrap(); - - // Check that the passcred flag is set. - assert_eq!(rustix::net::sockopt::get_socket_passcred(&s).unwrap(), true); - } - - // Set the ip ttl. - rustix::net::sockopt::set_ip_ttl(&s, 77).unwrap(); - - // Check the ip ttl. - assert_eq!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 77); - - #[cfg(not(any( - windows, - target_os = "dragonfly", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - )))] - { - // Set the multicast loop flag; - rustix::net::sockopt::set_ip_multicast_loop(&s, false).unwrap(); - - // Check that the multicast loop flag is set. - assert_eq!( - rustix::net::sockopt::get_ip_multicast_loop(&s).unwrap(), - false - ); - } - - // Set the nodelay flag; - rustix::net::sockopt::set_tcp_nodelay(&s, true).unwrap(); - - // Check that the nodelay flag is set. - assert_eq!(rustix::net::sockopt::get_tcp_nodelay(&s).unwrap(), true); -} diff --git a/vendor/rustix/tests/net/unix.rs b/vendor/rustix/tests/net/unix.rs deleted file mode 100644 index 21a6542f8..000000000 --- a/vendor/rustix/tests/net/unix.rs +++ /dev/null @@ -1,147 +0,0 @@ -//! Test a simple Unix-domain socket server and client. -//! -//! The client sends lists of integers and the server sends back sums. - -// This test uses `AF_UNIX` with `SOCK_SEQPACKET` which is unsupported on macOS. -#![cfg(not(any( - target_os = "ios", - target_os = "macos", - target_os = "redox", - target_os = "wasi", -)))] -// This test uses `DecInt`. -#![cfg(feature = "itoa")] -#![cfg(feature = "fs")] - -use rustix::fs::{cwd, unlinkat, AtFlags}; -use rustix::io::{read, write}; -use rustix::net::{ - accept, bind_unix, connect_unix, listen, socket, AddressFamily, Protocol, SocketAddrUnix, - SocketType, -}; -use rustix::path::DecInt; -use std::path::Path; -use std::str::FromStr; -use std::sync::{Arc, Condvar, Mutex}; -use std::thread; - -const BUFFER_SIZE: usize = 20; - -fn server(ready: Arc<(Mutex, Condvar)>, path: &Path) { - let connection_socket = socket( - AddressFamily::UNIX, - SocketType::SEQPACKET, - Protocol::default(), - ) - .unwrap(); - - let name = SocketAddrUnix::new(path).unwrap(); - bind_unix(&connection_socket, &name).unwrap(); - listen(&connection_socket, 1).unwrap(); - - { - let (lock, cvar) = &*ready; - let mut started = lock.lock().unwrap(); - *started = true; - cvar.notify_all(); - } - - let mut buffer = vec![0; BUFFER_SIZE]; - 'exit: loop { - let data_socket = accept(&connection_socket).unwrap(); - let mut sum = 0; - loop { - let nread = read(&data_socket, &mut buffer).unwrap(); - - if &buffer[..nread] == b"exit" { - break 'exit; - } - if &buffer[..nread] == b"sum" { - break; - } - - sum += i32::from_str(&String::from_utf8_lossy(&buffer[..nread])).unwrap(); - } - - write(&data_socket, DecInt::new(sum).as_bytes()).unwrap(); - } - - unlinkat(cwd(), path, AtFlags::empty()).unwrap(); -} - -fn client(ready: Arc<(Mutex, Condvar)>, path: &Path, runs: &[(&[&str], i32)]) { - { - let (lock, cvar) = &*ready; - let mut started = lock.lock().unwrap(); - while !*started { - started = cvar.wait(started).unwrap(); - } - } - - let addr = SocketAddrUnix::new(path).unwrap(); - let mut buffer = vec![0; BUFFER_SIZE]; - - for (args, sum) in runs { - let data_socket = socket( - AddressFamily::UNIX, - SocketType::SEQPACKET, - Protocol::default(), - ) - .unwrap(); - connect_unix(&data_socket, &addr).unwrap(); - - for arg in *args { - write(&data_socket, arg.as_bytes()).unwrap(); - } - write(&data_socket, b"sum").unwrap(); - - let nread = read(&data_socket, &mut buffer).unwrap(); - assert_eq!( - i32::from_str(&String::from_utf8_lossy(&buffer[..nread])).unwrap(), - *sum - ); - } - - let data_socket = socket( - AddressFamily::UNIX, - SocketType::SEQPACKET, - Protocol::default(), - ) - .unwrap(); - connect_unix(&data_socket, &addr).unwrap(); - write(&data_socket, b"exit").unwrap(); -} - -#[test] -fn test_unix() { - let ready = Arc::new((Mutex::new(false), Condvar::new())); - let ready_clone = Arc::clone(&ready); - - let tmp = tempfile::tempdir().unwrap(); - let path = tmp.path().join("soccer"); - let send_path = path.to_owned(); - let server = thread::Builder::new() - .name("server".to_string()) - .spawn(move || { - server(ready, &send_path); - }) - .unwrap(); - let send_path = path.to_owned(); - let client = thread::Builder::new() - .name("client".to_string()) - .spawn(move || { - client( - ready_clone, - &send_path, - &[ - (&["1", "2"], 3), - (&["4", "77", "103"], 184), - (&["5", "78", "104"], 187), - (&[], 0), - ], - ); - }) - .unwrap(); - client.join().unwrap(); - server.join().unwrap(); -} diff --git a/vendor/rustix/tests/net/v4.rs b/vendor/rustix/tests/net/v4.rs deleted file mode 100644 index 0908057be..000000000 --- a/vendor/rustix/tests/net/v4.rs +++ /dev/null @@ -1,86 +0,0 @@ -//! Test a simple IPv4 socket server and client. -//! -//! The client send a message and the server sends one back. - -#![cfg(not(any(target_os = "redox", target_os = "wasi")))] - -use rustix::net::{ - accept, bind_v4, connect_v4, getsockname, listen, recv, send, socket, AddressFamily, Ipv4Addr, - Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4, SocketType, -}; -use std::sync::{Arc, Condvar, Mutex}; -use std::thread; - -const BUFFER_SIZE: usize = 20; - -fn server(ready: Arc<(Mutex, Condvar)>) { - let connection_socket = - socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap(); - - let name = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 0); - bind_v4(&connection_socket, &name).unwrap(); - - let who = match getsockname(&connection_socket).unwrap() { - SocketAddrAny::V4(addr) => addr, - _ => panic!(), - }; - - listen(&connection_socket, 1).unwrap(); - - { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - *port = who.port(); - cvar.notify_all(); - } - - let mut buffer = vec![0; BUFFER_SIZE]; - let data_socket = accept(&connection_socket).unwrap(); - let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world"); - - send(&data_socket, b"goodnight, moon", SendFlags::empty()).unwrap(); -} - -fn client(ready: Arc<(Mutex, Condvar)>) { - let port = { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - while *port == 0 { - port = cvar.wait(port).unwrap(); - } - *port - }; - - let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port); - let mut buffer = vec![0; BUFFER_SIZE]; - - let data_socket = socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap(); - connect_v4(&data_socket, &addr).unwrap(); - - send(&data_socket, b"hello, world", SendFlags::empty()).unwrap(); - - let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon"); -} - -#[test] -fn test_v4() { - let ready = Arc::new((Mutex::new(0_u16), Condvar::new())); - let ready_clone = Arc::clone(&ready); - - let server = thread::Builder::new() - .name("server".to_string()) - .spawn(move || { - server(ready); - }) - .unwrap(); - let client = thread::Builder::new() - .name("client".to_string()) - .spawn(move || { - client(ready_clone); - }) - .unwrap(); - client.join().unwrap(); - server.join().unwrap(); -} diff --git a/vendor/rustix/tests/net/v6.rs b/vendor/rustix/tests/net/v6.rs deleted file mode 100644 index 07205be89..000000000 --- a/vendor/rustix/tests/net/v6.rs +++ /dev/null @@ -1,95 +0,0 @@ -//! Test a simple IPv6 socket server and client. -//! -//! The client send a message and the server sends one back. - -#![cfg(not(any(target_os = "redox", target_os = "wasi")))] - -use rustix::net::{ - accept, bind_v6, connect_v6, getsockname, listen, recv, send, socket, AddressFamily, Ipv6Addr, - Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV6, SocketType, -}; -use std::sync::{Arc, Condvar, Mutex}; -use std::thread; - -const BUFFER_SIZE: usize = 20; - -fn server(ready: Arc<(Mutex, Condvar)>) { - let connection_socket = socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - ) - .unwrap(); - - let name = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 0, 0, 0); - bind_v6(&connection_socket, &name).unwrap(); - - let who = match getsockname(&connection_socket).unwrap() { - SocketAddrAny::V6(addr) => addr, - _ => panic!(), - }; - - listen(&connection_socket, 1).unwrap(); - - { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - *port = who.port(); - cvar.notify_all(); - } - - let mut buffer = vec![0; BUFFER_SIZE]; - let data_socket = accept(&connection_socket).unwrap(); - let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world"); - - send(&data_socket, b"goodnight, moon", SendFlags::empty()).unwrap(); -} - -fn client(ready: Arc<(Mutex, Condvar)>) { - let port = { - let (lock, cvar) = &*ready; - let mut port = lock.lock().unwrap(); - while *port == 0 { - port = cvar.wait(port).unwrap(); - } - *port - }; - - let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0); - let mut buffer = vec![0; BUFFER_SIZE]; - - let data_socket = socket( - AddressFamily::INET6, - SocketType::STREAM, - Protocol::default(), - ) - .unwrap(); - connect_v6(&data_socket, &addr).unwrap(); - - send(&data_socket, b"hello, world", SendFlags::empty()).unwrap(); - - let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap(); - assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon"); -} - -#[test] -fn test_v6() { - let ready = Arc::new((Mutex::new(0_u16), Condvar::new())); - let ready_clone = Arc::clone(&ready); - - let server = thread::Builder::new() - .name("server".to_string()) - .spawn(move || { - server(ready); - }) - .unwrap(); - let client = thread::Builder::new() - .name("client".to_string()) - .spawn(move || { - client(ready_clone); - }) - .unwrap(); - client.join().unwrap(); - server.join().unwrap(); -} diff --git a/vendor/rustix/tests/param/auxv.rs b/vendor/rustix/tests/param/auxv.rs deleted file mode 100644 index 90a088101..000000000 --- a/vendor/rustix/tests/param/auxv.rs +++ /dev/null @@ -1,41 +0,0 @@ -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -use rustix::param::linux_hwcap; -use rustix::param::{clock_ticks_per_second, page_size}; - -#[test] -fn test_page_size() { - let size = page_size(); - assert_ne!(size, 0); - assert!(size.is_power_of_two()); - assert_eq!(size, page_size()); - assert_eq!(size, unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }); -} - -#[test] -fn test_clock_ticks_per_second() { - let size = clock_ticks_per_second(); - assert_ne!(size, 0); - assert_eq!(size, unsafe { libc::sysconf(libc::_SC_CLK_TCK) as u64 }); -} - -#[cfg(any( - all(target_os = "android", target_pointer_width = "64"), - target_os = "linux", -))] -#[test] -fn test_linux_hwcap() { - weak!(fn getauxval(libc::c_ulong) -> libc::c_ulong); - - if let Some(libc_getauxval) = getauxval.get() { - let (_hwcap, hwcap2) = linux_hwcap(); - - // GLIBC seems to return a different value than `LD_SHOW_AUXV=1` reports. - #[cfg(not(target_env = "gnu"))] - assert_eq!(_hwcap, unsafe { libc_getauxval(libc::AT_HWCAP) } as usize); - - assert_eq!(hwcap2, unsafe { libc_getauxval(libc::AT_HWCAP2) } as usize); - } -} diff --git a/vendor/rustix/tests/param/main.rs b/vendor/rustix/tests/param/main.rs deleted file mode 100644 index e350a6f1f..000000000 --- a/vendor/rustix/tests/param/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! Tests for [`rustix::param`]. - -#![cfg(feature = "param")] -#![cfg(not(windows))] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] -#![cfg_attr(core_c_str, feature(core_c_str))] - -#[cfg(not(target_os = "wasi"))] -#[macro_use] -mod weak; - -#[cfg(not(target_os = "wasi"))] -mod auxv; diff --git a/vendor/rustix/tests/param/weak.rs b/vendor/rustix/tests/param/weak.rs deleted file mode 100644 index 377a8a5a1..000000000 --- a/vendor/rustix/tests/param/weak.rs +++ /dev/null @@ -1,201 +0,0 @@ -// Implementation derived from `weak` in Rust's -// library/std/src/sys/unix/weak.rs at revision -// fd0cb0cdc21dd9c06025277d772108f8d42cb25f. - -//! Support for "weak linkage" to symbols on Unix -//! -//! Some I/O operations we do in libstd require newer versions of OSes but we -//! need to maintain binary compatibility with older releases for now. In order -//! to use the new functionality when available we use this module for -//! detection. -//! -//! One option to use here is weak linkage, but that is unfortunately only -//! really workable on Linux. Hence, use dlsym to get the symbol value at -//! runtime. This is also done for compatibility with older versions of glibc, -//! and to avoid creating dependencies on `GLIBC_PRIVATE` symbols. It assumes -//! that we've been dynamically linked to the library the symbol comes from, -//! but that is currently always the case for things like libpthread/libc. -//! -//! A long time ago this used weak linkage for the `__pthread_get_minstack` -//! symbol, but that caused Debian to detect an unnecessarily strict versioned -//! dependency on libc6 (#23628). - -// There are a variety of `#[cfg]`s controlling which targets are involved in -// each instance of `weak!` and `syscall!`. Rather than trying to unify all of -// that, we'll just allow that some unix targets don't use this module at all. -#![allow(dead_code, unused_macros)] -#![allow(clippy::doc_markdown)] - -use core::ffi::c_void; -use core::ptr::null_mut; -use core::sync::atomic::{self, AtomicPtr, Ordering}; -use core::{marker, mem}; -use rustix::ffi::CStr; - -const NULL: *mut c_void = null_mut(); -const INVALID: *mut c_void = 1 as *mut c_void; - -macro_rules! weak { - (fn $name:ident($($t:ty),*) -> $ret:ty) => ( - #[allow(non_upper_case_globals)] - static $name: $crate::weak::Weak $ret> = - $crate::weak::Weak::new(concat!(stringify!($name), '\0')); - ) -} - -pub(crate) struct Weak { - name: &'static str, - addr: AtomicPtr, - _marker: marker::PhantomData, -} - -impl Weak { - pub(crate) const fn new(name: &'static str) -> Self { - Self { - name, - addr: AtomicPtr::new(INVALID), - _marker: marker::PhantomData, - } - } - - pub(crate) fn get(&self) -> Option { - assert_eq!(mem::size_of::(), mem::size_of::()); - unsafe { - // Relaxed is fine here because we fence before reading through the - // pointer (see the comment below). - match self.addr.load(Ordering::Relaxed) { - INVALID => self.initialize(), - NULL => None, - addr => { - let func = mem::transmute_copy::<*mut c_void, F>(&addr); - // The caller is presumably going to read through this value - // (by calling the function we've dlsymed). This means we'd - // need to have loaded it with at least C11's consume - // ordering in order to be guaranteed that the data we read - // from the pointer isn't from before the pointer was - // stored. Rust has no equivalent to memory_order_consume, - // so we use an acquire fence (sorry, ARM). - // - // Now, in practice this likely isn't needed even on CPUs - // where relaxed and consume mean different things. The - // symbols we're loading are probably present (or not) at - // init, and even if they aren't the runtime dynamic loader - // is extremely likely have sufficient barriers internally - // (possibly implicitly, for example the ones provided by - // invoking `mprotect`). - // - // That said, none of that's *guaranteed*, and so we fence. - atomic::fence(Ordering::Acquire); - Some(func) - } - } - } - } - - // Cold because it should only happen during first-time initialization. - #[cold] - unsafe fn initialize(&self) -> Option { - let val = fetch(self.name); - // This synchronizes with the acquire fence in `get`. - self.addr.store(val, Ordering::Release); - - match val { - NULL => None, - addr => Some(mem::transmute_copy::<*mut c_void, F>(&addr)), - } - } -} - -unsafe fn fetch(name: &str) -> *mut c_void { - let name = match CStr::from_bytes_with_nul(name.as_bytes()) { - Ok(c_str) => c_str, - Err(..) => return null_mut(), - }; - libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) -} - -#[cfg(not(any(target_os = "android", target_os = "linux")))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - errno::set_errno(errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - unsafe fn $name($($arg_name:$t),*) -> $ret { - // This looks like a hack, but concat_idents only accepts idents - // (not paths). - use libc::*; - - trait AsSyscallArg { - type SyscallArgType; - fn as_syscall_arg(self) -> Self::SyscallArgType; - } - - // Pass pointer types as pointers, to preserve provenance. - impl AsSyscallArg for *mut T { - type SyscallArgType = *mut T; - fn as_syscall_arg(self) -> Self::SyscallArgType { self } - } - impl AsSyscallArg for *const T { - type SyscallArgType = *const T; - fn as_syscall_arg(self) -> Self::SyscallArgType { self } - } - - // Pass `BorrowedFd` values as the integer value. - impl AsSyscallArg for $crate::fd::BorrowedFd<'_> { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { - $crate::fd::AsRawFd::as_raw_fd(&self) as _ - } - } - - // Coerce integer values into `c_long`. - impl AsSyscallArg for i32 { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - impl AsSyscallArg for u32 { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - impl AsSyscallArg for usize { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - - syscall( - concat_idents!(SYS_, $name), - $($arg_name.as_syscall_arg()),* - ) as $ret - } - ) -} - -macro_rules! weakcall { - ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - $vis unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` - // interposition, but if it's not found just fail. - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - errno::set_errno(errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} diff --git a/vendor/rustix/tests/path/arg.rs b/vendor/rustix/tests/path/arg.rs deleted file mode 100644 index 0eb511be1..000000000 --- a/vendor/rustix/tests/path/arg.rs +++ /dev/null @@ -1,167 +0,0 @@ -use rustix::ffi::{CStr, CString}; -use rustix::io; -use rustix::path::Arg; -#[cfg(feature = "itoa")] -use rustix::path::DecInt; -use std::borrow::Cow; -use std::ffi::{OsStr, OsString}; -use std::path::{Component, Components, Iter, Path, PathBuf}; - -#[test] -fn test_arg() { - use rustix::cstr; - use std::borrow::Borrow; - - let t: &str = "hello"; - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: String = "hello".to_owned(); - assert_eq!("hello", Arg::as_str(&t).unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: &OsStr = OsStr::new("hello"); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: OsString = OsString::from("hello".to_owned()); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: &Path = Path::new("hello"); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: PathBuf = PathBuf::from("hello".to_owned()); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: &CStr = cstr!("hello"); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: CString = cstr!("hello").to_owned(); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!( - cstr!("hello"), - Borrow::borrow(&Arg::as_cow_c_str(&t).unwrap()) - ); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Components = Path::new("hello").components(); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Component = Path::new("hello").components().next().unwrap(); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Iter = Path::new("hello").iter(); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Cow<'_, str> = Cow::Borrowed("hello"); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Cow<'_, str> = Cow::Owned("hello".to_owned()); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Cow<'_, OsStr> = Cow::Borrowed(OsStr::new("hello")); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Cow<'_, OsStr> = Cow::Owned(OsString::from("hello".to_owned())); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Cow<'_, CStr> = Cow::Borrowed(cstr!("hello")); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Cow<'_, CStr> = Cow::Owned(cstr!("hello").to_owned()); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: &[u8] = b"hello"; - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - let t: Vec = b"hello".to_vec(); - assert_eq!("hello", t.as_str().unwrap()); - assert_eq!("hello".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("hello"), Borrow::borrow(&t.into_c_str().unwrap())); - - #[cfg(feature = "itoa")] - { - let t: DecInt = DecInt::new(43110); - assert_eq!("43110", t.as_str()); - assert_eq!("43110".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(cstr!("43110"), Borrow::borrow(&t.as_cow_c_str().unwrap())); - assert_eq!(cstr!("43110"), t.as_c_str()); - assert_eq!(cstr!("43110"), Borrow::borrow(&t.into_c_str().unwrap())); - } -} - -#[test] -fn test_invalid() { - use std::borrow::Borrow; - - let t: &[u8] = b"hello\xc0world"; - assert_eq!(t.as_str().unwrap_err(), io::Errno::INVAL); - assert_eq!("hello\u{fffd}world".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!( - b"hello\xc0world\0", - Borrow::::borrow(&t.as_cow_c_str().unwrap()).to_bytes_with_nul() - ); - assert_eq!( - b"hello\xc0world\0", - Borrow::::borrow(&t.into_c_str().unwrap()).to_bytes_with_nul() - ); -} - -#[test] -fn test_embedded_nul() { - let t: &[u8] = b"hello\0world"; - assert_eq!("hello\0world", t.as_str().unwrap()); - assert_eq!("hello\0world".to_owned(), Arg::to_string_lossy(&t)); - assert_eq!(t.as_cow_c_str().unwrap_err(), io::Errno::INVAL); - assert_eq!(t.into_c_str().unwrap_err(), io::Errno::INVAL); -} diff --git a/vendor/rustix/tests/path/dec_int.rs b/vendor/rustix/tests/path/dec_int.rs deleted file mode 100644 index 6ce1a5123..000000000 --- a/vendor/rustix/tests/path/dec_int.rs +++ /dev/null @@ -1,20 +0,0 @@ -use rustix::path::DecInt; - -#[test] -fn test_dec_int() { - assert_eq!(DecInt::new(0).as_ref().to_str().unwrap(), "0"); - assert_eq!(DecInt::new(-1).as_ref().to_str().unwrap(), "-1"); - assert_eq!(DecInt::new(789).as_ref().to_str().unwrap(), "789"); - assert_eq!( - DecInt::new(i64::MIN).as_ref().to_str().unwrap(), - i64::MIN.to_string() - ); - assert_eq!( - DecInt::new(i64::MAX).as_ref().to_str().unwrap(), - i64::MAX.to_string() - ); - assert_eq!( - DecInt::new(u64::MAX).as_ref().to_str().unwrap(), - u64::MAX.to_string() - ); -} diff --git a/vendor/rustix/tests/path/main.rs b/vendor/rustix/tests/path/main.rs deleted file mode 100644 index 3215c7e5e..000000000 --- a/vendor/rustix/tests/path/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Tests for [`rustix::path`]. - -#![cfg(any(feature = "fs", feature = "net"))] -#![cfg(not(windows))] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] -#![cfg_attr(core_c_str, feature(core_c_str))] -#![cfg_attr(alloc_c_string, feature(alloc_c_string))] - -#[cfg(not(feature = "rustc-dep-of-std"))] -mod arg; -#[cfg(feature = "itoa")] -mod dec_int; diff --git a/vendor/rustix/tests/process/cpu_set.rs b/vendor/rustix/tests/process/cpu_set.rs deleted file mode 100644 index c4d9edf08..000000000 --- a/vendor/rustix/tests/process/cpu_set.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_cpu_set() { - let set = rustix::process::sched_getaffinity(None).unwrap(); - - let mut count = 0; - for i in 0..rustix::process::CpuSet::MAX_CPU { - if set.is_set(i) { - count += 1; - } - } - - assert_eq!(count, set.count()); -} diff --git a/vendor/rustix/tests/process/id.rs b/vendor/rustix/tests/process/id.rs deleted file mode 100644 index 10095fa60..000000000 --- a/vendor/rustix/tests/process/id.rs +++ /dev/null @@ -1,65 +0,0 @@ -use rustix::process; - -#[test] -fn test_getuid() { - assert_eq!(process::getuid(), process::getuid()); - unsafe { - assert_eq!(process::getuid().as_raw(), libc::getuid()); - assert_eq!(process::getuid().is_root(), libc::getuid() == 0); - } -} - -#[test] -fn test_getgid() { - assert_eq!(process::getgid(), process::getgid()); - unsafe { - assert_eq!(process::getgid().as_raw(), libc::getgid()); - assert_eq!(process::getgid().is_root(), libc::getgid() == 0); - } -} - -#[test] -fn test_geteuid() { - assert_eq!(process::geteuid(), process::geteuid()); - unsafe { - assert_eq!(process::geteuid().as_raw(), libc::geteuid()); - assert_eq!(process::geteuid().is_root(), libc::geteuid() == 0); - } -} - -#[test] -fn test_getegid() { - assert_eq!(process::getegid(), process::getegid()); - unsafe { - assert_eq!(process::getegid().as_raw(), libc::getegid()); - assert_eq!(process::getegid().is_root(), libc::getegid() == 0); - } -} - -#[test] -fn test_getpid() { - assert_eq!(process::getpid(), process::getpid()); - unsafe { - assert_eq!( - process::getpid().as_raw_nonzero().get() as libc::pid_t, - libc::getpid() - ); - assert_eq!(process::getpid().is_init(), libc::getpid() == 1); - } -} - -#[test] -fn test_getppid() { - assert_eq!(process::getppid(), process::getppid()); - unsafe { - assert_eq!( - process::Pid::as_raw(process::getppid()) as libc::pid_t, - libc::getppid() - ); - if let Some(ppid) = process::getppid() { - assert_eq!(ppid.is_init(), libc::getppid() == 1); - } else { - assert_eq!(libc::getppid(), 0); - } - } -} diff --git a/vendor/rustix/tests/process/main.rs b/vendor/rustix/tests/process/main.rs deleted file mode 100644 index 90aa34c59..000000000 --- a/vendor/rustix/tests/process/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! Tests for [`rustix::process`]. - -#![cfg(feature = "process")] -#![cfg(not(windows))] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] -#![cfg_attr(core_c_str, feature(core_c_str))] - -#[cfg(not(target_os = "wasi"))] -#[macro_use] -mod weak; - -mod cpu_set; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. -mod id; -#[cfg(any(target_os = "android", target_os = "linux"))] -mod membarrier; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] // WASI doesn't have [gs]etpriority. -mod priority; -#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -mod rlimit; -mod sched_yield; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have uname. -mod uname; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have waitpid. -mod wait; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -mod working_directory; diff --git a/vendor/rustix/tests/process/membarrier.rs b/vendor/rustix/tests/process/membarrier.rs deleted file mode 100644 index ed9b00c1a..000000000 --- a/vendor/rustix/tests/process/membarrier.rs +++ /dev/null @@ -1,40 +0,0 @@ -#[test] -fn test_membarrier() { - use rustix::process::{membarrier, membarrier_query, MembarrierCommand, MembarrierQuery}; - - let query: MembarrierQuery = membarrier_query(); - - // Supported registration commands should succeed. - for cmd in [ - MembarrierCommand::RegisterGlobalExpedited, - MembarrierCommand::RegisterPrivateExpedited, - MembarrierCommand::RegisterPrivateExpeditedSyncCore, - MembarrierCommand::RegisterPrivateExpeditedRseq, - ] - .iter() - .copied() - { - if query.contains_command(cmd) { - membarrier(cmd).unwrap(); - } - } - - // All supported commands should now succeed, and all unsupported - // commands should fail. - for cmd in [ - MembarrierCommand::Global, - MembarrierCommand::GlobalExpedited, - MembarrierCommand::PrivateExpedited, - MembarrierCommand::PrivateExpeditedSyncCore, - MembarrierCommand::PrivateExpeditedRseq, - ] - .iter() - .copied() - { - if query.contains_command(cmd) { - membarrier(cmd).unwrap(); - } else { - membarrier(cmd).unwrap_err(); - } - } -} diff --git a/vendor/rustix/tests/process/priority.rs b/vendor/rustix/tests/process/priority.rs deleted file mode 100644 index 7feb1467a..000000000 --- a/vendor/rustix/tests/process/priority.rs +++ /dev/null @@ -1,83 +0,0 @@ -use rustix::process::nice; -#[cfg(not(target_os = "redox"))] -use rustix::process::{getpriority_process, setpriority_process}; - -#[cfg(not(target_os = "freebsd"))] // FreeBSD's nice(3) doesn't return the old value. -#[test] -fn test_priorities() { - let old = nice(0).unwrap(); - - #[cfg(not(target_os = "redox"))] - { - let get_prio = getpriority_process(None).unwrap(); - assert_eq!(get_prio, old); - } - - // Lower the priority by one. - let new = nice(1).unwrap(); - - // If the test wasn't running with the lowest priority initially, test that - // we were able to lower the priority. - if old < 19 { - assert_eq!(old + 1, new); - } - - let get = nice(0).unwrap(); - assert_eq!(new, get); - - #[cfg(not(target_os = "redox"))] - { - let get_prio = getpriority_process(None).unwrap(); - assert_eq!(get_prio, new); - - setpriority_process(None, get + 1).unwrap(); - let now = getpriority_process(None).unwrap(); - - // If the test wasn't running with the lowest priority initially, test - // that we were able to lower the priority. - if get < 19 { - assert_eq!(get + 1, now); - } - setpriority_process(None, get + 10000).unwrap(); - let now = getpriority_process(None).unwrap(); - // Linux's max is 19; Darwin's max is 20. - assert!(now >= 19 && now <= 20); - // Darwin appears to return `EPERM` on an out of range `nice`. - if let Ok(again) = nice(1) { - assert_eq!(now, again); - } - } -} - -/// FreeBSD's `nice` doesn't return the new nice value, so use a specialized -/// test. -#[cfg(target_os = "freebsd")] -#[test] -fn test_priorities() { - let start = getpriority_process(None).unwrap(); - - let _ = nice(0).unwrap(); - - let now = getpriority_process(None).unwrap(); - assert_eq!(start, now); - - let _ = nice(1).unwrap(); - - let now = getpriority_process(None).unwrap(); - assert_eq!(start + 1, now); - - setpriority_process(None, start + 2).unwrap(); - - let now = getpriority_process(None).unwrap(); - assert_eq!(start + 2, now); - - setpriority_process(None, 10000).unwrap(); - - let now = getpriority_process(None).unwrap(); - assert_eq!(now, 20); - - let _ = nice(1).unwrap(); - - let now = getpriority_process(None).unwrap(); - assert_eq!(now, 20); -} diff --git a/vendor/rustix/tests/process/proc.rs b/vendor/rustix/tests/process/proc.rs deleted file mode 100644 index e85d85883..000000000 --- a/vendor/rustix/tests/process/proc.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[test] -fn test_proc_funcs() { - let _maps = rustix::io::proc_self_maps().unwrap(); - let _pagemap = rustix::io::proc_self_pagemap().unwrap(); -} diff --git a/vendor/rustix/tests/process/rlimit.rs b/vendor/rustix/tests/process/rlimit.rs deleted file mode 100644 index b01f9204c..000000000 --- a/vendor/rustix/tests/process/rlimit.rs +++ /dev/null @@ -1,51 +0,0 @@ -use rustix::process::{Resource, Rlimit}; - -#[test] -fn test_getrlimit() { - let lim = rustix::process::getrlimit(Resource::Stack); - assert_ne!(lim.current, Some(0)); - assert_ne!(lim.maximum, Some(0)); -} - -#[test] -fn test_setrlimit() { - let old = rustix::process::getrlimit(Resource::Core); - let new = Rlimit { - current: Some(0), - maximum: Some(4096), - }; - assert_ne!(old, new); - rustix::process::setrlimit(Resource::Core, new.clone()).unwrap(); - - let lim = rustix::process::getrlimit(Resource::Core); - assert_eq!(lim, new); - - #[cfg(any(target_os = "android", target_os = "linux"))] - { - let new = Rlimit { - current: Some(0), - maximum: Some(0), - }; - - let first = rustix::process::getrlimit(Resource::Core); - - let old = match rustix::process::prlimit(None, Resource::Core, new.clone()) { - Ok(rlimit) => rlimit, - Err(rustix::io::Errno::NOSYS) => return, - Err(e) => Err(e).unwrap(), - }; - - assert_eq!(first, old); - - let other = Rlimit { - current: Some(0), - maximum: Some(0), - }; - - let again = - rustix::process::prlimit(Some(rustix::process::getpid()), Resource::Core, other) - .unwrap(); - - assert_eq!(again, new); - } -} diff --git a/vendor/rustix/tests/process/sched_yield.rs b/vendor/rustix/tests/process/sched_yield.rs deleted file mode 100644 index eacf17d5e..000000000 --- a/vendor/rustix/tests/process/sched_yield.rs +++ /dev/null @@ -1,7 +0,0 @@ -use rustix::process::sched_yield; - -#[test] -fn test_sched_yield() { - // Just make sure we can call it. - sched_yield(); -} diff --git a/vendor/rustix/tests/process/uname.rs b/vendor/rustix/tests/process/uname.rs deleted file mode 100644 index bc944c49e..000000000 --- a/vendor/rustix/tests/process/uname.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[test] -fn test_uname() { - let name: rustix::process::Uname = rustix::process::uname(); - - assert!(!name.sysname().to_bytes().is_empty()); - assert!(!name.nodename().to_bytes().is_empty()); - assert!(!name.release().to_bytes().is_empty()); - assert!(!name.version().to_bytes().is_empty()); - assert!(!name.machine().to_bytes().is_empty()); - - #[cfg(any(target_os = "android", target_os = "linux"))] - assert!(!name.domainname().to_bytes().is_empty()); -} diff --git a/vendor/rustix/tests/process/wait.rs b/vendor/rustix/tests/process/wait.rs deleted file mode 100644 index a1f25a631..000000000 --- a/vendor/rustix/tests/process/wait.rs +++ /dev/null @@ -1,25 +0,0 @@ -use libc::{kill, SIGSTOP}; -use rustix::process; -use serial_test::serial; -use std::process::{Command, Stdio}; - -// These tests must execute serially to prevent race condition, where -// `test_wait` waits for the child process spawned in `test_waitpid`, causing -// the tests to get stuck. - -#[test] -#[serial] -fn test_waitpid() { - let child = Command::new("yes") - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .spawn() - .expect("failed to execute child"); - unsafe { kill(child.id() as _, SIGSTOP) }; - - let pid = unsafe { process::Pid::from_raw(child.id() as _) }; - let status = process::waitpid(pid, process::WaitOptions::UNTRACED) - .expect("failed to wait") - .unwrap(); - assert!(status.stopped()); -} diff --git a/vendor/rustix/tests/process/weak.rs b/vendor/rustix/tests/process/weak.rs deleted file mode 100644 index d4f00f999..000000000 --- a/vendor/rustix/tests/process/weak.rs +++ /dev/null @@ -1,201 +0,0 @@ -// Implementation derived from `weak` in Rust's -// library/std/src/sys/unix/weak.rs at revision -// fd0cb0cdc21dd9c06025277d772108f8d42cb25f. - -//! Support for "weak linkage" to symbols on Unix -//! -//! Some I/O operations we do in libstd require newer versions of OSes but we -//! need to maintain binary compatibility with older releases for now. In order -//! to use the new functionality when available we use this module for -//! detection. -//! -//! One option to use here is weak linkage, but that is unfortunately only -//! really workable on Linux. Hence, use dlsym to get the symbol value at -//! runtime. This is also done for compatibility with older versions of glibc, -//! and to avoid creating dependencies on `GLIBC_PRIVATE` symbols. It assumes -//! that we've been dynamically linked to the library the symbol comes from, -//! but that is currently always the case for things like libpthread/libc. -//! -//! A long time ago this used weak linkage for the `__pthread_get_minstack` -//! symbol, but that caused Debian to detect an unnecessarily strict versioned -//! dependency on libc6 (#23628). - -// There are a variety of `#[cfg]`s controlling which targets are involved in -// each instance of `weak!` and `syscall!`. Rather than trying to unify all of -// that, we'll just allow that some unix targets don't use this module at all. -#![allow(dead_code, unused_macros)] -#![allow(clippy::doc_markdown)] - -use core::ffi::c_void; -use core::ptr::null_mut; -use core::sync::atomic::{self, AtomicPtr, Ordering}; -use core::{marker, mem}; -use rustix::ffi::CStr; - -const NULL: *mut c_void = null_mut(); -const INVALID: *mut c_void = 1 as *mut c_void; - -macro_rules! weak { - (fn $name:ident($($t:ty),*) -> $ret:ty) => ( - #[allow(non_upper_case_globals)] - static $name: $crate::weak::Weak $ret> = - $crate::weak::Weak::new(concat!(stringify!($name), '\0')); - ) -} - -pub(crate) struct Weak { - name: &'static str, - addr: AtomicPtr, - _marker: marker::PhantomData, -} - -impl Weak { - pub(crate) const fn new(name: &'static str) -> Self { - Self { - name, - addr: AtomicPtr::new(INVALID), - _marker: marker::PhantomData, - } - } - - pub(crate) fn get(&self) -> Option { - assert_eq!(mem::size_of::(), mem::size_of::()); - unsafe { - // Relaxed is fine here because we fence before reading through the - // pointer (see the comment below). - match self.addr.load(Ordering::Relaxed) { - INVALID => self.initialize(), - NULL => None, - addr => { - let func = mem::transmute_copy::<*mut c_void, F>(&addr); - // The caller is presumably going to read through this value - // (by calling the function we've dlsymed). This means we'd - // need to have loaded it with at least C11's consume - // ordering in order to be guaranteed that the data we read - // from the pointer isn't from before the pointer was - // stored. Rust has no equivalent to memory_order_consume, - // so we use an acquire fence (sorry, ARM). - // - // Now, in practice this likely isn't needed even on CPUs - // where relaxed and consume mean different things. The - // symbols we're loading are probably present (or not) at - // init, and even if they aren't the runtime dynamic loader - // is extremely likely have sufficient barriers internally - // (possibly implicitly, for example the ones provided by - // invoking `mprotect`). - // - // That said, none of that's *guaranteed*, and so we fence. - atomic::fence(Ordering::Acquire); - Some(func) - } - } - } - } - - // Cold because it should only happen during first-time initialization. - #[cold] - unsafe fn initialize(&self) -> Option { - let val = fetch(self.name); - // This synchronizes with the acquire fence in `get`. - self.addr.store(val, Ordering::Release); - - match val { - NULL => None, - addr => Some(mem::transmute_copy::<*mut c_void, F>(&addr)), - } - } -} - -unsafe fn fetch(name: &str) -> *mut c_void { - let name = match CStr::from_bytes_with_nul(name.as_bytes()) { - Ok(c_str) => c_str, - Err(..) => return null_mut(), - }; - libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr().cast()) -} - -#[cfg(not(any(target_os = "android", target_os = "linux")))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - errno::set_errno(errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -macro_rules! syscall { - (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - unsafe fn $name($($arg_name:$t),*) -> $ret { - // This looks like a hack, but concat_idents only accepts idents - // (not paths). - use libc::*; - - trait AsSyscallArg { - type SyscallArgType; - fn as_syscall_arg(self) -> Self::SyscallArgType; - } - - // Pass pointer types as pointers, to preserve provenance. - impl AsSyscallArg for *mut T { - type SyscallArgType = *mut T; - fn as_syscall_arg(self) -> Self::SyscallArgType { self } - } - impl AsSyscallArg for *const T { - type SyscallArgType = *const T; - fn as_syscall_arg(self) -> Self::SyscallArgType { self } - } - - // Pass `BorrowedFd` values as the integer value. - impl AsSyscallArg for $crate::fd::BorrowedFd<'_> { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { - $crate::fd::AsRawFd::as_raw_fd(&self) as _ - } - } - - // Coerce integer values into `c_long`. - impl AsSyscallArg for i32 { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - impl AsSyscallArg for u32 { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - impl AsSyscallArg for usize { - type SyscallArgType = c::c_long; - fn as_syscall_arg(self) -> Self::SyscallArgType { self as _ } - } - - syscall( - concat_idents!(SYS_, $name), - $($arg_name.as_syscall_arg()),* - ) as $ret - } - ) -} - -macro_rules! weakcall { - ($vis:vis fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - $vis unsafe fn $name($($arg_name: $t),*) -> $ret { - weak! { fn $name($($t),*) -> $ret } - - // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` - // interposition, but if it's not found just fail. - if let Some(fun) = $name.get() { - fun($($arg_name),*) - } else { - errno::set_errno(errno::Errno(libc::ENOSYS)); - -1 - } - } - ) -} diff --git a/vendor/rustix/tests/process/working_directory.rs b/vendor/rustix/tests/process/working_directory.rs deleted file mode 100644 index 1c3262bb9..000000000 --- a/vendor/rustix/tests/process/working_directory.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![cfg(feature = "fs")] - -#[cfg(not(target_os = "macos"))] -use rustix::fs::{Mode, OFlags}; -use tempfile::{tempdir, TempDir}; - -#[allow(unused)] -fn tmpdir() -> TempDir { - tempdir().expect("expected to be able to create a temporary directory") -} - -/// Disable this test on macos because GHA has a weird system folder structure -/// that makes this test fail. -#[cfg(not(target_os = "macos"))] -#[test] -fn test_changing_working_directory() { - let tmpdir = tmpdir(); - - let orig_cwd = rustix::process::getcwd(Vec::new()).expect("get the cwd"); - let orig_fd_cwd = rustix::fs::openat(rustix::fs::cwd(), ".", OFlags::RDONLY, Mode::empty()) - .expect("get a fd for the current directory"); - - rustix::process::chdir(tmpdir.path()).expect("changing dir to the tmp"); - let ch1_cwd = rustix::process::getcwd(Vec::new()).expect("get the cwd"); - - assert_ne!(orig_cwd, ch1_cwd, "The cwd hasn't changed!"); - assert_eq!( - ch1_cwd.to_string_lossy(), - tmpdir.path().to_string_lossy(), - "The cwd is not the same as the tmpdir" - ); - - #[cfg(not(target_os = "fuchsia"))] - rustix::process::fchdir(orig_fd_cwd).expect("changing dir to the original"); - #[cfg(target_os = "fushcia")] - rustix::process::chdir(orig_cwd).expect("changing dir to the original"); - let ch2_cwd = rustix::process::getcwd(ch1_cwd).expect("get the cwd"); - - assert_eq!( - orig_cwd, ch2_cwd, - "The cwd wasn't changed back to the its original position" - ); -} diff --git a/vendor/rustix/tests/rand/getrandom.rs b/vendor/rustix/tests/rand/getrandom.rs deleted file mode 100644 index ac316e447..000000000 --- a/vendor/rustix/tests/rand/getrandom.rs +++ /dev/null @@ -1,7 +0,0 @@ -use rustix::rand::{getrandom, GetRandomFlags}; - -#[test] -fn test_getrandom() { - let mut buf = [0_u8; 256]; - let _ = getrandom(&mut buf, GetRandomFlags::empty()); -} diff --git a/vendor/rustix/tests/rand/main.rs b/vendor/rustix/tests/rand/main.rs deleted file mode 100644 index 9dac8027f..000000000 --- a/vendor/rustix/tests/rand/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Tests for [`rustix::rand`]. - -#![cfg(feature = "rand")] -#![cfg(not(windows))] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - -#[cfg(any(linux_raw, all(libc, target_os = "linux")))] -mod getrandom; diff --git a/vendor/rustix/tests/termios/isatty.rs b/vendor/rustix/tests/termios/isatty.rs deleted file mode 100644 index 5e6fae73d..000000000 --- a/vendor/rustix/tests/termios/isatty.rs +++ /dev/null @@ -1,69 +0,0 @@ -use rustix::fd::AsRawFd; -use rustix::termios::{isatty, tcgetwinsize}; -use tempfile::{tempdir, TempDir}; - -#[allow(unused)] -fn tmpdir() -> TempDir { - tempdir().expect("expected to be able to create a temporary directory") -} - -#[test] -fn std_file_is_not_terminal() { - let tmpdir = tempfile::tempdir().unwrap(); - assert!(!isatty( - &std::fs::File::create(tmpdir.path().join("file")).unwrap() - )); - assert!(!isatty( - &std::fs::File::open(tmpdir.path().join("file")).unwrap() - )); -} - -#[test] -fn stdout_stderr_terminals() { - // This test is flaky under qemu. - if std::env::vars().any(|var| var.0.starts_with("CARGO_TARGET_") && var.0.ends_with("_RUNNER")) - { - return; - } - - // Compare `isatty` against `libc::isatty`. - assert_eq!(isatty(&std::io::stdout()), unsafe { - libc::isatty(std::io::stdout().as_raw_fd()) != 0 - }); - assert_eq!(isatty(&std::io::stderr()), unsafe { - libc::isatty(std::io::stderr().as_raw_fd()) != 0 - }); - - // Compare `isatty` against `tcgetwinsize`. - assert_eq!( - isatty(&std::io::stdout()), - tcgetwinsize(&std::io::stdout()).is_ok() - ); - assert_eq!( - isatty(&std::io::stderr()), - tcgetwinsize(&std::io::stderr()).is_ok() - ); -} - -#[test] -fn stdio_descriptors() { - #[cfg(unix)] - use std::os::unix::io::AsRawFd; - #[cfg(target_os = "wasi")] - use std::os::wasi::io::AsRawFd; - - unsafe { - assert_eq!( - rustix::io::stdin().as_raw_fd(), - std::io::stdin().as_raw_fd() - ); - assert_eq!( - rustix::io::stdout().as_raw_fd(), - std::io::stdout().as_raw_fd() - ); - assert_eq!( - rustix::io::stderr().as_raw_fd(), - std::io::stderr().as_raw_fd() - ); - } -} diff --git a/vendor/rustix/tests/termios/main.rs b/vendor/rustix/tests/termios/main.rs deleted file mode 100644 index d9ad9338b..000000000 --- a/vendor/rustix/tests/termios/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Tests for [`rustix::termios`]. - -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] -#![cfg(feature = "termios")] - -#[cfg(not(windows))] -mod isatty; -#[cfg(not(windows))] -mod ttyname; diff --git a/vendor/rustix/tests/termios/ttyname.rs b/vendor/rustix/tests/termios/ttyname.rs deleted file mode 100644 index 636178c31..000000000 --- a/vendor/rustix/tests/termios/ttyname.rs +++ /dev/null @@ -1,24 +0,0 @@ -use rustix::io; -use rustix::termios::{isatty, ttyname}; -use std::fs::File; - -#[test] -fn test_ttyname_ok() { - let file = File::open("/dev/stdin").unwrap(); - if isatty(&file) { - assert!(ttyname(&file, Vec::new()) - .unwrap() - .into_string() - .unwrap() - .starts_with("/dev/")); - } -} - -#[test] -fn test_ttyname_not_tty() { - let file = File::open("Cargo.toml").unwrap(); - assert_eq!(ttyname(&file, Vec::new()).unwrap_err(), io::Errno::NOTTY); - - let file = File::open("/dev/null").unwrap(); - assert_eq!(ttyname(&file, Vec::new()).unwrap_err(), io::Errno::NOTTY); -} diff --git a/vendor/rustix/tests/thread/clocks.rs b/vendor/rustix/tests/thread/clocks.rs deleted file mode 100644 index cf14df777..000000000 --- a/vendor/rustix/tests/thread/clocks.rs +++ /dev/null @@ -1,212 +0,0 @@ -#[cfg(not(any( - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -use rustix::thread::{clock_nanosleep_absolute, clock_nanosleep_relative, ClockId}; -#[cfg(not(target_os = "redox"))] -use { - rustix::io, - rustix::thread::{nanosleep, NanosleepRelativeResult, Timespec}, -}; - -#[cfg(not(target_os = "redox"))] -#[test] -fn test_invalid_nanosleep() { - match nanosleep(&Timespec { - tv_sec: 0, - tv_nsec: 1_000_000_000, - }) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match nanosleep(&Timespec { - tv_sec: 0, - tv_nsec: !0, - }) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match nanosleep(&Timespec { - tv_sec: !0, - tv_nsec: 1_000_000_000, - }) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match nanosleep(&Timespec { - tv_sec: !0, - tv_nsec: !0, - }) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[test] -fn test_invalid_nanosleep_absolute() { - match clock_nanosleep_absolute( - ClockId::Monotonic, - &Timespec { - tv_sec: 0, - tv_nsec: 1000000000, - }, - ) { - Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match clock_nanosleep_absolute( - ClockId::Monotonic, - &Timespec { - tv_sec: 0, - tv_nsec: !0, - }, - ) { - Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match clock_nanosleep_absolute( - ClockId::Monotonic, - &Timespec { - tv_sec: !0, - tv_nsec: 1_000_000_000, - }, - ) { - Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match clock_nanosleep_absolute( - ClockId::Monotonic, - &Timespec { - tv_sec: !0, - tv_nsec: !0, - }, - ) { - Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[test] -fn test_invalid_nanosleep_relative() { - match clock_nanosleep_relative( - ClockId::Monotonic, - &Timespec { - tv_sec: 0, - tv_nsec: 1_000_000_000, - }, - ) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match clock_nanosleep_relative( - ClockId::Monotonic, - &Timespec { - tv_sec: 0, - tv_nsec: !0, - }, - ) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match clock_nanosleep_relative( - ClockId::Monotonic, - &Timespec { - tv_sec: !0, - tv_nsec: 1_000_000_000, - }, - ) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } - match clock_nanosleep_relative( - ClockId::Monotonic, - &Timespec { - tv_sec: !0, - tv_nsec: !0, - }, - ) { - NanosleepRelativeResult::Err(io::Errno::INVAL) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } -} - -#[cfg(not(target_os = "redox"))] -#[test] -fn test_zero_nanosleep() { - match nanosleep(&Timespec { - tv_sec: 0, - tv_nsec: 0, - }) { - NanosleepRelativeResult::Ok => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[test] -fn test_zero_nanosleep_absolute() { - match clock_nanosleep_absolute( - ClockId::Monotonic, - &Timespec { - tv_sec: 0, - tv_nsec: 0, - }, - ) { - Ok(()) => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } -} - -#[cfg(not(any( - target_os = "emscripten", - target_os = "freebsd", - target_os = "ios", - target_os = "macos", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[test] -fn test_zero_nanosleep_relative() { - match clock_nanosleep_relative( - ClockId::Monotonic, - &Timespec { - tv_sec: 0, - tv_nsec: 0, - }, - ) { - NanosleepRelativeResult::Ok => (), - otherwise => panic!("unexpected resut: {:?}", otherwise), - } -} diff --git a/vendor/rustix/tests/thread/id.rs b/vendor/rustix/tests/thread/id.rs deleted file mode 100644 index 7aa5abba5..000000000 --- a/vendor/rustix/tests/thread/id.rs +++ /dev/null @@ -1,7 +0,0 @@ -use rustix::thread; - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_gettid() { - assert_eq!(thread::gettid(), thread::gettid()); -} diff --git a/vendor/rustix/tests/thread/main.rs b/vendor/rustix/tests/thread/main.rs deleted file mode 100644 index 0fc9b42c4..000000000 --- a/vendor/rustix/tests/thread/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Tests for [`rustix::thread`]. - -#![cfg(feature = "thread")] -#![cfg(not(windows))] - -#[cfg(not(any(target_os = "redox")))] -mod clocks; -#[cfg(any(target_os = "android", target_os = "linux"))] -mod id; diff --git a/vendor/rustix/tests/time/dynamic_clocks.rs b/vendor/rustix/tests/time/dynamic_clocks.rs deleted file mode 100644 index a7e1e6792..000000000 --- a/vendor/rustix/tests/time/dynamic_clocks.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![cfg(not(any(target_os = "redox", target_os = "wasi")))] - -use rustix::fd::AsFd; -use rustix::time::{clock_gettime_dynamic, ClockId, DynamicClockId}; - -#[test] -fn test_known_clocks() { - clock_gettime_dynamic(DynamicClockId::Known(ClockId::Realtime)).unwrap(); - clock_gettime_dynamic(DynamicClockId::Known(ClockId::Monotonic)).unwrap(); -} - -#[test] -fn test_dynamic_clocks() { - let file = std::fs::File::open("Cargo.toml").unwrap(); - clock_gettime_dynamic(DynamicClockId::Dynamic(file.as_fd())).unwrap_err(); -} - -#[cfg(any(target_os = "android", target_os = "linux"))] -#[test] -fn test_conditional_clocks() { - let _ = clock_gettime_dynamic(DynamicClockId::Tai); -} diff --git a/vendor/rustix/tests/time/main.rs b/vendor/rustix/tests/time/main.rs deleted file mode 100644 index 43283bca2..000000000 --- a/vendor/rustix/tests/time/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! Tests for [`rustix::time`]. - -#![cfg(feature = "time")] -#![cfg(not(windows))] -#![cfg_attr(target_os = "wasi", feature(wasi_ext))] -#![cfg_attr(io_lifetimes_use_std, feature(io_safety))] - -mod dynamic_clocks; -#[cfg(not(any(target_os = "redox", target_os = "wasi")))] -mod monotonic; -#[cfg(any(target_os = "android", target_os = "linux"))] -mod timerfd; -mod timespec; -mod y2038; diff --git a/vendor/rustix/tests/time/monotonic.rs b/vendor/rustix/tests/time/monotonic.rs deleted file mode 100644 index 89470f2b4..000000000 --- a/vendor/rustix/tests/time/monotonic.rs +++ /dev/null @@ -1,45 +0,0 @@ -#[cfg(feature = "thread")] -use rustix::thread::nanosleep; -use rustix::time::{clock_gettime, ClockId, Timespec}; - -/// Attempt to test that the monotonic clock is monotonic. Time may or may not -/// advance, but it shouldn't regress. -#[test] -fn test_monotonic_clock() { - let a = clock_gettime(ClockId::Monotonic); - let b = clock_gettime(ClockId::Monotonic); - if b.tv_sec == a.tv_sec { - assert!(b.tv_nsec >= a.tv_nsec); - } else { - assert!(b.tv_sec > a.tv_sec); - } -} - -/// With the "thread" feature, we can sleep so that we're guaranteed that time -/// has advanced. -#[cfg(feature = "thread")] -#[test] -fn test_monotonic_clock_with_sleep_1s() { - let a = clock_gettime(ClockId::Monotonic); - let _rem = nanosleep(&Timespec { - tv_sec: 1, - tv_nsec: 0, - }); - let b = clock_gettime(ClockId::Monotonic); - assert!(b.tv_sec > a.tv_sec); -} - -/// With the "thread" feature, we can sleep so that we're guaranteed that time -/// has advanced. -#[cfg(feature = "thread")] -#[test] -fn test_monotonic_clock_with_sleep_1ms() { - let a = clock_gettime(ClockId::Monotonic); - let _rem = nanosleep(&Timespec { - tv_sec: 0, - tv_nsec: 1_000_000, - }); - let b = clock_gettime(ClockId::Monotonic); - assert!(b.tv_sec >= a.tv_sec); - assert!(b.tv_sec != a.tv_sec || b.tv_nsec > a.tv_nsec); -} diff --git a/vendor/rustix/tests/time/timerfd.rs b/vendor/rustix/tests/time/timerfd.rs deleted file mode 100644 index 6ad4dd72e..000000000 --- a/vendor/rustix/tests/time/timerfd.rs +++ /dev/null @@ -1,75 +0,0 @@ -use rustix::time::{ - timerfd_create, timerfd_gettime, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags, - TimerfdTimerFlags, Timespec, -}; - -#[test] -fn test_timerfd() { - let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap(); - - let set = Itimerspec { - it_interval: Timespec { - tv_sec: 0, - tv_nsec: 0, - }, - it_value: Timespec { - tv_sec: 1, - tv_nsec: 2, - }, - }; - let _old: Itimerspec = timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set).unwrap(); - - // Wait for the timer to expire. - let mut buf = [0_u8; 8]; - assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8)); - assert!(u64::from_ne_bytes(buf) >= 1); - - let new = timerfd_gettime(&fd).unwrap(); - - // The timer counts down. - assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); - assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); - assert!(new.it_value.tv_sec <= set.it_value.tv_sec); - assert!( - new.it_value.tv_nsec < set.it_value.tv_nsec || new.it_value.tv_sec < set.it_value.tv_sec - ); -} - -/// Similar, but set an interval for a repeated timer. Don't check that the -/// times are monotonic because that would race with the timer repeating. -#[test] -fn test_timerfd_with_interval() { - let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap(); - - let set = Itimerspec { - it_interval: Timespec { - tv_sec: 0, - tv_nsec: 6, - }, - it_value: Timespec { - tv_sec: 1, - tv_nsec: 7, - }, - }; - let _old: Itimerspec = timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set).unwrap(); - - // Wait for the timer to expire. - let mut buf = [0_u8; 8]; - assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8)); - assert!(u64::from_ne_bytes(buf) >= 1); - - let new = timerfd_gettime(&fd).unwrap(); - - assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); - assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); - - // Wait for the timer to expire again. - let mut buf = [0_u8; 8]; - assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8)); - assert!(u64::from_ne_bytes(buf) >= 1); - - let new = timerfd_gettime(&fd).unwrap(); - - assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); - assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); -} diff --git a/vendor/rustix/tests/time/timespec.rs b/vendor/rustix/tests/time/timespec.rs deleted file mode 100644 index 6d892dcfe..000000000 --- a/vendor/rustix/tests/time/timespec.rs +++ /dev/null @@ -1,26 +0,0 @@ -#[test] -fn test_timespec_layout() { - #[cfg(not(target_os = "redox"))] - use rustix::fs::{UTIME_NOW, UTIME_OMIT}; - use rustix::time::{Nsecs, Secs, Timespec}; - - let tv_sec: Secs = 0; - let tv_nsec: Nsecs = 0; - let _ = Timespec { tv_sec, tv_nsec }; - - #[cfg(not(target_os = "redox"))] - let _ = Timespec { - tv_sec, - tv_nsec: UTIME_NOW, - }; - #[cfg(not(target_os = "redox"))] - let _ = Timespec { - tv_sec, - tv_nsec: UTIME_OMIT, - }; - let _ = Timespec { tv_sec, tv_nsec: 0 }; - let _ = Timespec { - tv_sec, - tv_nsec: 999_999_999, - }; -} diff --git a/vendor/rustix/tests/time/y2038.rs b/vendor/rustix/tests/time/y2038.rs deleted file mode 100644 index 45a073d19..000000000 --- a/vendor/rustix/tests/time/y2038.rs +++ /dev/null @@ -1,77 +0,0 @@ -/// Test that `Timespec` and `Secs` support a 64-bit number of seconds, -/// avoiding the y2038 bug. -/// -/// The Rust Musl target and libc crate are currently using Musl 1.1. It is -/// expected to update to Musl 1.2 at some point, at which point it'll gain a -/// 64-bit `time_t`. -/// -/// 32-bit Android is [not y2038 compatible]. In theory we could use -/// `libc::syscall` and call the new syscalls ourselves, however that doesn't -/// seem worth the effort on a platform that will likely never support add -/// such support itself. -/// -/// [not y2038 compatible]: https://android.googlesource.com/platform/bionic/+/refs/heads/master/docs/32-bit-abi.md#is-32_bit-on-lp32-y2038 -#[cfg(not(all(target_env = "musl", target_pointer_width = "32")))] -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -#[cfg(not(all(target_os = "emscripten", target_pointer_width = "32")))] -#[test] -fn test_y2038() { - use rustix::time::{Secs, Timespec}; - - let tv_sec: i64 = 0; - let _ = Timespec { tv_sec, tv_nsec: 0 }; - let _: Secs = tv_sec; - - #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] - { - use rustix::time::Itimerspec; - - let _ = Itimerspec { - it_interval: Timespec { tv_sec, tv_nsec: 0 }, - it_value: Timespec { tv_sec, tv_nsec: 0 }, - }; - } -} - -#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] -#[test] -fn test_y2038_with_timerfd() { - use rustix::time::{ - timerfd_create, timerfd_gettime, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags, - TimerfdTimerFlags, Timespec, - }; - - let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap(); - - let set = Itimerspec { - it_interval: Timespec { - tv_sec: (1_u64 << 32) as _, - tv_nsec: 20, - }, - it_value: Timespec { - tv_sec: (1_u64 << 32) as _, - tv_nsec: 21, - }, - }; - let _old: Itimerspec = match timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set) { - Ok(i) => i, - - // On 32-bit and mips64 platforms, accept `EOVERFLOW`, meaning that - // y2038 support in `timerfd` APIs is not available on this platform - // or this version of the platform. - #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] - Err(rustix::io::Errno::OVERFLOW) => return, - - Err(e) => panic!("unexpected error: {:?}", e), - }; - - let new = timerfd_gettime(&fd).unwrap(); - - // The timer counts down. - assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); - assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); - assert!(new.it_value.tv_sec <= set.it_value.tv_sec); - assert!( - new.it_value.tv_nsec < set.it_value.tv_nsec || new.it_value.tv_sec < set.it_value.tv_sec - ); -} -- cgit v1.2.3