rustc: Check that the output file is writeable before linking
This is because on Linux, the linker will silently overwrite a read-only file.
This commit is contained in:
parent
1cf029c229
commit
4dbef017dd
4 changed files with 45 additions and 26 deletions
|
@ -959,6 +959,16 @@ pub fn link_binary(sess: Session,
|
|||
}
|
||||
}
|
||||
|
||||
fn is_writeable(p: &Path) -> bool {
|
||||
use std::libc::consts::os::posix88::S_IWUSR;
|
||||
|
||||
!os::path_exists(p) ||
|
||||
(match p.get_mode() {
|
||||
None => false,
|
||||
Some(m) => m & S_IWUSR as uint == S_IWUSR as uint
|
||||
})
|
||||
}
|
||||
|
||||
pub fn link_args(sess: Session,
|
||||
obj_filename: &Path,
|
||||
out_filename: &Path,
|
||||
|
@ -982,6 +992,21 @@ pub fn link_args(sess: Session,
|
|||
out_filename.clone()
|
||||
};
|
||||
|
||||
// Make sure the output and obj_filename are both writeable.
|
||||
// Mac, FreeBSD, and Windows system linkers check this already --
|
||||
// however, the Linux linker will happily overwrite a read-only file.
|
||||
// We should be consistent.
|
||||
let obj_is_writeable = is_writeable(obj_filename);
|
||||
let out_is_writeable = is_writeable(&output);
|
||||
if !out_is_writeable {
|
||||
sess.fatal(format!("Output file {} is not writeable -- check its permissions.",
|
||||
output.display()));
|
||||
}
|
||||
else if !obj_is_writeable {
|
||||
sess.fatal(format!("Object file {} is not writeable -- check its permissions.",
|
||||
obj_filename.display()));
|
||||
}
|
||||
|
||||
// The default library location, we need this to find the runtime.
|
||||
// The location of crates will be determined as needed.
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
|
|
|
@ -556,7 +556,7 @@ impl CtxMethods for BuildContext {
|
|||
debug2!("In declare inputs for {}", id.to_str());
|
||||
for cs in to_do.iter() {
|
||||
for c in cs.iter() {
|
||||
let path = pkg_src.start_dir.join(&c.file).normalize();
|
||||
let path = pkg_src.start_dir.join(&c.file);
|
||||
debug2!("Recording input: {}", path.display());
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
inputs.push((~"file", path.as_str().unwrap().to_owned()));
|
||||
|
@ -623,19 +623,19 @@ impl CtxMethods for BuildContext {
|
|||
// Declare all the *inputs* to the declared input too, as inputs
|
||||
for executable in subex.iter() {
|
||||
exe_thing.discover_input("binary",
|
||||
executable.to_str(),
|
||||
executable.as_str().unwrap().to_owned(),
|
||||
workcache_support::digest_only_date(executable));
|
||||
}
|
||||
for library in sublib.iter() {
|
||||
exe_thing.discover_input("binary",
|
||||
library.to_str(),
|
||||
library.as_str().unwrap().to_owned(),
|
||||
workcache_support::digest_only_date(library));
|
||||
}
|
||||
|
||||
for transitive_dependency in sub_build_inputs.iter() {
|
||||
exe_thing.discover_input(
|
||||
"file",
|
||||
transitive_dependency.to_str(),
|
||||
transitive_dependency.as_str().unwrap().to_owned(),
|
||||
workcache_support::digest_file_with_date(transitive_dependency));
|
||||
}
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ fn touch_source_file(workspace: &Path, pkgid: &PkgId) {
|
|||
// should be able to do this w/o a process
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
// n.b. Bumps time up by 2 seconds to get around granularity issues
|
||||
if run::process_output("touch", [~"-A", ~"02", p.to_str()]).status != 0 {
|
||||
if run::process_output("touch", [~"-A", ~"02", p.as_str().unwrap().to_owned()]).status != 0 {
|
||||
let _ = cond.raise((pkg_src_dir.clone(), ~"Bad path"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -441,8 +441,8 @@ impl<'self> Visitor<()> for ViewItemVisitor<'self> {
|
|||
// Now we know that this crate has a discovered dependency on
|
||||
// installed_path
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
add_dep(self.deps, self.parent_crate.to_str(),
|
||||
(~"binary", installed_path.to_str()));
|
||||
add_dep(self.deps, self.parent_crate.as_str().unwrap().to_owned(),
|
||||
(~"binary", installed_path.as_str().unwrap().to_owned()));
|
||||
self.exec.discover_input("binary",
|
||||
installed_path.as_str().unwrap(),
|
||||
digest_only_date(installed_path));
|
||||
|
@ -492,6 +492,10 @@ impl<'self> Visitor<()> for ViewItemVisitor<'self> {
|
|||
self.exec.discover_input("binary",
|
||||
dep.as_str().unwrap(),
|
||||
digest_only_date(dep));
|
||||
add_dep(self.deps,
|
||||
self.parent_crate.as_str().unwrap().to_owned(),
|
||||
(~"binary", dep.as_str().unwrap().to_owned()));
|
||||
|
||||
// Also, add an additional search path
|
||||
let dep_dir = dep.dir_path();
|
||||
debug2!("Installed {} into {}", dep.display(), dep_dir.display());
|
||||
|
@ -502,41 +506,31 @@ impl<'self> Visitor<()> for ViewItemVisitor<'self> {
|
|||
lib_name, outputs_disc.len(), inputs_disc.len());
|
||||
// It must have installed *something*...
|
||||
assert!(!outputs_disc.is_empty());
|
||||
let target_workspace = outputs_disc[0].pop();
|
||||
for dep in outputs_disc.iter() {
|
||||
debug2!("Discovering a binary input: {}", dep.to_str());
|
||||
self.exec.discover_input("binary", dep.to_str(),
|
||||
digest_only_date(dep));
|
||||
add_dep(self.deps,
|
||||
self.parent_crate.to_str(),
|
||||
(~"binary", dep.to_str()));
|
||||
}
|
||||
let mut target_workspace = outputs_disc[0].clone();
|
||||
target_workspace.pop();
|
||||
for &(ref what, ref dep) in inputs_disc.iter() {
|
||||
if *what == ~"file" {
|
||||
add_dep(self.deps,
|
||||
self.parent_crate.to_str(),
|
||||
(~"file", dep.to_str()));
|
||||
|
||||
self.parent_crate.as_str().unwrap().to_owned(),
|
||||
(~"file", dep.clone()));
|
||||
self.exec.discover_input(*what,
|
||||
*dep,
|
||||
digest_file_with_date(
|
||||
&Path::new(dep.as_slice())));
|
||||
}
|
||||
else if *what == ~"binary" {
|
||||
} else if *what == ~"binary" {
|
||||
add_dep(self.deps,
|
||||
self.parent_crate.to_str(),
|
||||
(~"binary", dep.to_str()));
|
||||
self.parent_crate.as_str().unwrap().to_owned(),
|
||||
(~"binary", dep.clone()));
|
||||
self.exec.discover_input(*what,
|
||||
*dep,
|
||||
digest_only_date(
|
||||
&Path::new(dep.as_slice())));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fail2!("Bad kind: {}", *what);
|
||||
}
|
||||
// Also, add an additional search path
|
||||
debug2!("Installed {} into {}",
|
||||
lib_name, target_workspace.to_str());
|
||||
lib_name, target_workspace.as_str().unwrap().to_owned());
|
||||
(self.save)(target_workspace.clone());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue