This can be done by simply changing the `\??\` prefix to `\\?\` and then attempting to convert to a user path.
Currently it simply strips off the prefix which could lead to the wrong path being returned (e.g. if it's not a drive path or if the path contains trailing spaces, etc).
Remove `all` in target_thread_local cfg
I think it was left there by mistake after the previous refactoring. I just came across it while rebasing to master.
Make sure the implementation of TcpStream::as_raw_fd is fully inlined
Currently the following function:
```rust
use std::os::fd::{AsRawFd, RawFd};
use std::net::TcpStream;
pub fn as_raw_fd(socket: &TcpStream) -> RawFd {
socket.as_raw_fd()
}
```
Is optimized to the following:
```asm
example::as_raw_fd:
push rax
call qword ptr [rip + <std::net::tcp::TcpStream as std::sys_common::AsInner<std::sys_common::net::TcpStream>>::as_inner@GOTPCREL]
mov rdi, rax
call qword ptr [rip + std::sys_common::net::TcpStream::socket@GOTPCREL]
mov rdi, rax
pop rax
jmp qword ptr [rip + _ZN73_$LT$std..sys..unix..net..Socket$u20$as$u20$std..os..fd..raw..AsRawFd$GT$9as_raw_fd17h633bcf7e481df8bbE@GOTPCREL]
```
I think it would make more sense to inline trivial functions used within `TcpStream::AsRawFd`.
Add 64-bit `time_t` support on 32-bit glibc Linux to `set_times`
Add support to `set_times` for 64-bit `time_t` on 32-bit glibc Linux platforms which have a 32-bit `time_t`. Split from #109773.
Tracking issue: #98245
If opening a directory with `FILE_LIST_DIRECTORY` access fails then we should try opening without requesting that access. We may still be able to delete it if it's empty or a link.
Restructure and rename std thread_local internals to make it less of a maze
Every time I try to work on std's thread local internals, it feels like I'm trying to navigate a confusing maze made of macros, deeply nested modules, and types with multiple names/aliases. Time to clean it up a bit.
This PR:
- Exports `Key` with its own name (`Key`), instead of `__LocalKeyInner`
- Uses `pub macro` to put `__thread_local_inner` into a (unstable, hidden) module, removing `#[macro_export]`, removing it from the crate root.
- Removes the `__` from `__thread_local_inner`.
- Removes a few unnecessary `allow_internal_unstable` features from the macros
- Removes the `libstd_thread_internals` feature. (Merged with `thread_local_internals`.)
- And removes it from the unstable book
- Gets rid of the deeply nested modules for the `Key` definitions (`mod fast` / `mod os` / `mod statik`).
- Turns a `#[cfg]` mess into a single `cfg_if`, now that there's no `#[macro_export]` anymore that breaks with `cfg_if`.
- Simplifies the `cfg_if` conditions to not repeat the conditions.
- Removes useless `normalize-stderr-test`, which were left over from when the `Key` types had different names on different platforms.
- Removes a seemingly unnecessary `realstd` re-export on `cfg(test)`.
This PR changes nothing about the thread local implementation. That's for a later PR. (Which should hopefully be easier once all this stuff is a bit cleaned up.)
Spelling library
Split per https://github.com/rust-lang/rust/pull/110392
I can squash once people are happy w/ the changes. It's really uncommon for large sets of changes to be perfectly acceptable w/o at least some changes.
I probably won't have time to respond until tomorrow or the next day
Fix `std` compilation error for wasi+atomics
Fix https://github.com/rust-lang/rust/issues/109727
It seems that the `unsupported/once.rs` module isn't meant to exist at the same time as the `futex` module, as they have conflicting definitions.
I've solved this by defining the `once` module only if `not(target_feature = "atomics")`.
The `wasm32-unknown-unknown` target [similarly only defines the `once` module if `not(target_feature = "atomics")`](01c4f31927/library/std/src/sys/wasm/mod.rs (L69-L70)).
As show in [this block of code](01c4f31927/library/std/src/sys_common/once/mod.rs (L10-L34)), the `sys::once` module doesn't need to exist if `all(target_arch = "wasm32", target_feature = "atomics")`.
NotFound errors:
* `ERROR_INVALID_DRIVE`: The system cannot find the drive specified
* `ERROR_BAD_NETPATH`: The network path was not found
* `ERROR_BAD_NET_NAME`: The network name cannot be found.
InvalidFilename:
* `ERROR_BAD_PATHNAME`: The specified path is invalid.
linkat() not available in the system headers of Solaris 10
I've installed rustup on x86_64-unknown-linux-gnu and would like to use the target sparcv9-sun-solaris. For this, I have built a gcc from the source code for cross-compiling to sparcv9-sun-solaris2.10 with system headers of Solaris 10.
With the following hello word example:
main.rs:
```rust
fn main() {
println!("Hello, world!");
}
```
I had a compilation error:
```
$ rustc -v --target sparcv9-sun-solaris -C linker=/opt/cross-solaris/gcc730/bin/sparcv9-sun-solaris2.10-gcc main.rs
error: linking with `/opt/cross-solaris/gcc730/bin/sparcv9-sun-solaris2.10-gcc` failed: exit status: 1
|
= note: "/opt/cross-solaris/gcc730/bin/sparcv9-sun-solaris2.10-gcc" "-m64" "/tmp/rustcgebYgj/symbols.o" "main.main.89363361-cgu.0.rcgu.o" "main.main.89363361-cgu.1.rcgu.o" "main.main.89363361-cgu.2.rcgu.o" "main.main.89363361-cgu.3.rcgu.o" "main.main.89363361-cgu.4.rcgu.o" "main.main.89363361-cgu.5.rcgu.o" "main.csypsau9u2r8348.rcgu.o" "-Wl,-z,ignore" "-L" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib" "-Wl,-Bstatic" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libstd-fa47c8247d587714.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libpanic_unwind-5c87bbe223e6c2a3.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libobject-d484934062ff9fbb.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libmemchr-e8dbd5835abcbf43.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libaddr2line-909ad09329bde2f9.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libgimli-4d74a3be929697ac.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/librustc_demangle-47cbe1d7f7271ae1.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libstd_detect-239fd2d25fb32a00.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libhashbrown-c4a7ce45fb9dec19.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libminiz_oxide-fa6bc3d9bfb4e402.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libadler-419f5a82ddd339a3.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/librustc_std_workspace_alloc-7672b378962c11be.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libunwind-0f9e07f0a032c000.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libcfg_if-ede7757c356dfb28.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/liblibc-808d56fbc668148a.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/liballoc-784767fe059ad3fe.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/librustc_std_workspace_core-aa31d7ef0556bbe1.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libcore-81d07df07db18847.rlib" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libcompiler_builtins-313a510e63006db2.rlib" "-Wl,-Bdynamic" "-lsocket" "-lposix4" "-lpthread" "-lresolv" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lsendfile" "-llgrp" "-L" "/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib" "-o" "main" "-nodefaultlibs"
= note: /opt/cross-solaris/gcc730/lib/gcc/sparcv9-sun-solaris2.10/7.3.0/../../../../sparcv9-sun-solaris2.10/bin/ld: warning: -z ignore ignored.
/home/dlaugt/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/sparcv9-sun-solaris/lib/libstd-fa47c8247d587714.rlib(std-fa47c8247d587714.std.5c42d2c1-cgu.0.rcgu.o): In function `std::sys::unix::fs:🔗:h3683dfbfbb4995cb':
/rustc/897e37553bba8b42751c67658967889d11ecd120/library/std/src/sys/unix/fs.rs:1407: undefined reference to `linkat'
collect2: error: ld returned 1 exit status
= help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
= note: use the `-l` flag to specify native libraries to link
= note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
```
linkat() is not available in the system headers of Solaris 10. The hello word example works fine when I build/use rust with this PR change.
don't splice from files into pipes in io::copy
This fixes potential data ordering issue where a write performed after a copy operation could become visible in the copy even though it signaled completion.
I assumed that by not setting `SPLICE_F_MOVE` we would be safe and the kernel would do a copy in kernel space and we could avoid the read-write syscall and copy-to/from-userspace costs. But apparently that flag only makes a difference when splicing from a pipe, but not when splicing into it.
Context: https://lkml.org/lkml/2023/2/9/673
Initial support for loongarch64-unknown-linux-gnu
Hi, We hope to add a new port in rust for LoongArch.
LoongArch intro
LoongArch is a RISC style ISA which is independently designed by Loongson
Technology in China. It is divided into two versions, the 32-bit version (LA32)
and the 64-bit version (LA64). LA64 applications have application-level
backward binary compatibility with LA32 applications. LoongArch is composed of
a basic part (Loongson Base) and an expanded part. The expansion part includes
Loongson Binary Translation (LBT), Loongson VirtualiZation (LVZ), Loongson SIMD
EXtension (LSX) and Loongson Advanced SIMD EXtension(LASX).
Currently the LA464 processor core supports LoongArch ISA and the Loongson
3A5000 processor integrates 4 64-bit LA464 cores. LA464 is a four-issue 64-bit
high-performance processor core. It can be used as a single core for high-end
embedded and desktop applications, or as a basic processor core to form an
on-chip multi-core system for server and high-performance machine applications.
Documentations:
ISA:
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
ABI:
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
More docs can be found at:
https://loongson.github.io/LoongArch-Documentation/README-EN.html
Since last year, we have locally adapted two versions of rust, rust1.41 and rust1.57, and completed the test locally.
I'm not sure if I'm submitting all the patches at once, so I split up the patches and here's one of the commits
Fix buffer overrun in bootstrap and (test-only) symlink_junction
I don't think these can be hit in practice, due to their inputs being valid paths. It's also not security-sensitive code, but just... bad vibes.
I think this is still not really the right way to do this (in terms of path correctness), but is no worse than it was.
r? `@ChrisDenton`
Use `getentropy()` instead of `/dev/urandom` on Emscripten
`/dev/urandom` is usually available on Emscripten, except when using
the special `NODERAWFS` filesystem backend, which replaces all normal
filesystem access with direct Node.js operations.
Since this filesystem backend directly access the filesystem on the
OS, it is not recommended to depend on `/dev/urandom`, especially
when trying to run the Wasm binary on OSes that are not Unix-based.
This can be considered a non-functional change, since Emscripten
implements `/dev/urandom` in the same way as `getentropy()` when not
linking with `-sNODERAWFS`.
Use random `HashMap` keys on Hermit
Initializing the keys with random data provided by the libOS avoids HashDOS attacks and similar issues.
CC `@stlankes`
Support TLS access into dylibs on Windows
This allows access to `#[thread_local]` in upstream dylibs on Windows by introducing a MIR shim to return the address of the thread local. Accesses that go into an upstream dylib will call the MIR shim to get the address of it.
`convert_tls_rvalues` is introduced in `rustc_codegen_ssa` which rewrites MIR TLS accesses to dummy calls which are replaced with calls to the MIR shims when the dummy calls are lowered to backend calls.
A new `dll_tls_export` target option enables this behavior with a `false` value which is set for Windows platforms.
This fixes https://github.com/rust-lang/rust/issues/84933.
`OsStr` has historically kept its implementation details private out of
concern for locking us into a specific encoding on Windows.
This is an alternative to #95290 which proposed specifying the encoding on Windows. Instead, this
only specifies that for cross-platform code, `OsStr`'s encoding is a superset of UTF-8 and defines
rules for safely interacting with it
At minimum, this can greatly simplify the `os_str_bytes` crate and every
arg parser that interacts with `OsStr` directly (which is most of those
that support invalid UTF-8).
fix typo in the creation of OpenOption for RustyHermit
Due to this typo we have to build a workaround for issue hermitcore/libhermit-rs#191.
RustyHermit is a tier 3 platform and backward compatibility does not have to be guaranteed.
Windows: make `Command` prefer non-verbatim paths
When spawning Commands, the path we use can end up being queried using `env::current_exe` (or the equivalent in other languages). Not all applications handle these paths properly therefore we should have a stronger preference for non-verbatim paths when spawning processes.
Implement read_buf for a few more types
Implement read_buf for TcpStream, Stdin, StdinLock, ChildStdout,
ChildStderr (and internally for AnonPipe, Handle, Socket), so
that it skips buffer initialization.
The other provided methods like read_to_string and read_to_end are
implemented in terms of read_buf and so benefit from the optimization
as well.
This commit also implements read_vectored and is_read_vectored where
applicable.
Distribute libntdll.a with windows-gnu toolchains
This allows the OS loader to load essential functions (e.g. read/write file) at load time instead of lazily doing so at runtime.
r? libs
Due to this typo we have to build a workaround for issue
hermitcore/libhermit-rs#191.
RustyHermit is a tier 3 platform and backward compatibility does
not have to be guaranteed.
`/dev/urandom` is usually available on Emscripten, except when using
the special `NODERAWFS` filesystem backend, which replaces all normal
filesystem access with direct Node.js operations.
Since this filesystem backend directly access the filesystem on the
OS, it is not recommended to depend on `/dev/urandom`, especially
when trying to run the Wasm binary on OSes that are not Unix-based.
This can be considered a non-functional change, since Emscripten
implements `/dev/urandom` in the same way as `getentropy()` when not
linking with `-sNODERAWFS`.
use `as_ptr` to determine the address of atomics
The PR #107736 renamed atomic `as_mut_ptr` to `as_ptr`. Consequently, the futex implementation of the tier-3 platform `RutyHermit` has to use this new interface. In addition, this PR removes also an unused import.
This allows removing all the platform-dependent code from `library/std/src/thread/local.rs` and `library/std/src/thread/mod.rs`
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Split the __thread_local_inner macro to make it more readable. Also move
everything to crate::sys::common::thread_local.
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Move __thread_local_inner macro in crate:🧵:local to crate::sys.
Currently, the tidy check does not fail for `library/std/src/thread/local.rs` even though it contains platform specific code. This is beacause target_family did not exist at the time the tidy checks were written [1].
[1]: https://github.com/rust-lang/rust/pull/105861#discussion_r1125841678
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Implement read_buf for TcpStream, Stdin, StdinLock, ChildStdout,
ChildStderr (and internally for AnonPipe, Handle, Socket), so
that it skips buffer initialization.
The other provided methods like read_to_string and read_to_end are
implemented in terms of read_buf and so benefit from the optimization
as well.
This commit also implements read_vectored and is_read_vectored where
applicable.
Add vectored positioned I/O on Unix
Add methods for vectored I/O with an offset on `File` for `unix` under `#![feature(unix_file_vectored_at)]`.
The new methods are wrappers around `preadv` and `pwritev`.
Tracking issue: #89517
Add support for QNX Neutrino to standard library
This change:
- adds standard library support for QNX Neutrino (7.1).
- upgrades `libc` to version `0.2.139` which supports QNX Neutrino
`@gh-tr`
⚠️ Backtraces on QNX require https://github.com/rust-lang/backtrace-rs/pull/507 which is not yet merged! (But everything else works without these changes) ⚠️
Tested mainly with a x86_64 virtual machine (see qnx-nto.md) and partially with an aarch64 hardware (some tests fail due to constrained resources).
[stdio][windows] Use MBTWC and WCTMB
`MultiByteToWideChar` and `WideCharToMultiByte` are extremely well optimized, and therefore should probably be used when we know we can (specifically in the Windows stdio stuff).
Fixes#107092
add support of RustyHermit's BSD socket layer
RustyHermit is a tier 3 platform and publishes a new kernel interface. The new version supports a common BSD socket layer. By supporting this interface, the implementation of `std` can be harmonized to other operating systems. In `sys_common/mod.rs` we remove only a special case for RustyHermit. All changes are done in the RustyHermit specific directories.
To realize this socket layer, the handling of file descriptors is also harmonized to other operating systems.
RustHermit publishs a new kernel interface and supports
a common BSD socket layer. By supporting this interface,
the implementation can be harmonized to other operating systems.
To realize this socket layer, the handling of file descriptors
is also harmonized to other operating systems.
As reported in sunfishcode/is-terminal#18, there are situations where
`GetFileInformationByHandleEx` can write a file name length that is
longer than the provided buffer. To avoid deferencing memory past the
end of the buffer, use a bounds-checked function to form a slice to
the buffer and handle the out-of-bounds case.
This ports the fix from sunfishcode/is-terminal#19 to std's `is_terminal`
implementation.
Windows: Quote more batch file arguments
Make sure to always quote batch file arguments that contain command prompt special characters.
Additionally add `/d` command line parameter to disable any autorun scripts that may change the way variable expansion works. This makes it more consistent across systems and may help avoid surprises.
## Background Info
[`CreateProcess`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw) with the `lpApplicationName` set can only be used to run `.exe` files and not script files such as `.bat`. However, for historical reasons, we do have special handling so that `.bat` files will be correctly run with `cmd.exe` as the application.
In Windows, command line arguments are passed as a single string (not an array). Applications can parse this string however they like but most follow the standard MSVC C/C++ convention. But `cmd.exe` uses different argument parsing rules to other Windows programs (because it emulates old DOS). This PR aims to help smooth over some of the differences.
r? libs
Make sure to quote batch file arguments that contain command prompt special characters.
Additionally add `/d` command line parameter to disable any commands that may change the way variable expansion works.
Optimize `LazyLock` size
The initialization function was unnecessarily stored separately from the data to be initialized. Since both cannot exist at the same time, a `union` can be used, with the `Once` acting as discriminant. This unfortunately requires some extra methods on `Once` so that `Drop` can be implemented correctly and efficiently.
`@rustbot` label +T-libs +A-atomic
Added another error to be processed in fallback
This pull request addresses the problem of Rust not being able to read file/directory metadata because the current user doesn't have permission to read the file and are thus inaccessible.
One particular example is `System Volume Information`. But any example can be made by having a file/directory, which the current user can't access even though the system does allow to view the metadata, which is handled by the fallback.
The fallback exists to get the metadata but it was limited to one error type. Having added ERROR_ACCESS_DENIED per Chris Denton's suggestion, file/directory properties are now properly read.
Solution suggested by Chris Denton https://github.com/nushell/nushell/issues/6857#issuecomment-1426847135
Use associated items of `char` instead of freestanding items in `core::char`
The associated functions and constants on `char` have been stable since 1.52 and the freestanding items have soft-deprecated since 1.62 (https://github.com/rust-lang/rust/pull/95566). This PR ~~marks them as "deprecated in future", similar to the integer and floating point modules (`core::{i32, f32}` etc)~~ replaces all uses of `core::char::*` with `char::*` to prepare for future deprecation of `core::char::*`.
Stop at the first `NULL` argument when iterating `argv`
Some C commandline parsers (e.g. GLib and Qt) are replacing already handled arguments in `argv` with `NULL` and move them to the end. That means that `argc` might be bigger than the actual number of non-`NULL` pointers in `argv` at this point.
To handle this we simply stop iterating at the first `NULL` argument.
`argv` is also guaranteed to be `NULL`-terminated so any non-`NULL` arguments after the first `NULL` can safely be ignored.
Fixes https://github.com/rust-lang/rust/issues/105999
Use `__wasilibc_get_environ()` to read the environment variable list
from wasi-libc instead of using `environ`. `environ` is a global
variable which effectively requires wasi-libc to initialize the
environment variables eagerly, and `__wasilibc_get_environ()` is
specifically designed to be an alternative that lets wasi-libc
intiailize its environment variables lazily.
This should have the side effect of fixing at least some of the cases
of #107635.
library/std/sys_common: Define MIN_ALIGN for m68k-unknown-linux-gnu
This PR adds the missing definition of MIN_ALIGN for the m68k-unknown-linux target.
Avoid __cxa_thread_atexit_impl on Emscripten
- Fixes https://github.com/rust-lang/rust/issues/91628.
- Fixes https://github.com/emscripten-core/emscripten/issues/15722.
See discussion in both issues.
The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid.
Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway.
Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++.
Do not use box syntax in `std`
See #94970 and #49733. About half of the `box` instances in `std` do not even need to allocate, the other half can simply be replaced with `Box::new`.
`@rustbot` label +T-libs
r? rust-lang/libs
Remove various double spaces in the libraries.
I was just pretty bothered by this when reading the source for a function, and was suggested to check if this happened elsewhere.
Stop probing for statx unless necessary
As is the current toy program:
fn main() -> std::io::Result<()> {
use std::fs;
let metadata = fs::metadata("foo.txt")?;
assert!(!metadata.is_dir());
Ok(())
}
... observed under strace will issue:
[snip]
statx(0, NULL, AT_STATX_SYNC_AS_STAT, STATX_ALL, NULL) = -1 EFAULT (Bad address) statx(AT_FDCWD, "foo.txt", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=0, ...}) = 0
While statx is not necessarily always present, checking for it can be delayed to the first error condition. Said condition may very well never happen, in which case the check got avoided altogether.
Note this is still suboptimal as there still will be programs issuing it, but bulk of the problem is removed.
Tested by forbidding the syscall for the binary and observing it correctly falls back to newfstatat.
While here tidy up the commentary, in particular by denoting some problems with the current approach.
- Fixes https://github.com/rust-lang/rust/issues/91628.
- Fixes https://github.com/emscripten-core/emscripten/issues/15722.
See discussion in both issues.
The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid.
Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway.
Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++.
r? @alexcrichton
As is the current toy program:
fn main() -> std::io::Result<()> {
use std::fs;
let metadata = fs::metadata("foo.txt")?;
assert!(!metadata.is_dir());
Ok(())
}
... observed under strace will issue:
[snip]
statx(0, NULL, AT_STATX_SYNC_AS_STAT, STATX_ALL, NULL) = -1 EFAULT (Bad address)
statx(AT_FDCWD, "foo.txt", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=0, ...}) = 0
While statx is not necessarily always present, checking for it can be
delayed to the first error condition. Said condition may very well never
happen, in which case the check got avoided altogether.
Note this is still suboptimal as there still will be programs issuing
it, but bulk of the problem is removed.
Tested by forbidding the syscall for the binary and observing it
correctly falls back to newfstatat.
While here tidy up the commentary, in particular by denoting some
problems with the current approach.
Even where actually running processes is not supported.
Needed for the next commit.
The manual trait implementations now belong on ExitStatusError,
which still can't exist.
Unify id-based thread parking implementations
Multiple platforms currently use thread-id-based parking implementations (NetBSD and SGX[^1]). Even though the strategy does not differ, these are duplicated for each platform, as the id is encoded into an atomic thread variable in different ways for each platform.
Since `park` is only called by one thread, it is possible to move the thread id into a separate field. By ensuring that the field is only written to once, before any other threads access it, these accesses can be unsynchronized, removing any restrictions on the size and niches of the thread id.
This PR also renames the internal `thread_parker` modules to `thread_parking`, as that name now better reflects their contents. I hope this does not add too much reviewing noise.
r? `@m-ou-se`
`@rustbot` label +T-libs
[^1]: SOLID supports this as well, I will switch it over in a follow-up PR.
kmc-solid: Fix memory ordering in thread operations
Fixes two memory ordering issues in the thread state machine (`ThreadInner::lifecycle`) of the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets.
1. When detaching a thread that is still running (i.e., the owner updates `lifecycle` first, and the child updates it next), the first update did not synchronize-with the second update, resulting in a data race between the first update and the deallocation of `ThreadInner` by the child thread.
2. When joining on a thread, the joiner has to pass its own task ID to the joinee in order to be woken up later, but in doing so, it did not synchronize-with the read operation, creating possible sequences of execution where the joinee wakes up an incorrect or non-existent task.
Both issue are theoretical and most likely have never manifested in practice because of the stronger guarantees provided by the Arm memory model (particularly due to its barrier-based definition). Compiler optimizations could have subverted this, but the inspection of compiled code did not reveal such optimizations taking place.
Bump master bootstrap compiler
This PR bumps the bootstrap compiler to the beta created earlier this week, cherry-picks the stabilization version number updates, and updates the `cfg(bootstrap)`s.
r? `@Mark-Simulacrum`
available_parallelism: Gracefully handle zero value cfs_period_us
There seem to be some scenarios where the cgroup cpu quota field `cpu.cfs_period_us` can contain `0`. This field is used to determine the "amount" of parallelism suggested by the function `std:🧵:available_parallelism`
A zero value of this field cause a panic when `available_parallelism()` is invoked. This issue was detected by the call from binaries built by `cargo test`. I really don't feel like `0` is a good value for `cpu.cfs_period_us`, but I also don't think applications should panic if this value is seen.
This panic started happening with rust 1.64.0.
This case is gracefully handled by other projects which read this information: [num_cpus](e437b9d908/src/linux.rs (L207-L210)), [ninja](https://github.com/ninja-build/ninja/pull/2174/files), [dotnet](c4341d45ac/src/coreclr/pal/src/misc/cgroup.cpp (L481-L483))
Before this change, running `cargo test` in environments configured as described above would trigger this panic:
```
$ RUST_BACKTRACE=1 cargo test
Finished test [unoptimized + debuginfo] target(s) in 3.55s
Running unittests src/main.rs (target/debug/deps/x-9a42e145aca2934d)
thread 'main' panicked at 'attempt to divide by zero', library/std/src/sys/unix/thread.rs:546:70
stack backtrace:
0: rust_begin_unwind
1: core::panicking::panic_fmt
2: core::panicking::panic
3: std::sys::unix:🧵:cgroups::quota
4: std::sys::unix:🧵:available_parallelism
5: std:🧵:available_parallelism
6: test::helpers::concurrency::get_concurrency
7: test::console::run_tests_console
8: test::test_main
9: test::test_main_static
10: x::main
at ./src/main.rs:1:1
11: core::ops::function::FnOnce::call_once
at /tmp/rust-1.64-1.64.0-1/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: test failed, to rerun pass '--bin x'
```
I've tested this change in an environment which has the bad (questionable?) setup and rebuilding the test executable against a fixed std library fixes the panic.
Use correct clock in `park_timeout` on Horizon
Horizon does not support using `CLOCK_MONOTONIC` with condition variables, so use the system time instead.
Some C commandline parsers (e.g. GLib and Qt) are replacing already
handled arguments in `argv` with `NULL` and move them to the end. That
means that `argc` might be bigger than the actual number of non-`NULL`
pointers in `argv` at this point.
To handle this we simply stop iterating at the first `NULL` argument.
`argv` is also guaranteed to be `NULL`-terminated so any non-`NULL`
arguments after the first `NULL` can safely be ignored.
Fixes https://github.com/rust-lang/rust/issues/105999
Use a more efficient `Once` on platforms without threads
The current implementation uses an atomic queue and spins rather than panicking when calling `call_once` recursively. Since concurrency is not supported on platforms like WASM, `Once` can be implemented much more efficiently using just a single non-atomic state variable.
fs: Fix#50619 (again) and add a regression test
Bug #50619 was fixed by adding an end_of_stream flag in #50630.
Unfortunately, that fix only applied to the readdir_r() path. When I
switched Linux to use readdir() in #92778, I inadvertently reintroduced
the bug on that platform. Other platforms that had always used
readdir() were presumably never fixed.
This patch enables end_of_stream for all platforms, and adds a
Linux-specific regression test that should hopefully prevent the bug
from being reintroduced again.
Allow blocking `Command::output`
### Problem
Currently, `Command::output` is internally implemented using `Command::spawn`. This is problematic because some targets (like UEFI) do not actually support multitasking and thus block while the program is executing. This coupling does not make much sense as `Command::output` is supposed to block until the execution is complete anyway and thus does not need to rely on a non-blocking `Child` or any other intermediate.
### Solution
This PR moves the implementation of `Command::output` to `std::sys`. This means targets can choose to implement only `Command::output` without having to implement `Command::spawn`.
### Additional Information
This was originally conceived when working on https://github.com/rust-lang/rust/pull/100316. Currently, the only target I know about that will benefit from this change is UEFI.
This PR can also be used to implement more efficient `Command::output` since the intermediate `Process` is not actually needed anymore, but that is outside the scope of this PR.
Since this is not a public API change, I'm not sure if an RFC is needed or not.
Use more LFS functions.
On Linux, use mmap64, open64, openat64, and sendfile64 in place of their non-LFS counterparts.
This is relevant to #94173.
With these changes (together with rust-lang/backtrace-rs#501), the simple binaries I produce with rustc seem to have no non-LFS functions, so maybe #94173 is fixed. But I can't be sure if I've missed something and maybe some non-LFS functions could sneak in somehow.
Bug #50619 was fixed by adding an end_of_stream flag in #50630.
Unfortunately, that fix only applied to the readdir_r() path. When I
switched Linux to use readdir() in #92778, I inadvertently reintroduced
the bug on that platform. Other platforms that had always used
readdir() were presumably never fixed.
This patch enables end_of_stream for all platforms, and adds a
Linux-specific regression test that should hopefully prevent the bug
from being reintroduced again.
This allows decoupling `Command::spawn` and `Command::output`. This is
useful for targets which do support launching programs in blocking mode
but do not support multitasking (Eg: UEFI).
This was originally conceived when working on https://github.com/rust-lang/rust/pull/100316
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Avoid heap allocation when truncating thread names
Ensure that heap allocation does not occur in a thread until `std::thread` is ready. This fixes issues with custom allocators that call `std:🧵:current()`, since doing so prematurely initializes `THREAD_INFO` and causes the following `thread_info::set()` to fail.
Reimplement std's thread parker on top of events on SGX
Mutex and Condvar are being replaced by more efficient implementations, which need thread parking themselves (see #93740). Therefore, the generic `Parker` needs to be replaced on all platforms where the new lock implementation will be used.
SGX enclaves have a per-thread event state, which allows waiting for and setting specific bits. This is already used by the current mutex implementation. The thread parker can however be much more efficient, as it only needs to store the `TCS` address of one thread. This address is stored in a state variable, which can also be set to indicate the thread was already notified.
`park_timeout` does not guard against spurious wakeups like the current condition variable does. This is allowed by the API of `Parker`, and I think it is better to let users handle these wakeups themselves as the guarding is quite expensive and might not be necessary.
`@jethrogb` as you wrote the initial SGX support for `std`, I assume you are the target maintainer? Could you help me test this, please? Lacking a x86_64 chip, I can't run SGX.
Add `read_to_end` method for `sys::{target}::pipe::AnonPipe`. This allows
having a more optimized version of `read_to_end` for ChildStdout.
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
kmc-solid: `std::sys` code maintenance
Includes a set of changes to fix the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets and make some other improvements.
- Address `fuzzy_provenance_casts` by using `expose_addr` and `from_exposed_addr` for pointer-integer casts
- Add a stub implementation of `is_terminal` (#98070)
- Address `unused_imports` and `unused_unsafe`
- Stop doing `Box::from_raw(&*(x: Box<T>) as *const T as *mut T)`
Ensure that heap allocation does not occur in a thread until std::thread
is ready. This fixes issues with custom allocators that call
std:🧵:current(), since doing so prematurely initializes
THREAD_INFO and causes the following thread_info::set() to fail.
On Linux, use mmap64, open64, openat64, and sendfile64 in place of their
non-LFS counterparts.
This is relevant to #94173.
With these changes (together with rust-lang/backtrace-rs#501), the
simple binaries I produce with rustc seem to have no non-LFS functions,
so maybe #94173 is fixed. But I can't be sure if I've missed something
and maybe some non-LFS functions could sneak in somehow.
Pass on null handle values to child process
Fixes#101645
In Windows, stdio handles are (semantically speaking) `Option<Handle>` where `Handle` is a non-zero value. When spawning a process with `Stdio::Inherit`, Rust currently turns zero values into `-1` values. This has the unfortunate effect of breaking console subprocesses (which typically need stdio) that are spawned from gui applications (that lack stdio by default) because the console process won't be assigned handles from the newly created console (as they usually would in that situation). Worse, `-1` is actually [a valid handle](https://doc.rust-lang.org/std/os/windows/io/struct.OwnedHandle.html) which means "the current process". So if a console process, for example, waits on stdin and it has a `-1` value then the process will end up waiting on itself.
This PR fixes it by propagating the nulls instead of converting them to `-1`.
While I think the current behaviour is a mistake, changing it (however justified) is an API change so I think this PR should at least have some input from t-libs-api. So choosing at random...
r? `@joshtriplett`
Commit 77005950f0 implemented masking of
FileType to fix an issue[^1] in the semantic of FileType comparison.
This commit introduces masking to Hash to maintain the invariant that
x == y => hash(x) == hash(y).
[^1]: https://github.com/rust-lang/rust/issues/104900
When spawning Commands, the path we use can end up being queried using `env::current_exe` (or the equivalent in other languages). Not all applications handle these paths properly therefore we should have a stronger preference for non-verbatim paths when spawning processes.
Pointer-integer casts are required for conversion between `EXINF` (ITRON
task entry point parameter) and `*const ThreadInner`. Addresses the
deny-level lint `fuzzy_provenance_casts`.
Extract WStrUnits to sys_common::wstr
This commit extracts WStrUnits from sys::windows::args to sys_common::wstr. This allows using the same structure for other targets which use wtf8 (example UEFI).
This was originally a part of https://github.com/rust-lang/rust/pull/100316
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
This commit extracts WStrUnits from sys::windows::args to sys_common::wstr. This
allows using the same structure for other targets which use wtf8 (example UEFI).
This was originally a part of https://github.com/rust-lang/rust/pull/100316
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
There seem to be some scenarios where `cpu.cfs_period_us` can contain `0`
This causes a panic when calling `std:🧵:available_parallelism()` as is done so
from binaries built by `cargo test`, which was how the issue was
discovered. I don't feel like `0` is a good value for `cpu.cfs_period_us`, but I
also don't think applications should panic if this value is seen.
This case is handled by other projects which read this information:
- num_cpus: e437b9d908/src/linux.rs (L207-L210)
- ninja: https://github.com/ninja-build/ninja/pull/2174/files
- dotnet: c4341d45ac/src/coreclr/pal/src/misc/cgroup.cpp (L481-L483)
Before this change, this panic could be seen in environments setup as described
above:
```
$ RUST_BACKTRACE=1 cargo test
Finished test [unoptimized + debuginfo] target(s) in 3.55s
Running unittests src/main.rs (target/debug/deps/x-9a42e145aca2934d)
thread 'main' panicked at 'attempt to divide by zero', library/std/src/sys/unix/thread.rs:546:70
stack backtrace:
0: rust_begin_unwind
1: core::panicking::panic_fmt
2: core::panicking::panic
3: std::sys::unix:🧵:cgroups::quota
4: std::sys::unix:🧵:available_parallelism
5: std:🧵:available_parallelism
6: test::helpers::concurrency::get_concurrency
7: test::console::run_tests_console
8: test::test_main
9: test::test_main_static
10: x::main
at ./src/main.rs:1:1
11: core::ops::function::FnOnce::call_once
at /tmp/rust-1.64-1.64.0-1/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: test failed, to rerun pass '--bin local-rabmq-amqpprox'
```
I've tested this change in an environment which has the bad setup and
rebuilding the test executable against a fixed std library fixes the
panic.
Truncate thread names on Linux and Apple targets
These targets have system limits on the thread names, 16 and 64 bytes
respectively, and `pthread_setname_np` returns an error if the name is
longer. However, we're not in a context that can propagate errors when
we call this, and we used to implicitly truncate on Linux with `prctl`,
so now we manually truncate these names ahead of time.
r? ``````@thomcc``````
Don't link to `libresolv` in libstd on Darwin
Currently we link `libresolv` into every Rust program on apple targets despite never using it (as of https://github.com/rust-lang/rust/pull/44965). I had thought we needed this for `getaddrinfo` or something, but we do not / cannot safely use it.
I'd like to fix this for `libiconv` too (the other library we pull in. that's harder since it's coming in through `libc`, which is https://github.com/rust-lang/libc/pull/2944)).
---
This may warrant release notes. I'm not sure but I've added the flag regardless -- It's a change to the list of dylibs every Rust program pulls in, so it's worth mentioning.
It's pretty unlikely anybody was relying on this being pulled in, and `std` does not guarantee that it will link (and thus transitively provide access to) any particular system library -- anybody relying on that behavior would already be broken when dynamically linking std. That is, there's an outside chance something will fail to link on macOS and iOS because it was accidentally relying on our unnecessary dependency.
(If that *does* happen, that project could be easily fixed by linking libresolv explicitly on those platforms, probably via `#[link(name = "resolv")] extern {}`,` -Crustc-link-lib=resolv`, `println!("cargo:rustc-link-lib=resolv")`, or one of several places in `.config/cargo.toml`)
---
I'm also going to preemptively add the nomination for discussing this in the libs meeting. Basically: Do we care about programs that assume we will bring libraries in that we do not use. `libresolv` and `libiconv` on macOS/iOS are in this camp (`libresolv` because we used to use it, and `libiconv` because the `libc` crate was unintentionally(?) pulling it in to every Rust program).
I'd like to remove them both, but this may cause link issues programs that are relying on `std` to depend on them transitively. (Relying on std for this does not work in all build configurations, so this seems very fragile, and like a use case we should not support).
More generally, IMO we should not guarantee the specific set of system-provided libraries we use (beyond what is implied by an OS version requirement), which means we'd be free to remove this cruft.
kmc-solid: Handle errors returned by `SOLID_FS_ReadDir`
Fixes the issue where the `std::fs::ReadDir` implementaton of the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets silently suppressed errors returned by the underlying `SOLID_FS_ReadDir` system function. The new implementation correctly handles all cases:
- `SOLID_ERR_NOTFOUND` indicates the end of directory stream.
- `SOLID_ERR_OK` + non-empty `d_name` indicates success.
- Some old filesystem drivers may return `SOLID_ERR_OK` + empty `d_name` to indicate the end of directory stream.
- Any other negative values (per ITRON convention) represent an error.
Eliminate 280-byte memset from ReadDir iterator
This guy:
1536ab1b38/library/std/src/sys/unix/fs.rs (L589)
It turns out `libc::dirent64` is quite big—https://docs.rs/libc/0.2.135/libc/struct.dirent64.html. In #103135 this memset accounted for 0.9% of the runtime of iterating a big directory.
Almost none of the big zeroed value is ever used. We memcpy a tiny prefix (19 bytes) into it, and then read just 9 bytes (`d_ino` and `d_type`) back out. We can read exactly those 9 bytes we need directly from the original entry_ptr instead.
## History
This code got added in #93459 and tweaked in #94272 and #94750.
Prior to #93459, there was no memset but a full 280 bytes were being copied from the entry_ptr.
<table><tr><td>copy 280 bytes</td></tr></table>
This was not legal because not all of those bytes might be initialized, or even allocated, depending on the length of the directory entry's name, leading to a segfault. That PR fixed the segfault by creating a new zeroed dirent64 and copying just the guaranteed initialized prefix into it.
<table><tr><td>memset 280 bytes</td><td>copy 19 bytes</td></tr></table>
However this was still buggy because it used `addr_of!((*entry_ptr).d_name)`, which is considered UB by Miri in the case that the full extent of entry_ptr is not in bounds of the same allocation. (Arguably this shouldn't be a requirement, but here we are.)
The UB got fixed by #94272 by replacing `addr_of` with some pointer manipulation based on `offset_from`, but still fundamentally the same operation.
<table><tr><td>memset 280 bytes</td><td>copy 19 bytes</td></tr></table>
Then #94750 noticed that only 9 of those 19 bytes were even being used, so we could pick out only those 9 to put in the ReadDir value.
<table><tr><td>memset 280 bytes</td><td>copy 19 bytes</td><td>copy 9 bytes</td></tr></table>
After my PR we just grab the 9 needed bytes directly from entry_ptr.
<table><tr><td>copy 9 bytes</td></tr></table>
The resulting code is more complex but I believe still worthwhile to land for the following reason. This is an extremely straightforward thing to accomplish in C and clearly libc assumes that; literally just `entry_ptr->d_name`. The extra work in comparison to accomplish it in Rust is not an example of any actual safety being provided by Rust. I believe it's useful to have uncovered that and think about what could be done in the standard library or language to support this obvious operation better.
## References
- https://man7.org/linux/man-pages/man3/readdir.3.html
Reduce false positives in msys2 detection
Currently msys2 will be detected by getting the file path and looking to see if it contains the substrings "msys-" and "-ptr" (or "cygwin-" and "-pty"). This risks false positives, especially with filesystem files and if `GetFileInformationByHandleEx` returns a [full path](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryinformationfile#remarks).
This PR adds a check to see if the handle is a pipe before doing the substring search. Additionally, for "msys2-" or "cygwin-" it only checks if the file name starts with the substring rather than looking at the whole path.
These targets have system limits on the thread names, 16 and 64 bytes
respectively, and `pthread_setname_np` returns an error if the name is
longer. However, we're not in a context that can propagate errors when
we call this, and we used to implicitly truncate on Linux with `prctl`,
so now we manually truncate these names ahead of time.
Previously, the signal mask is always reset when a child process is
started. This breaks tools like `nohup` which expect `SIGHUP` to be
blocked.
With this change, the default behavior changes to inherit the signal mask.
This also changes the signal disposition for `SIGPIPE` to only be
changed if the `#[unix_sigpipe]` attribute isn't set.
std: use `sync::Mutex` for internal statics
Since `sync::Mutex` is now `const`-constructible, it can be used for internal statics, removing the need for `sys_common::StaticMutex`. This adds some extra allocations on platforms which need to box their mutexes (currently SGX and some UNIX), but these will become unnecessary with the lock improvements tracked in #93740.
I changed the program argument implementation on Hermit, it does not need `Mutex` but can use atomics like some UNIX systems (ping `@mkroening` `@stlankes).`
Use semaphores for thread parking on Apple platforms
Currently we use a mutex-condvar pair for thread parking on Apple systems. Unfortunately, `pthread_cond_timedwait` uses the real-time clock for measuring time, which causes problems when the system time changes. The parking implementation in this PR uses a semaphore instead, which measures monotonic time by default, avoiding these issues. As a further benefit, this has the potential to improve performance a bit, since `unpark` does not need to wait for a lock to be released.
Since the Mach semaphores are poorly documented (I could not find availability or stability guarantees for instance), this uses a [dispatch semaphore](https://developer.apple.com/documentation/dispatch/dispatch_semaphore?language=objc) instead. While it adds a layer of indirection (it uses Mach semaphores internally), the overhead is probably negligible.
Tested on macOS 12.5.
r? ``````@thomcc``````
Add `IsTerminal` trait to determine if a descriptor or handle is a terminal
The UNIX implementation uses `isatty`. The Windows implementation uses
the same logic the `atty` crate uses, including the hack needed to
detect msys terminals.
Implement this trait for `Stdin`/`Stdout`/`Stderr`/`File` on all
platforms. On Unix, implement it for `BorrowedFd`/`OwnedFd`. On Windows,
implement it for `BorrowedHandle`/`OwnedHandle`.
Based on https://github.com/rust-lang/rust/pull/91121
Co-authored-by: Matt Wilkinson <mattwilki17@gmail.com>
Rather than referencing a slice's pointer and then creating a new slice
with a longer length, offset from the base structure pointer instead.
This makes some choices of Rust semantics happier.
The UNIX and WASI implementations use `isatty`. The Windows
implementation uses the same logic the `atty` crate uses, including the
hack needed to detect msys terminals.
Implement this trait for `File` and for `Stdin`/`Stdout`/`Stderr` and
their locked counterparts on all platforms. On UNIX and WASI, implement
it for `BorrowedFd`/`OwnedFd`. On Windows, implement it for
`BorrowedHandle`/`OwnedHandle`.
Based on https://github.com/rust-lang/rust/pull/91121
Co-authored-by: Matt Wilkinson <mattwilki17@gmail.com>
sync thread_local key conditions exactly with what the macro uses
This makes the `cfg` in `mod.rs` syntactically the same as those in `local.rs`.
I don't think this should actually change anything, but seems better to be consistent?
I looked into this due to https://github.com/rust-lang/rust/issues/102549, but this PR would make it *less* likely that `__OsLocalKeyInner` is going to get provided, so this cannot help with that issue.
r? `@thomcc`
More dupe word typos
I only picked those changes (from the regex search) that I am pretty certain doesn't change meaning and is just a typo fix. Do correct me if any fix is undesirable and I can revert those. Thanks.
impl AsFd and AsRawFd for io::{Stdin, Stdout, Stderr}, not the sys versions
https://github.com/rust-lang/rust/pull/100892 implemented AsFd for the
sys versions, rather than for the public types. Change the
implementations to apply to the public types.
openbsd: don't reallocate a guard page on the stack.
the kernel currently enforce that a stack is immutable. calling mmap(2) or mprotect(2) to change it will result in EPERM, which generate a panic!().
so just do like for Linux, and trust the kernel to do the right thing.
Optimize TLS on Windows
This implements the suggestion in the current TLS code to embed the linked list of destructors in the `StaticKey` structure to save allocations. Additionally, locking is avoided when no destructor needs to be run. By using one Windows-provided `Once` per key instead of a global lock, locking is more finely-grained (this unblocks #100579).
Allow compiling the `wasm32-wasi` std library with atomics
The issue #102157 demonstrates how currently the `-Z build-std` option will fail when re-compiling the standard library with `RUSTFLAGS` like `RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C link-args=--shared-memory"`. This change attempts to resolve those build issues by depending on the the WebAssembly `futex` module and providing an implementation for `env_lock`. Fixes#102157.
fs::get_path solarish version.
similar to linux, albeit there is no /proc/self notion on solaris
based system thus flattening the difference for simplification sake.
Copying the approach of the Unix target, this change uses the standard
`RwLock` to protect against concurrent access of libc's environment.
This locking is only enabled when WebAssembly's `atomics` feature is
also enabled.
The issue #102157 demonstrates how currently the `-Z build-std` option
will fail when re-compiling the standard library with `RUSTFLAGS` like
`RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C
link-args=--shared-memory"`. This change attempts to resolve those build
issues by depending on the the WebAssembly `futex` module and providing
an implementation for `env_lock`. Fixes#102157.
Rollup of 8 pull requests
Successful merges:
- #101118 (fs::get_mode enable getting the data via fcntl/F_GETFL on major BSD)
- #102072 (Add `ptr::Alignment` type)
- #102799 (rustdoc: remove hover gap in file picker)
- #102820 (Show let-else suggestion on stable.)
- #102829 (rename `ImplItemKind::TyAlias` to `ImplItemKind::Type`)
- #102831 (Don't use unnormalized type in `Ty::fn_sig` call in rustdoc `clean_middle_ty`)
- #102834 (Remove unnecessary `lift`/`lift_to_tcx` calls from rustdoc)
- #102838 (remove cfg(bootstrap) from Miri)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
the kernel currently enforce that a stack is immutable. calling mmap(2) or
mprotect(2) to change it will result in EPERM, which generate a panic!().
so just do like for Linux, and trust the kernel to do the right thing.
Reduce CString allocations in std as much as possible
Currently, every operation involving paths in `fs` allocates memory to hold the path before sending it through the syscall. This PR instead uses a stack allocation (chosen size is somewhat arbitrary) when the path is short before falling back to heap allocations for long paths.
Benchmarks show that the stack allocation is ~2x faster for short paths:
```
test sys::unix::fd::tests::bench_heap_path_alloc ... bench: 34 ns/iter (+/- 2)
test sys::unix::fd::tests::bench_stack_path_alloc ... bench: 15 ns/iter (+/- 1)
```
For long paths, I couldn't find any measurable difference.
---
I'd be surprised if I was the first to think of this, so I didn't fully flush out the PR. If this change is desirable, I'll make use of `run_with_cstr` across all platforms in every fs method (currently just unix open for testing). I also added an `impl From<FromBytesWithNulError>` which is presumably a no-no (or at least needs to be done in another PR).
---
Also see https://github.com/nix-rust/nix/pull/1655 with a bunch of discussion where I'm doing something similar.
Add `AsFd` implementations for stdio lock types on WASI.
This mirrors the implementations on Unix platforms, and also mirrors the existing `AsRawFd` impls.
This is similar to #100892, but is for the `*Lock` types.