Skip to content

Commit 359ab0b

Browse files
committed
rustc_back: Rewrite realpath to not use old_io
Just bind the relevant platform-specific functions we should probably be calling anyway.
1 parent bf4e77d commit 359ab0b

File tree

3 files changed

+64
-67
lines changed

3 files changed

+64
-67
lines changed

src/librustc_back/fs.rs

Lines changed: 60 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,70 +8,67 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use libc;
1112
use std::io;
12-
use std::env;
13-
#[allow(deprecated)] use std::old_path::{self, GenericPath};
14-
#[allow(deprecated)] use std::old_io;
1513
use std::path::{Path, PathBuf};
1614

17-
/// Returns an absolute path in the filesystem that `path` points to. The
18-
/// returned path does not contain any symlinks in its hierarchy.
19-
#[allow(deprecated)] // readlink is deprecated
15+
#[cfg(windows)]
2016
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
21-
let old = old_path::Path::new(original.to_str().unwrap());
22-
match old_realpath(&old) {
23-
Ok(p) => Ok(PathBuf::from(p.as_str().unwrap())),
24-
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
17+
use std::fs::File;
18+
use std::ffi::OsString;
19+
use std::os::windows::prelude::*;
20+
21+
extern "system" {
22+
fn GetFinalPathNameByHandleW(hFile: libc::HANDLE,
23+
lpszFilePath: libc::LPCWSTR,
24+
cchFilePath: libc::DWORD,
25+
dwFlags: libc::DWORD) -> libc::DWORD;
2526
}
26-
}
27-
28-
#[allow(deprecated)]
29-
fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
30-
use std::old_io::fs;
31-
const MAX_LINKS_FOLLOWED: usize = 256;
32-
let original = old_path::Path::new(env::current_dir().unwrap()
33-
.to_str().unwrap()).join(original);
3427

35-
// Right now lstat on windows doesn't work quite well
36-
if cfg!(windows) {
37-
return Ok(original)
28+
let mut v = Vec::with_capacity(16 * 1024);
29+
let f = try!(File::open(original));
30+
unsafe {
31+
let ret = GetFinalPathNameByHandleW(f.as_raw_handle(),
32+
v.as_mut_ptr(),
33+
v.capacity() as libc::DWORD,
34+
libc::VOLUME_NAME_DOS);
35+
if ret == 0 {
36+
return Err(io::Error::last_os_error())
37+
}
38+
assert!(ret as usize < v.capacit());
39+
v.set_len(ret);
3840
}
41+
Ok(PathBuf::from(OsString::from_wide(&v)))
42+
}
3943

