Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#117451 - Byron:issue-108277-apple-fix, r=jo…
…shtriplett Add support for pre-unix-epoch file dates on Apple platforms (rust-lang#108277) Please note that even though the assertion being hit is the same on MacOS and thus similar to what's described in rust-lang#108277, on MacOS it's possible to convert the numbers such that they are valid, don't hit the assertion and are round-trippable. Doing so effectively fixes the issue on Apple platforms. This PR does not attempt to harden other platforms against negative nanoseconds, which can happen for many reasons including mild filesystem corruption. ---- 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>
- Loading branch information