Skip to content

Commit 2f1eb0c

Browse files
onur-ozkancuviper
authored andcommitted
improve and fix x install
Fix: Write access check of `prefix` and `sysconfdir` when DESTDIR is present. Improvement: Instead of repeatedly reading `DESTDIR` within each `fn prepare_dir` usage, read it once and pass it to the `fn prepare_dir`. Signed-off-by: onur-ozkan <[email protected]> (cherry picked from commit 4b14048)
1 parent b125c10 commit 2f1eb0c

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed

src/bootstrap/install.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,27 @@ fn install_sh(
7373

7474
let prefix = default_path(&builder.config.prefix, "/usr/local");
7575
let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
76+
let destdir_env = env::var_os("DESTDIR").map(PathBuf::from);
7677

77-
// Sanity check for the user write access on prefix and sysconfdir
78-
assert!(
79-
is_dir_writable_for_user(&prefix),
80-
"User doesn't have write access on `install.prefix` path in the `config.toml`.",
81-
);
82-
assert!(
83-
is_dir_writable_for_user(&sysconfdir),
84-
"User doesn't have write access on `install.sysconfdir` path in `config.toml`."
85-
);
78+
// Sanity checks on the write access of user.
79+
//
80+
// When the `DESTDIR` environment variable is present, there is no point to
81+
// check write access for `prefix` and `sysconfdir` individually, as they
82+
// are combined with the path from the `DESTDIR` environment variable. In
83+
// this case, we only need to check the `DESTDIR` path, disregarding the
84+
// `prefix` and `sysconfdir` paths.
85+
if let Some(destdir) = &destdir_env {
86+
assert!(is_dir_writable_for_user(destdir), "User doesn't have write access on DESTDIR.");
87+
} else {
88+
assert!(
89+
is_dir_writable_for_user(&prefix),
90+
"User doesn't have write access on `install.prefix` path in the `config.toml`.",
91+
);
92+
assert!(
93+
is_dir_writable_for_user(&sysconfdir),
94+
"User doesn't have write access on `install.sysconfdir` path in `config.toml`."
95+
);
96+
}
8697

8798
let datadir = prefix.join(default_path(&builder.config.datadir, "share"));
8899
let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust"));
@@ -96,13 +107,13 @@ fn install_sh(
96107
let mut cmd = Command::new(SHELL);
97108
cmd.current_dir(&empty_dir)
98109
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
99-
.arg(format!("--prefix={}", prepare_dir(prefix)))
100-
.arg(format!("--sysconfdir={}", prepare_dir(sysconfdir)))
101-
.arg(format!("--datadir={}", prepare_dir(datadir)))
102-
.arg(format!("--docdir={}", prepare_dir(docdir)))
103-
.arg(format!("--bindir={}", prepare_dir(bindir)))
104-
.arg(format!("--libdir={}", prepare_dir(libdir)))
105-
.arg(format!("--mandir={}", prepare_dir(mandir)))
110+
.arg(format!("--prefix={}", prepare_dir(&destdir_env, prefix)))
111+
.arg(format!("--sysconfdir={}", prepare_dir(&destdir_env, sysconfdir)))
112+
.arg(format!("--datadir={}", prepare_dir(&destdir_env, datadir)))
113+
.arg(format!("--docdir={}", prepare_dir(&destdir_env, docdir)))
114+
.arg(format!("--bindir={}", prepare_dir(&destdir_env, bindir)))
115+
.arg(format!("--libdir={}", prepare_dir(&destdir_env, libdir)))
116+
.arg(format!("--mandir={}", prepare_dir(&destdir_env, mandir)))
106117
.arg("--disable-ldconfig");
107118
builder.run(&mut cmd);
108119
t!(fs::remove_dir_all(&empty_dir));
@@ -112,19 +123,16 @@ fn default_path(config: &Option<PathBuf>, default: &str) -> PathBuf {
112123
config.as_ref().cloned().unwrap_or_else(|| PathBuf::from(default))
113124
}
114125

115-
fn prepare_dir(mut path: PathBuf) -> String {
126+
fn prepare_dir(destdir_env: &Option<PathBuf>, mut path: PathBuf) -> String {
116127
// The DESTDIR environment variable is a standard way to install software in a subdirectory
117128
// while keeping the original directory structure, even if the prefix or other directories
118129
// contain absolute paths.
119130
//
120131
// More information on the environment variable is available here:
121132
// https://www.gnu.org/prep/standards/html_node/DESTDIR.html
122-
if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) {
123-
// Sanity check for the user write access on DESTDIR
124-
assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR.");
125-
133+
if let Some(destdir) = destdir_env {
126134
let without_destdir = path.clone();
127-
path = destdir;
135+
path = destdir.clone();
128136
// Custom .join() which ignores disk roots.
129137
for part in without_destdir.components() {
130138
if let Component::Normal(s) = part {

0 commit comments

Comments
 (0)