40-
let result = original.root_path();
41-
let mut result = result.expect("make_absolute has no root_path");
42-
let mut followed = 0;
43-
44-
for part in original.components() {
45-
result.push(part);
44+
#[cfg(unix)]
45+
pub fn realpath(original: &Path) -> io::Result<PathBuf> {
46+
use std::os::unix::prelude::*;
47+
use std::ffi::{OsString, CString};
4648

47-
loop {
48-
if followed == MAX_LINKS_FOLLOWED {
49-
return Err(old_io::standard_error(old_io::InvalidInput))
50-
}
49+
extern {
50+
fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
51+
-> *mut libc::c_char;
52+
}
5153

52-
match fs::lstat(&result) {
53-
Err(..) => break,
54-
Ok(ref stat) if stat.kind != old_io::FileType::Symlink => break,
55-
Ok(..) => {
56-
followed += 1;
57-
let path = try!(fs::readlink(&result));
58-
result.pop();
59-
result.push(path);
60-
}
61-
}
54+
let path = try!(CString::new(original.as_os_str().as_bytes()));
55+
let mut buf = vec![0u8; 16 * 1024];
56+
unsafe {
57+
let r = realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _);
58+
if r.is_null() {
59+
return Err(io::Error::last_os_error())
6260
}
6361
}
64-
65-
return Ok(result);
62+
let p = buf.iter().position(|i| *i == 0).unwrap();
63+
buf.truncate(p);
64+
Ok(PathBuf::from(OsString::from_vec(buf)))
6665
}
6766

6867
#[cfg(all(not(windows), test))]
6968
mod test {
70-
use std::old_io;
71-
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
72-
use super::old_realpath as realpath;
73-
use std::old_io::TempDir;
74-
use std::old_path::{Path, GenericPath};
69+
use tempdir::TempDir;
70+
use std::fs::{self, File};
71+
use std::path::{Path, PathBuf};
7572

7673
#[test]
7774
fn realpath_works() {
@@ -83,15 +80,15 @@ mod test {
8380
let linkdir = tmpdir.join("test3");
8481

8582
File::create(&file).unwrap();
86-
mkdir(&dir, old_io::USER_RWX).unwrap();
87-
symlink(&file, &link).unwrap();
88-
symlink(&dir, &linkdir).unwrap();
89-
90-
assert!(realpath(&tmpdir).unwrap() == tmpdir);
91-
assert!(realpath(&file).unwrap() == file);
92-
assert!(realpath(&link).unwrap() == file);
93-
assert!(realpath(&linkdir).unwrap() == dir);
94-
assert!(realpath(&linkdir.join("link")).unwrap() == file);
83+
fs::create_dir(&dir).unwrap();
84+
fs::soft_link(&file, &link).unwrap();
85+
fs::soft_link(&dir, &linkdir).unwrap();
86+
87+
assert_eq!(realpath(&tmpdir).unwrap(), tmpdir);
88+
assert_eq!(realpath(&file).unwrap(), file);
89+
assert_eq!(realpath(&link).unwrap(), file);
90+
assert_eq!(realpath(&linkdir).unwrap(), dir);
91+
assert_eq!(realpath(&linkdir.join("link")).unwrap(), file);
9592
}
9693

9794
#[test]
@@ -106,13 +103,13 @@ mod test {
106103
let e = d.join("e");
107104
let f = a.join("f");
108105

109-
mkdir_recursive(&b, old_io::USER_RWX).unwrap();
110-
mkdir_recursive(&d, old_io::USER_RWX).unwrap();
106+
fs::create_dir_all(&b).unwrap();
107+
fs::create_dir_all(&d).unwrap();
111108
File::create(&f).unwrap();
112-
symlink(&Path::new("../d/e"), &c).unwrap();
113-
symlink(&Path::new("../f"), &e).unwrap();
109+
fs::soft_link("../d/e", &c).unwrap();
110+
fs::soft_link("../f", &e).unwrap();
114111

115-
assert!(realpath(&c).unwrap() == f);
116-
assert!(realpath(&e).unwrap() == f);
112+
assert_eq!(realpath(&c).unwrap(), f);
113+
assert_eq!(realpath(&e).unwrap(), f);
117114
}
118115
}

src/librustc_back/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,16 @@
3535
#![feature(box_syntax)]
3636
#![feature(collections)]
3737
#![feature(core)]
38-
#![feature(old_fs)]
39-
#![feature(old_io)]
40-
#![feature(old_path)]
4138
#![feature(rustc_private)]
4239
#![feature(staged_api)]
4340
#![feature(rand)]
4441
#![feature(path_ext)]
4542
#![feature(step_by)]
43+
#![feature(libc)]
4644
#![cfg_attr(test, feature(test, rand))]
4745

4846
extern crate syntax;
47+
extern crate libc;
4948
extern crate serialize;
5049
#[macro_use] extern crate log;
5150

src/librustc_back/rpath.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
9797
let cwd = env::current_dir().unwrap();
9898
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
9999
lib.pop();
100-
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
100+
let mut output = cwd.join(&config.out_filename);
101101
output.pop();
102+
let output = (config.realpath)(&output).unwrap();
102103
let relative = path_relative_from(&lib, &output)
103104
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
104105
// FIXME (#9639): This needs to handle non-utf8 paths

0 commit comments

Comments
 (0)