While a bare "NUL" *should* be redirected to the NUL device, especially in this simple case, let's be explicit that we aren't opening a file called "NUL" and instead open it directly.
This will also set a good example for people copying std code.
Remove asmjs
Fulfills [MCP 668](https://github.com/rust-lang/compiler-team/issues/668).
`asmjs-unknown-emscripten` does not work as-specified, and lacks essential upstream support for generating asm.js, so it should not exist at all.
Xous as an operating system is compiled with gcc-type personalities when
it comes to unwinding. This enables unwinding inside panics on Xous,
which enables Rust tests.
Signed-off-by: Sean Cross <sean@xobs.io>
Removes the private type `std::sys::solid::net::FileDesc`, replacing its
only usage in `std::sys::solid::net::Socket` with `std::os::solid::io::
OwnedFd`.
Time in UNIX system calls counts from the epoch, 1970-01-01. The timespec
struct used in various system calls represents this as a number of seconds and
a number of nanoseconds. Nanoseconds are required to be between 0 and
999_999_999, because the portion outside that range should be represented in
the seconds field; if nanoseconds were larger than 999_999_999, the seconds
field should go up instead.
Suppose you ask for the time 1969-12-31, what time is that? On UNIX systems
that support times before the epoch, that's seconds=-86400, one day before the
epoch. But now, suppose you ask for the time 1969-12-31 23:59:00.1. In other
words, a tenth of a second after one minute before the epoch. On most UNIX
systems, that's represented as seconds=-60, nanoseconds=100_000_000. The macOS
bug is that it returns seconds=-59, nanoseconds=-900_000_000.
While that's in some sense an accurate description of the time (59.9 seconds
before the epoch), that violates the invariant of the timespec data structure:
nanoseconds must be between 0 and 999999999. This causes this assertion in the
Rust standard library.
So, on macOS, if we get a Timespec value with seconds less than or equal to
zero, and nanoseconds between -999_999_999 and -1 (inclusive), we can add
1_000_000_000 to the nanoseconds and subtract 1 from the seconds, and then
convert. The resulting timespec value is still accepted by macOS, and when fed
back into the OS, produces the same results. (If you set a file's mtime with
that timestamp, then read it back, you get back the one with negative
nanoseconds again.)
Co-authored-by: Josh Triplett <josh@joshtriplett.org>
Create `windows/api.rs` for safer FFI
FFI is inherently unsafe. For memory safety we need to assert that some contract is being upheld on both sides of the FFI, though of course we can only ever check our side. In Rust, `unsafe` blocks are used to assert safety and `// SAFETY` comments describing why it is safe. Currently in sys/windows we have a lot of this unsafety spread all over the place, with variations on the same unsafe patterns repeated. And because of the repitition and frequency, we're a bit lax with the safety comments.
This PR aims to fix this and to make FFI safety more auditable by creating an `api` module with the goal of centralising and consolidating this unsafety. It contains thin wrappers around the Windows API that make most functions safe to call or, if that's not possible, then at least safer. Note that its goal is *only* to address safety. It does not stray far from the Windows API and intentionally does not attempt to make higher lever wrappers around, for example, file handles. This is better left to the existing modules. The windows/api.rs file has a top level comment to help future contributors understand the intent of the module and the design decisions made.
I chose two functions as a first tentative step towards the above goal:
- [`GetLastError`](https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) is trivially safe. There's no reason to wrap it in an `unsafe` block every time. So I simply created a safe `get_last_error` wrapper.
- [`SetFileInformationByHandle`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileinformationbyhandle) is more complex. It essentially takes a generic type but over a C API which necessitates some amount of ceremony. Rather than implementing similar unsafe patterns in multiple places, I provide a safe `set_file_information_by_handle` that takes a Rusty generic type and handles converting that to the form required by the C FFI.
r? libs
These methods are the pre-stabilized API for obtaining peer credentials
from an `AF_UNIX` socket, part of the `unix_socket_ancillary_data` feature.
Their current behavior is to get/set one of the `SO_PASSCRED` (Linux),
`LOCAL_CREDS_PERSISTENT` (FreeBSD), or `LOCAL_CREDS` (NetBSD) socket
options. On other targets the `{set_}passcred()` methods do not exist.
There are two problems with this approach:
1. Having public methods only exist for certain targets isn't permitted
in a stable `std` API.
2. These options have generally similar purposes, but they are non-POSIX
and their details can differ in subtle and surprising ways (such as
whether they continue to be set after the next call to `recvmsg()`).
Splitting into OS-specific extension traits is the preferred solution to
both problems.
Windows: Support sub-millisecond sleep
Use `CreateWaitableTimerExW` with `CREATE_WAITABLE_TIMER_HIGH_RESOLUTION`. Does not work before Windows 10, version 1803 so in that case we fallback to using `Sleep`.
I've created a `WaitableTimer` type so it can one day be adapted to also support waiting to an absolute time (which has been talked about). Note though that it currently returns `Err(())` because we can't do anything with the errors other than fallback to the old `Sleep`. Feel free to tell me to do errors properly. It just didn't seem worth constructing an `io::Error` if we're never going to surface it to the user. And it *should* all be infallible anyway unless the OS is too old to support it.
Closes#43376
Remove Apple RNG fallbacks and simplify implementation
Now that we have [higher Apple platform requirements](https://github.com/rust-lang/rust/pull/104385), the RNG code can be simplified a lot. Since `getentropy` still doesn't look to be usable outside macOS this implementation:
- Removes any macOS fallback paths and unconditionally links to `getentropy`
- Minimizes the implementation for everything else (iOS, watchOS, etc).
`CCRandomGenerateBytes` was added in iOS 8 which means that we can use it now. It and `SecRandomCopyBytes` have the exact same functionality, but the former has a simpler API and no longer requires libstd to link to `Security.framework` for one function. Its also available in all the other target's SDKs.
Why care about `getentropy` then though on macOS? Well, its still much more performant. Benchmarking shows it runs at ~2x the speed of `CCRandomGenerateBytes`, which makes sense since it directly pulls from the kernel vs going through its own generator etc.
Semi-related to a previous, but reverted, attempt at improving this logic in https://github.com/rust-lang/rust/pull/101011
time: use clock_gettime on macos
Replace `gettimeofday` with `clock_gettime(CLOCK_REALTIME)` on:
```
all(target_os = "macos", not(target_arch = "aarch64")),
target_os = "ios",
target_os = "watchos",
target_os = "tvos"
))]
```
`gettimeofday` was first used in
cc367edd95
which predated the introduction of `clock_gettime` support in macOS
10.12 Sierra which became the minimum supported version in
58bbca958d.
Replace `mach_{absolute_time,timebase_info}` with
`clock_gettime(CLOCK_REALTIME)` on:
```
all(target_os = "macos", not(target_arch = "aarch64")),
target_os = "ios",
target_os = "watchos",
target_os = "tvos"
))]
```
`mach_{absolute_time,timebase_info}` were first used in
cc367edd95
which predated the introduction of `clock_gettime` support in macOS
10.12 Sierra which became the minimum supported version in
58bbca958d.
Note that this change was made for aarch64 in
5008a317ce which predated 10.12 becoming
the minimum supported version. The discussion took place in
https://github.com/rust-lang/rust/issues/91417 and in particular
https://github.com/rust-lang/rust/issues/91417#issuecomment-992151582
and
https://github.com/rust-lang/rust/issues/91417#issuecomment-1033048064
are relevant.
Rollup of 6 pull requests
Successful merges:
- #107159 (rand use getrandom for freebsd (available since 12.x))
- #116859 (Make `ty::print::Printer` take `&mut self` instead of `self`)
- #117046 (return unfixed len if pat has reported error)
- #117070 (rustdoc: wrap Type with Box instead of Generics)
- #117074 (Remove smir from triage and add me to stablemir)
- #117086 (Update .mailmap to promote my livename)
r? `@ghost`
`@rustbot` modify labels: rollup
report `unused_import` for empty reexports even it is pub
Fixes#116032
An easy fix. r? `@petrochenkov`
(Discovered this issue while reviewing #115993.)
On Windows make `read_dir` error on the empty path
This makes Windows consistent with other platforms. Note that this should not be taken to imply any decision on #114149 has been taken. However it was felt that while there is a lack of libs-api consensus, we should be consistent across platforms in the meantime.
This is a change in behaviour for Windows so will also need an fcp before merging.
r? libs-api
Make TCP connect handle EINTR correctly
According to the [POSIX](https://pubs.opengroup.org/onlinepubs/009695399/functions/connect.html) standard, if connect() is interrupted by a signal that is caught while blocked waiting to establish a connection, connect() shall fail and set errno to EINTR, but the connection request shall not be aborted, and the connection shall be established asynchronously. When the connection has been established asynchronously, select() and poll() shall indicate that the file descriptor for the socket is ready for writing.
The previous implementation differs from the recomendation: in a case of the EINTR we tried to reconnect in a loop and sometimes get EISCONN error (this problem was originally detected on MacOS).
1. More details about the problem in an [article](http://www.madore.org/~david/computers/connect-intr.html).
2. The original [issue](https://git.picodata.io/picodata/picodata/tarantool-module/-/issues/157).
Panic when the global allocator tries to register a TLS destructor
Using a `RefCell` avoids the undefined behaviour encountered in #116390 and reduces the amount of `unsafe` code in the codebase.
Updated libc and doc for Vita target
Doc changes:
- Updated Vita target readme. The recommended approach to build artifacts for the platform now is [cargo-vita](https://crates.io/crates/cargo-vita) which wraps all the convoluted steps previously described in a yaml for `cargo-make`
- Updated maintainer list for Vita target. (`@ZetaNumbers` `@pheki` please agree to be added to the list, `@amg98` please let us know if you're still planning on actively maintaining target support)
Code changes:
- ~Updated libc for rust-lang/libc#3284 and rust-lang/libc#3366~ (Already merged in #116527)
- In dupfd changed the flag same as for esp target, there is no CLOEXEC on Vita
- Enabled `new_pair` since we've implemented `socketpair` in Vita newlib
Implement sys::args for UEFI
- Uses `EFI_LOADED_IMAGE_PROTOCOL`, which is implemented for all loaded images.
Tested on qemu with OVMF
cc ``@nicholasbishop``
cc ``@dvdhrm``
Previously it failed on Windows if the file had the `FILE_ATTRIBUTE_HIDDEN` attribute set. This was inconsistent with `OpenOptions::new().write(true).truncate(true)` which can truncate an existing hidden file.
Make `try_exists` return `Ok(true)` for Windows Unix Sockets
This is a follow up to #109106 but for[ `fs::try_exists`](https://doc.rust-lang.org/std/fs/fn.try_exists.html), which doesn't need to get the metadata of a file (which can fail even if a file exists).
`fs::try_exists` currently fails on Windows if encountering a Unix Domain Socket (UDS). This PR fixes it by checking for an error code that's returned when there's a failure to use a reparse point.
## Reparse points
A reparse point is a way to invoke a filesystem filter on a file instead of the file being opened normally. This is used to implement symbolic links (by redirecting to a different path) but also to implement other types of special files such as Unix domain sockets. If the reparse point is not a link type then opening it with `CreateFileW` may fail with `ERROR_CANT_ACCESS_FILE` because the filesystem filter does not implement that operation. This differs from resolving links which may fail with errors such as `ERROR_FILE_NOT_FOUND` or `ERROR_CANT_RESOLVE_FILENAME`.
So `ERROR_CANT_ACCESS_FILE` means that the file exists but that we can't open it normally. Still, the file does exist on the filesystem so `try_exists` should report that as `Ok(true)`.
r? libs
Fix exit status / wait status on non-Unix cfg(unix) platforms
Fixes#114593
Needs FCP due to behavioural changes (NB only on non-Unix `#[cfg(unix)]` platforms).
Also, I think this is likely to break in CI. I have not been yet able to compile the new bits of `process_unsupported.rs`, although I have compiled the new module. I'd like some help from people familiar with eg emscripten and fuchsia (which are going to be affected, I think).
According to the POSIX standard, if connect() is interrupted by a
signal that is caught while blocked waiting to establish a connection,
connect() shall fail and set errno to EINTR, but the connection
request shall not be aborted, and the connection shall be established
asynchronously.
If asynchronous connection was successfully established after EINTR
and before the next connection attempt, OS returns EISCONN that was
handled as an error before. This behavior is fixed now and we handle
it as success.
The problem affects MacOS users: Linux doesn't return EISCONN in this
case, Windows connect() can not be interrupted without an old-fashoin
WSACancelBlockingCall function that is not used in the library.
So current solution gives connect() as OS specific implementation.