Skip to content

Commit 440c6a2

Browse files
committed
Handle win32 separater for cygwin paths
1 parent ba55b7c commit 440c6a2

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

library/std/src/sys/path/cygwin.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use crate::ffi::OsStr;
2+
use crate::path::{Path, PathBuf, Prefix};
3+
use crate::sys::common::small_c_string::run_path_with_cstr;
4+
use crate::sys::cvt;
5+
use crate::{io, ptr};
6+
7+
#[inline]
8+
pub fn is_sep_byte(b: u8) -> bool {
9+
b == b'/' || b == b'\\'
10+
}
11+
12+
#[inline]
13+
pub fn is_verbatim_sep(b: u8) -> bool {
14+
b == b'/' || b == b'\\'
15+
}
16+
17+
#[inline]
18+
pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
19+
None
20+
}
21+
22+
pub const MAIN_SEP_STR: &str = "/";
23+
pub const MAIN_SEP: char = '/';
24+
25+
unsafe extern "C" {
26+
// Doc: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
27+
// Src: https://github.com/cygwin/cygwin/blob/718a15ba50e0d01c79800bd658c2477f9a603540/winsup/cygwin/path.cc#L3902
28+
// Safety:
29+
// * `what` should be `CCP_WIN_A_TO_POSIX` here
30+
// * `from` is null-terminated UTF-8 path
31+
// * `to` is buffer, the buffer size is `size`.
32+
//
33+
// Converts a path to an absolute POSIX path, no matter the input is Win32 path or POSIX path.
34+
fn cygwin_conv_path(
35+
what: libc::c_uint,
36+
from: *const libc::c_char,
37+
to: *mut u8,
38+
size: libc::size_t,
39+
) -> libc::ssize_t;
40+
}
41+
42+
const CCP_WIN_A_TO_POSIX: libc::c_uint = 2;
43+
44+
/// Make a POSIX path absolute.
45+
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
46+
run_path_with_cstr(path, &|path| {
47+
let size = cvt(unsafe {
48+
cygwin_conv_path(CCP_WIN_A_TO_POSIX, path.as_ptr(), ptr::null_mut(), 0)
49+
})?;
50+
debug_assert!(size >= 1);
51+
let size = size as usize;
52+
let buffer = Vec::with_capacity(size);
53+
cvt(unsafe {
54+
cygwin_conv_path(CCP_WIN_A_TO_POSIX, path.as_ptr(), buffer.as_mut_ptr(), size)
55+
})?;
56+
unsafe {
57+
buffer.set_len(size - 1);
58+
}
59+
Ok(PathBuf::from(OsString::from_vec(buffer)))
60+
})
61+
}
62+
63+
pub(crate) fn is_absolute(path: &Path) -> bool {
64+
path.has_root()
65+
}

library/std/src/sys/path/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ cfg_if::cfg_if! {
1111
} else if #[cfg(target_os = "uefi")] {
1212
mod uefi;
1313
pub use uefi::*;
14+
} else if #[cfg(target_os = "cygwin")] {
15+
mod cygwin;
16+
pub use cygwin::*;
1417
} else {
1518
mod unix;
1619
pub use unix::*;

0 commit comments

Comments
 (0)