Show More
@@ -443,20 +443,19 b' Node components are:' | |||||
443 |
|
443 | |||
444 | If an untracked node `HAS_MTIME` *set*, |
|
444 | If an untracked node `HAS_MTIME` *set*, | |
445 | what follows is the modification time of a directory |
|
445 | what follows is the modification time of a directory | |
446 | represented with separated second and sub-second components |
|
446 | represented similarly to the C `timespec` struct: | |
447 | since the Unix epoch: |
|
|||
448 |
|
447 | |||
449 | * Offset 31: |
|
448 | * Offset 31: | |
450 | The number of seconds as a signed (two’s complement) 64-bit integer. |
|
449 | The number of seconds elapsed since the Unix epoch, | |
|
450 | as a signed (two’s complement) 64-bit integer. | |||
451 |
|
451 | |||
452 | * Offset 39: |
|
452 | * Offset 39: | |
453 |
The number of nanoseconds |
|
453 | The number of nanoseconds elapsed since | |
|
454 | the instant specified by the previous field alone, | |||
|
455 | as 32-bit integer. | |||
454 | Always greater than or equal to zero, and strictly less than a billion. |
|
456 | Always greater than or equal to zero, and strictly less than a billion. | |
455 | Increasing this component makes the modification time |
|
457 | Increasing this component makes the modification time | |
456 | go forward or backward in time dependening |
|
458 | go forward in time regardless of the sign of the seconds component. | |
457 | on the sign of the integral seconds components. |
|
|||
458 | (Note: this is buggy because there is no negative zero integer, |
|
|||
459 | but will be changed soon.) |
|
|||
460 |
|
459 | |||
461 | The presence of a directory modification time means that at some point, |
|
460 | The presence of a directory modification time means that at some point, | |
462 | this path in the working directory was observed: |
|
461 | this path in the working directory was observed: |
@@ -126,8 +126,7 b' pub(super) struct Timestamp {' | |||||
126 |
|
126 | |||
127 | /// In `0 .. 1_000_000_000`. |
|
127 | /// In `0 .. 1_000_000_000`. | |
128 | /// |
|
128 | /// | |
129 |
/// This timestamp is |
|
129 | /// This timestamp is after `(seconds, 0)` by this many nanoseconds. | |
130 | /// nanoseconds, if `seconds` is non-negative or negative, respectively. |
|
|||
131 | nanoseconds: U32Be, |
|
130 | nanoseconds: U32Be, | |
132 | } |
|
131 | } | |
133 |
|
132 | |||
@@ -446,13 +445,30 b' impl Timestamp {' | |||||
446 |
|
445 | |||
447 | impl From<SystemTime> for Timestamp { |
|
446 | impl From<SystemTime> for Timestamp { | |
448 | fn from(system_time: SystemTime) -> Self { |
|
447 | fn from(system_time: SystemTime) -> Self { | |
|
448 | // On Unix, `SystemTime` is a wrapper for the `timespec` C struct: | |||
|
449 | // https://www.gnu.org/software/libc/manual/html_node/Time-Types.html#index-struct-timespec | |||
|
450 | // We want to effectively access its fields, but the Rust standard | |||
|
451 | // library does not expose them. The best we can do is: | |||
449 | let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) { |
|
452 | let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) { | |
450 | Ok(duration) => { |
|
453 | Ok(duration) => { | |
451 | (duration.as_secs() as i64, duration.subsec_nanos()) |
|
454 | (duration.as_secs() as i64, duration.subsec_nanos()) | |
452 | } |
|
455 | } | |
453 | Err(error) => { |
|
456 | Err(error) => { | |
|
457 | // `system_time` is before `UNIX_EPOCH`. | |||
|
458 | // We need to undo this algorithm: | |||
|
459 | // https://github.com/rust-lang/rust/blob/6bed1f0bc3cc50c10aab26d5f94b16a00776b8a5/library/std/src/sys/unix/time.rs#L40-L41 | |||
454 | let negative = error.duration(); |
|
460 | let negative = error.duration(); | |
455 |
|
|
461 | let negative_secs = negative.as_secs() as i64; | |
|
462 | let negative_nanos = negative.subsec_nanos(); | |||
|
463 | if negative_nanos == 0 { | |||
|
464 | (-negative_secs, 0) | |||
|
465 | } else { | |||
|
466 | // For example if `system_time` was 4.3 seconds before | |||
|
467 | // the Unix epoch we get a Duration that represents | |||
|
468 | // `(-4, -0.3)` but we want `(-5, +0.7)`: | |||
|
469 | const NSEC_PER_SEC: u32 = 1_000_000_000; | |||
|
470 | (-1 - negative_secs, NSEC_PER_SEC - negative_nanos) | |||
|
471 | } | |||
456 | } |
|
472 | } | |
457 | }; |
|
473 | }; | |
458 | Timestamp { |
|
474 | Timestamp { |
General Comments 0
You need to be logged in to leave comments.
Login now