Setting append without write doesn't give you a writeable file. Showing
it as an example in the docs is confusing at best.
Using truncate on a read-only file is an error on POSIX systems (note
however that using create with read-only flags is fine).
This commit enables executables linked against the standard library to run on
Windows XP. There are two main components of this commit:
* APIs not available on XP are shimmed to have a fallback implementation and use
runtime detection to determine if they are available.
* Mutexes on Windows were reimplemented to use critical sections on XP where
rwlocks are not available.
The APIs which are not available on XP are:
* SetFileInformationByHandle - this is just used by `File::truncate` and that
function just returns an error now.
* SetThreadStackGuarantee - this is used by the stack overflow support on
windows, but if this isn't available then it's just ignored (it seems
non-critical).
* All condition variable APIs are missing - the shims added for these apis
simply always panic for now. We may eventually provide a fallback
implementation, but for now the standard library does not rely on condition
variables for normal use.
* RWLocks, like condition variables, are missing entirely. The same story for
condition variables is taken here. These APIs are all now panicking stubs as
the standard library doesn't rely on RWLocks for normal use.
Currently, as an optimization, we use SRWLOCKs for the standard `sync::Mutex`
implementation on Windows, which is indeed required for normal operation of the
standard library. To allow the standard library to run on XP, this commit
reimplements mutexes on Windows to use SRWLOCK instances *if available* and
otherwise a CriticalSection is used (with some checking for recursive
locking).
With all these changes put together, a 32-bit MSVC-built executable can run on
Windows XP and print "hello world"
Closes#12842Closes#19992Closes#24776
It turns out that the 32-bit toolchain for MSVC has many of these functions as
`static inline` functions in header files so there's not actually a symbol for
Rust to call. All of the implementations just cast floats to their 64-bit
variants and then cast back to 32-bit at the end, so the standard library now
takes this strategy.
Now that LLVM has been updated, the only remaining roadblock to implementing
unwinding for MSVC is to fill out the runtime support in `std::rt::unwind::seh`.
This commit does precisely that, fixing up some other bits and pieces along the
way:
* The `seh` unwinding module now uses `RaiseException` to initiate a panic.
* The `rust_try.ll` file was rewritten for MSVC (as it's quite different) and is
located at `rust_try_msvc_64.ll`, only included on MSVC builds for now.
* The personality function for all landing pads generated by LLVM is hard-wired
to `__C_specific_handler` instead of the standard `rust_eh_personality` lang
item. This is required to get LLVM to emit SEH unwinding information instead
of DWARF unwinding information. This also means that on MSVC the
`rust_eh_personality` function is entirely unused (but is defined as it's a
lang item).
More details about how panicking works on SEH can be found in the
`rust_try_msvc_64.ll` or `seh.rs` files, but I'm always open to adding more
comments!
A key aspect of this PR is missing, however, which is that **unwinding is still
turned off by default for MSVC**. There is a [bug in llvm][llvm-bug] which
causes optimizations to inline enough landing pads that LLVM chokes. If the
compiler is optimized at `-O1` (where inlining isn't enabled) then it can
bootstrap with unwinding enabled, but when optimized at `-O2` (inlining is
enabled) then it hits a fatal LLVM error.
[llvm-bug]: https://llvm.org/bugs/show_bug.cgi?id=23884
This removes a footgun, since it is a reasonable assumption to make that
pointers to `T` will be aligned to `align_of::<T>()`. This also matches
the behaviour of C/C++. `min_align_of` is now deprecated.
Closes#21611.
Now that LLVM has been updated, the only remaining roadblock to implementing
unwinding for MSVC is to fill out the runtime support in `std::rt::unwind::seh`.
This commit does precisely that, fixing up some other bits and pieces along the
way:
* The `seh` unwinding module now uses `RaiseException` to initiate a panic.
* The `rust_try.ll` file was rewritten for MSVC (as it's quite different) and is
located at `rust_try_msvc_64.ll`, only included on MSVC builds for now.
* The personality function for all landing pads generated by LLVM is hard-wired
to `__C_specific_handler` instead of the standard `rust_eh_personality` lang
item. This is required to get LLVM to emit SEH unwinding information instead
of DWARF unwinding information. This also means that on MSVC the
`rust_eh_personality` function is entirely unused (but is defined as it's a
lang item).
More details about how panicking works on SEH can be found in the
`rust_try_msvc_64.ll` or `seh.rs` files, but I'm always open to adding more
comments!
A key aspect of this PR is missing, however, which is that **unwinding is still
turned off by default for MSVC**. There is a [bug in llvm][llvm-bug] which
causes optimizations to inline enough landing pads that LLVM chokes. If the
compiler is optimized at `-O1` (where inlining isn't enabled) then it can
bootstrap with unwinding enabled, but when optimized at `-O2` (inlining is
enabled) then it hits a fatal LLVM error.
[llvm-bug]: https://llvm.org/bugs/show_bug.cgi?id=23884
This removes a footgun, since it is a reasonable assumption to make that
pointers to `T` will be aligned to `align_of::<T>()`. This also matches
the behaviour of C/C++. `min_align_of` is now deprecated.
Closes#21611.
signal(), sigemptyset(), and sigaddset() are only available as inline
functions until Android API 21. liblibc already handles signal()
appropriately, so drop it from c.rs; translate sigemptyset() and
sigaddset() (which is only used in a test) by hand from the C inlines.
We probably want to revert this commit when we bump Android API level.
Make sure that child processes don't get affected by libstd's desire to
ignore SIGPIPE, nor a third-party library's signal mask (which is needed
to use either a signal-handling thread correctly or to use signalfd /
kqueue correctly).
Both c.rs and stack_overflow.rs had bindings of libc's signal-handling
routines. It looks like the split dated from #16388, when (what is now)
c.rs was in libnative but not libgreen. Nobody is currently using the
c.rs bindings, but they're a bit more accurate in some places.
Move everything to c.rs (since I'll need signal handling in process.rs,
and we should avoid duplication), clean up the bindings, and manually
double-check everything against the relevant system headers (fixing a
few things in the process).
It looks like a lot of this dated to previous incarnations of the io
module, etc., and went unused in the reworking leading up to 1.0. Remove
everything we're not actively using (except for signal handling, which
will be reworked in the next commit).
The `execv` family of functions and `getopt` are prototyped somewhat strangely in C: they take a `char *const argv[]` (and `envp`, for `execve`), an immutable array of mutable C strings -- in other words, a `char *const *argv` or `argv: *const *mut c_char`. The current Rust binding uses `*mut *const c_char`, which is backwards (a mutable array of constant C strings).
That said, these functions do not actually modify their arguments. Once upon a time, C didn't have `const`, and to this day, string literals in C have type `char *` (`*mut c_char`). So an array of string literals has type `char * []`, equivalent to `char **` in a function parameter (Rust `*mut *mut c_char`). C allows an implicit cast from `T **` to `T * const *` (`*const *mut T`) but not to `const T * const *` (`*const *const T`). Therefore, prototyping `execv` as taking `const char * const argv[]` would have broken existing code (by requiring an explicit cast), despite being more correct. So, even though these functions don't need mutable data, they're prototyped as if they do.
While it's theoretically possible that an implementation could choose to use its freedom to modify the mutable data, such an implementation would break the innumerable users of `execv`-family functions that call them with string literals. Such an implementation would also break `std::process`, which currently works around this with an unsafe `as *mut _` cast, and assumes that `execvp` secretly does not modify its argument. Furthermore, there's nothing useful to be gained by being able to write to the strings in `argv` themselves but not being able to write to the array containing those strings (you can't reorder arguments, add arguments, increase the length of any parameter, etc.).
So, despite the C prototype with its legacy C problems, it's simpler for everyone for Rust to consider these functions as taking `*const *const c_char`, and it's also safe to do so. Rust does not need to expose the mistakes of C here. This patch makes that change, and drops the unsafe cast in `std::process` since it's now unnecessary.
The documentation of `std::net::Shutdown` mentions says it can be passed to the `shutdown` method of `UdpSocket`, which isn't true because `UdpSocket` has no such method. This commit removes that mention.
Fixes https://github.com/rust-lang/rust/issues/26408
Example output when using `Result::unwrap`:
```
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 2, message: "The system cannot find the file specified.\r\n" } }', src/libcore\result.rs:731
```
This could technically be considered a breaking change for any code that depends on the format of the `Debug` output for `io::Error` but I sincerely hope nobody wrote code like that.
The execv family of functions do not modify their arguments, so they do
not need mutable pointers. The C prototypes take a constant array of
mutable C-strings, but that's a legacy quirk from before C had const
(since C string literals have type `char *`). The Rust prototypes had
`*mut` in the wrong place, anyway: to match the C prototypes, it should
have been `*const *mut c_char`. But it is safe to pass constant strings
(like string literals) to these functions.
getopt is a special case, since GNU getopt modifies its arguments
despite the `const` claim in the prototype. It is apparently only
well-defined to call getopt on the actual argc and argv parameters
passed to main, anyway. Change it to take `*mut *mut c_char` for an
attempt at safety, but probably nobody should be using it from Rust,
since there's no great way to get at the parameters as passed to main.
Also fix the one caller of execvp in libstd, which now no longer needs
an unsafe cast.
Fixes#16290.
This commit shards the all-encompassing `core`, `std_misc`, `collections`, and `alloc` features into finer-grained components that are much more easily opted into and tracked. This reflects the effort to push forward current unstable APIs to either stabilization or removal. Keeping track of unstable features on a much more fine-grained basis will enable the library subteam to quickly analyze a feature and help prioritize internally about what APIs should be stabilized.
A few assorted APIs were deprecated along the way, but otherwise this change is just changing the feature name associated with each API. Soon we will have a dashboard for keeping track of all the unstable APIs in the standard library, and I'll also start making issues for each unstable API after performing a first-pass for stabilization.
The `thread::scoped` function will never be stabilized as-is and the API will
likely change significantly if it does, so this function is deprecated for
removal.
This function follows the well-established "constructor" pattern and the
initialization constant will likely be deprecated in favor of it once `const_fn`
is stabilized.
This commit shards the broad `core` feature of the libcore library into finer
grained features. This split groups together similar APIs and enables tracking
each API separately, giving a better sense of where each feature is within the
stabilization process.
A few minor APIs were deprecated along the way:
* Iterator::reverse_in_place
* marker::NoCopy