1use std::ffi::CString;
2use std::path::{Path, PathBuf, absolute};
3use std::{fs, io};
4
5#[cfg(windows)]
22pub fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
23 use std::ffi::OsString;
24 use std::path;
25 let mut components = p.components();
26 let prefix = match components.next() {
27 Some(path::Component::Prefix(p)) => p,
28 _ => return p.to_path_buf(),
29 };
30 match prefix.kind() {
31 path::Prefix::VerbatimDisk(disk) => {
32 let mut base = OsString::from(format!("{}:", disk as char));
33 base.push(components.as_path());
34 PathBuf::from(base)
35 }
36 path::Prefix::VerbatimUNC(server, share) => {
37 let mut base = OsString::from(r"\\");
38 base.push(server);
39 base.push(r"\");
40 base.push(share);
41 base.push(components.as_path());
42 PathBuf::from(base)
43 }
44 _ => p.to_path_buf(),
45 }
46}
47
48#[cfg(not(windows))]
49pub fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
50 p.to_path_buf()
51}
52
53pub enum LinkOrCopy {
54 Link,
55 Copy,
56}
57
58pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<LinkOrCopy> {
61 let p = p.as_ref();
67 let q = q.as_ref();
68
69 let err = match fs::hard_link(p, q) {
70 Ok(()) => return Ok(LinkOrCopy::Link),
71 Err(err) => err,
72 };
73
74 if err.kind() == io::ErrorKind::AlreadyExists {
75 fs::remove_file(q)?;
76 if fs::hard_link(p, q).is_ok() {
77 return Ok(LinkOrCopy::Link);
78 }
79 }
80
81 fs::copy(p, q).map(|_| LinkOrCopy::Copy)
83}
84
85#[cfg(any(unix, all(target_os = "wasi", target_env = "p1")))]
86pub fn path_to_c_string(p: &Path) -> CString {
87 use std::ffi::OsStr;
88 #[cfg(unix)]
89 use std::os::unix::ffi::OsStrExt;
90 #[cfg(all(target_os = "wasi", target_env = "p1"))]
91 use std::os::wasi::ffi::OsStrExt;
92
93 let p: &OsStr = p.as_ref();
94 CString::new(p.as_bytes()).unwrap()
95}
96#[cfg(windows)]
97pub fn path_to_c_string(p: &Path) -> CString {
98 CString::new(p.to_str().unwrap()).unwrap()
99}
100
101#[inline]
102pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
103 fs::canonicalize(&path).or_else(|_| absolute(&path))
104}