rustc_back: Rewrite realpath to not use old_io
Just bind the relevant platform-specific functions we should probably be calling anyway.
This commit is contained in:
parent
bf4e77d4b5
commit
359ab0b56b
3 changed files with 63 additions and 66 deletions
|
@ -8,70 +8,67 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use libc;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::env;
|
|
||||||
#[allow(deprecated)] use std::old_path::{self, GenericPath};
|
|
||||||
#[allow(deprecated)] use std::old_io;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// Returns an absolute path in the filesystem that `path` points to. The
|
#[cfg(windows)]
|
||||||
/// returned path does not contain any symlinks in its hierarchy.
|
|
||||||
#[allow(deprecated)] // readlink is deprecated
|
|
||||||
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
|
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
|
||||||
let old = old_path::Path::new(original.to_str().unwrap());
|
use std::fs::File;
|
||||||
match old_realpath(&old) {
|
use std::ffi::OsString;
|
||||||
Ok(p) => Ok(PathBuf::from(p.as_str().unwrap())),
|
use std::os::windows::prelude::*;
|
||||||
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
|
|
||||||
|
extern "system" {
|
||||||
|
fn GetFinalPathNameByHandleW(hFile: libc::HANDLE,
|
||||||
|
lpszFilePath: libc::LPCWSTR,
|
||||||
|
cchFilePath: libc::DWORD,
|
||||||
|
dwFlags: libc::DWORD) -> libc::DWORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut v = Vec::with_capacity(16 * 1024);
|
||||||
|
let f = try!(File::open(original));
|
||||||
|
unsafe {
|
||||||
|
let ret = GetFinalPathNameByHandleW(f.as_raw_handle(),
|
||||||
|
v.as_mut_ptr(),
|
||||||
|
v.capacity() as libc::DWORD,
|
||||||
|
libc::VOLUME_NAME_DOS);
|
||||||
|
if ret == 0 {
|
||||||
|
return Err(io::Error::last_os_error())
|
||||||
|
}
|
||||||
|
assert!(ret as usize < v.capacit());
|
||||||
|
v.set_len(ret);
|
||||||
|
}
|
||||||
|
Ok(PathBuf::from(OsString::from_wide(&v)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[cfg(unix)]
|
||||||
fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
|
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
|
||||||
use std::old_io::fs;
|
use std::os::unix::prelude::*;
|
||||||
const MAX_LINKS_FOLLOWED: usize = 256;
|
use std::ffi::{OsString, CString};
|
||||||
let original = old_path::Path::new(env::current_dir().unwrap()
|
|
||||||
.to_str().unwrap()).join(original);
|
|
||||||
|
|
||||||
// Right now lstat on windows doesn't work quite well
|
extern {
|
||||||
if cfg!(windows) {
|
fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
|
||||||
return Ok(original)
|
-> *mut libc::c_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = original.root_path();
|
let path = try!(CString::new(original.as_os_str().as_bytes()));
|
||||||
let mut result = result.expect("make_absolute has no root_path");
|
let mut buf = vec![0u8; 16 * 1024];
|
||||||
let mut followed = 0;
|
unsafe {
|
||||||
|
let r = realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _);
|
||||||
for part in original.components() {
|
if r.is_null() {
|
||||||
result.push(part);
|
return Err(io::Error::last_os_error())
|
||||||
|
|
||||||
loop {
|
|
||||||
if followed == MAX_LINKS_FOLLOWED {
|
|
||||||
return Err(old_io::standard_error(old_io::InvalidInput))
|
|
||||||
}
|
|
||||||
|
|
||||||
match fs::lstat(&result) {
|
|
||||||
Err(..) => break,
|
|
||||||
Ok(ref stat) if stat.kind != old_io::FileType::Symlink => break,
|
|
||||||
Ok(..) => {
|
|
||||||
followed += 1;
|
|
||||||
let path = try!(fs::readlink(&result));
|
|
||||||
result.pop();
|
|
||||||
result.push(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let p = buf.iter().position(|i| *i == 0).unwrap();
|
||||||
return Ok(result);
|
buf.truncate(p);
|
||||||
|
Ok(PathBuf::from(OsString::from_vec(buf)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(windows), test))]
|
#[cfg(all(not(windows), test))]
|
||||||
mod test {
|
mod test {
|
||||||
use std::old_io;
|
use tempdir::TempDir;
|
||||||
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
|
use std::fs::{self, File};
|
||||||
use super::old_realpath as realpath;
|
use std::path::{Path, PathBuf};
|
||||||
use std::old_io::TempDir;
|
|
||||||
use std::old_path::{Path, GenericPath};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn realpath_works() {
|
fn realpath_works() {
|
||||||
|
@ -83,15 +80,15 @@ mod test {
|
||||||
let linkdir = tmpdir.join("test3");
|
let linkdir = tmpdir.join("test3");
|
||||||
|
|
||||||
File::create(&file).unwrap();
|
File::create(&file).unwrap();
|
||||||
mkdir(&dir, old_io::USER_RWX).unwrap();
|
fs::create_dir(&dir).unwrap();
|
||||||
symlink(&file, &link).unwrap();
|
fs::soft_link(&file, &link).unwrap();
|
||||||
symlink(&dir, &linkdir).unwrap();
|
fs::soft_link(&dir, &linkdir).unwrap();
|
||||||
|
|
||||||
assert!(realpath(&tmpdir).unwrap() == tmpdir);
|
assert_eq!(realpath(&tmpdir).unwrap(), tmpdir);
|
||||||
assert!(realpath(&file).unwrap() == file);
|
assert_eq!(realpath(&file).unwrap(), file);
|
||||||
assert!(realpath(&link).unwrap() == file);
|
assert_eq!(realpath(&link).unwrap(), file);
|
||||||
assert!(realpath(&linkdir).unwrap() == dir);
|
assert_eq!(realpath(&linkdir).unwrap(), dir);
|
||||||
assert!(realpath(&linkdir.join("link")).unwrap() == file);
|
assert_eq!(realpath(&linkdir.join("link")).unwrap(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -106,13 +103,13 @@ mod test {
|
||||||
let e = d.join("e");
|
let e = d.join("e");
|
||||||
let f = a.join("f");
|
let f = a.join("f");
|
||||||
|
|
||||||
mkdir_recursive(&b, old_io::USER_RWX).unwrap();
|
fs::create_dir_all(&b).unwrap();
|
||||||
mkdir_recursive(&d, old_io::USER_RWX).unwrap();
|
fs::create_dir_all(&d).unwrap();
|
||||||
File::create(&f).unwrap();
|
File::create(&f).unwrap();
|
||||||
symlink(&Path::new("../d/e"), &c).unwrap();
|
fs::soft_link("../d/e", &c).unwrap();
|
||||||
symlink(&Path::new("../f"), &e).unwrap();
|
fs::soft_link("../f", &e).unwrap();
|
||||||
|
|
||||||
assert!(realpath(&c).unwrap() == f);
|
assert_eq!(realpath(&c).unwrap(), f);
|
||||||
assert!(realpath(&e).unwrap() == f);
|
assert_eq!(realpath(&e).unwrap(), f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,17 +35,16 @@
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(collections)]
|
#![feature(collections)]
|
||||||
#![feature(core)]
|
#![feature(core)]
|
||||||
#![feature(old_fs)]
|
|
||||||
#![feature(old_io)]
|
|
||||||
#![feature(old_path)]
|
|
||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(rand)]
|
#![feature(rand)]
|
||||||
#![feature(path_ext)]
|
#![feature(path_ext)]
|
||||||
#![feature(step_by)]
|
#![feature(step_by)]
|
||||||
|
#![feature(libc)]
|
||||||
#![cfg_attr(test, feature(test, rand))]
|
#![cfg_attr(test, feature(test, rand))]
|
||||||
|
|
||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
extern crate libc;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
|
||||||
|
|
|
@ -97,8 +97,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
|
||||||
let cwd = env::current_dir().unwrap();
|
let cwd = env::current_dir().unwrap();
|
||||||
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
|
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
|
||||||
lib.pop();
|
lib.pop();
|
||||||
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
|
let mut output = cwd.join(&config.out_filename);
|
||||||
output.pop();
|
output.pop();
|
||||||
|
let output = (config.realpath)(&output).unwrap();
|
||||||
let relative = path_relative_from(&lib, &output)
|
let relative = path_relative_from(&lib, &output)
|
||||||
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
|
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
|
||||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue