summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/util.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:29 +0000
commit631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch)
treea1b87c8f8cad01cf18f7c5f57a08f102771ed303 /src/bootstrap/util.rs
parentAdding debian version 1.69.0+dfsg1-1. (diff)
downloadrustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz
rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bootstrap/util.rs')
-rw-r--r--src/bootstrap/util.rs93
1 files changed, 1 insertions, 92 deletions
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index 93e53d383..2e1adbf63 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -146,100 +146,9 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
fs::symlink(src, dest)
}
- // Creating a directory junction on windows involves dealing with reparse
- // points and the DeviceIoControl function, and this code is a skeleton of
- // what can be found here:
- //
- // http://www.flexhex.com/docs/articles/hard-links.phtml
#[cfg(windows)]
fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> {
- use std::ffi::OsStr;
- use std::os::windows::ffi::OsStrExt;
- use std::ptr;
-
- use winapi::shared::minwindef::{DWORD, WORD};
- use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
- use winapi::um::handleapi::CloseHandle;
- use winapi::um::ioapiset::DeviceIoControl;
- use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT};
- use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT;
- use winapi::um::winnt::{
- FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_WRITE,
- IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, WCHAR,
- };
-
- #[allow(non_snake_case)]
- #[repr(C)]
- struct REPARSE_MOUNTPOINT_DATA_BUFFER {
- ReparseTag: DWORD,
- ReparseDataLength: DWORD,
- Reserved: WORD,
- ReparseTargetLength: WORD,
- ReparseTargetMaximumLength: WORD,
- Reserved1: WORD,
- ReparseTarget: WCHAR,
- }
-
- fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
- Ok(s.as_ref().encode_wide().chain(Some(0)).collect())
- }
-
- // We're using low-level APIs to create the junction, and these are more
- // picky about paths. For example, forward slashes cannot be used as a
- // path separator, so we should try to canonicalize the path first.
- let target = fs::canonicalize(target)?;
-
- fs::create_dir(junction)?;
-
- let path = to_u16s(junction)?;
-
- unsafe {
- let h = CreateFileW(
- path.as_ptr(),
- GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- ptr::null_mut(),
- OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
- ptr::null_mut(),
- );
-
- #[repr(C, align(8))]
- struct Align8<T>(T);
- let mut data = Align8([0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]);
- let db = data.0.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER;
- let buf = core::ptr::addr_of_mut!((*db).ReparseTarget) as *mut u16;
- let mut i = 0;
- // FIXME: this conversion is very hacky
- let v = br"\??\";
- let v = v.iter().map(|x| *x as u16);
- for c in v.chain(target.as_os_str().encode_wide().skip(4)) {
- *buf.offset(i) = c;
- i += 1;
- }
- *buf.offset(i) = 0;
- i += 1;
- (*db).ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
- (*db).ReparseTargetMaximumLength = (i * 2) as WORD;
- (*db).ReparseTargetLength = ((i - 1) * 2) as WORD;
- (*db).ReparseDataLength = (*db).ReparseTargetLength as DWORD + 12;
-
- let mut ret = 0;
- let res = DeviceIoControl(
- h as *mut _,
- FSCTL_SET_REPARSE_POINT,
- db.cast(),
- (*db).ReparseDataLength + 8,
- ptr::null_mut(),
- 0,
- &mut ret,
- ptr::null_mut(),
- );
-
- let out = if res == 0 { Err(io::Error::last_os_error()) } else { Ok(()) };
- CloseHandle(h);
- out
- }
+ junction::create(&target, &junction)
}
}