1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! The filesystem operations the compiler makes that are not a plain read or write.
//!
//! Linking-or-copying an artefact, a scratch directory, and turning a path into something a C
//! API will take. All of it goes through `libc-wrapper` rather than `std`.
//!
//! # What went, and why it was safe to lose
//!
//! Two pieces of this crate existed only for Windows. `fix_windows_verbatim_for_gcc` stripped the
//! `\\?\` prefix that `fs::canonicalize` produced there, because msvcrt silently mistranslated it
//! and gcc appeared to reject the path; the comment above it pointed at rust-lang/rust#25505 from
//! 2015. `path_to_c_string` had a second body that went through `to_str().unwrap()` because
//! Windows paths are UTF-16 and could not be handed over as bytes.
//!
//! Neither has a body to keep here. This compiler targets one platform, a path is bytes, and
//! `canonicalize` is `realpath(3)` which does not produce verbatim prefixes. `fix_windows_..`
//! is kept as the identity it already was on Unix rather than deleted, because its caller in
//! `rustc_codegen_ssa` reads as a deliberate step and removing the call is that crate's decision.
// ---------------------------------------------------------------------------------------------
// STD IS BANNED IN THIS CRATE.
//
// `#![no_std]` above is the ban and the compiler is the enforcer: without `extern crate std;`
// there is no `std` in the extern prelude, so any `std::` path fails to resolve and the build
// stops. Do not add that line back to make an error go away - the error is the point. Whatever
// needed `std` either has a `core`/`alloc` equivalent, belongs in `ekostd`, or is a
// dependency that has to be replaced.
//
// The prelude is the part a grep cannot see: `Vec`, `String`, `Box`, `format!`, `vec!`,
// `thread_local!` and `println!` name no path. Under `#![no_std]` they resolve through `alloc`
// and `eko` instead, which is why those imports appear at the top of every file here.
// ---------------------------------------------------------------------------------------------
use Vec;
use file;
use ;
/// Historically stripped a Windows verbatim prefix. The identity function on this platform.
/// Which of the two happened in [`link_or_copy`].
/// Hard-link `p` to `q`, falling back to a copy.
///
/// **The destination is not removed up front.** Creating a hard link fails when the destination
/// exists, and removing it defensively would cost every caller a syscall to serve the rare one -
/// incremental compilation calls this constantly and is built to avoid the failing case. So the
/// removal happens only after `link` reports `EEXIST`.
/// A path as NUL-terminated bytes, for a C API.
///
/// Returns the buffer rather than a `CString` because the only thing callers do with it is take
/// a pointer, and a `CString` would add an allocation and an interior-NUL check to a path that
/// came from the filesystem and cannot contain one.
/// Resolve a path, falling back to making it absolute if it does not exist.
/// Builds a scratch directory that removes itself when dropped.