os: fix using Win32-API with TCC32 (#10496)
parent
45c6b6493b
commit
1e9e717111
|
@ -779,16 +779,35 @@ pub fn getwd() string {
|
|||
pub fn real_path(fpath string) string {
|
||||
mut res := ''
|
||||
$if windows {
|
||||
// GetFullPathName doesn't work with symbolic links,
|
||||
// so if it is not a file, get full path
|
||||
mut fullpath := unsafe { &u16(vcalloc_noscan(max_path_len * 2)) }
|
||||
// TODO: check errors if path len is not enough
|
||||
ret := C.GetFullPathName(fpath.to_wide(), max_path_len, fullpath, 0)
|
||||
if ret == 0 {
|
||||
unsafe { free(fullpath) }
|
||||
return fpath.clone()
|
||||
size := max_path_len * 2
|
||||
// gets handle with GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
|
||||
// use C.CreateFile(fpath.to_wide(), 0x80000000, 1, 0, 3, 0x80, 0) instead of get_file_handle
|
||||
// try to open the file to get symbolic link path
|
||||
file := C.CreateFile(fpath.to_wide(), 0x80000000, 1, 0, 3, 0x80, 0)
|
||||
if file != voidptr(-1) {
|
||||
mut fullpath := unsafe { &u16(vcalloc_noscan(size)) }
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
|
||||
final_len := C.GetFinalPathNameByHandleW(file, fullpath, size, 0)
|
||||
C.CloseHandle(file)
|
||||
if final_len < size {
|
||||
rt := unsafe { string_from_wide2(fullpath, final_len) }
|
||||
res = rt[4..]
|
||||
} else {
|
||||
unsafe { free(fullpath) }
|
||||
eprintln('os.real_path() saw that the file path was too long')
|
||||
return fpath.clone()
|
||||
}
|
||||
} else {
|
||||
// if it is not a file C.CreateFile doesn't gets a file handle, use GetFullPath instead
|
||||
mut fullpath := unsafe { &u16(vcalloc_noscan(max_path_len * 2)) }
|
||||
// TODO: check errors if path len is not enough
|
||||
ret := C.GetFullPathName(fpath.to_wide(), max_path_len, fullpath, 0)
|
||||
if ret == 0 {
|
||||
unsafe { free(fullpath) }
|
||||
return fpath.clone()
|
||||
}
|
||||
res = unsafe { string_from_wide(fullpath) }
|
||||
}
|
||||
res = unsafe { string_from_wide(fullpath) }
|
||||
} $else {
|
||||
mut fullpath := vcalloc_noscan(max_path_len)
|
||||
ret := &char(C.realpath(&char(fpath.str), &char(fullpath)))
|
||||
|
|
|
@ -342,6 +342,20 @@ fn test_realpath_does_not_absolutize_non_existing_relative_paths() {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_realpath_absolutepath_symlink() {
|
||||
file_name := 'tolink_file.txt'
|
||||
symlink_name := 'symlink.txt'
|
||||
mut f := os.create(file_name) or { panic(err) }
|
||||
f.close()
|
||||
assert os.symlink(file_name, symlink_name) or { panic(err) }
|
||||
rpath := os.real_path(symlink_name)
|
||||
println(rpath)
|
||||
assert os.is_abs_path(rpath)
|
||||
assert rpath.ends_with(file_name)
|
||||
os.rm(symlink_name) or {}
|
||||
os.rm(file_name) or {}
|
||||
}
|
||||
|
||||
fn test_tmpdir() {
|
||||
t := os.temp_dir()
|
||||
assert t.len > 0
|
||||
|
|
|
@ -9,8 +9,7 @@ import strings
|
|||
fn C.CreateSymbolicLinkW(&u16, &u16, u32) int
|
||||
|
||||
// See https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createhardlinkw
|
||||
// TCC gets builder error
|
||||
// fn C.CreateHardLinkW(&u16, &u16, C.SECURITY_ATTRIBUTES) int
|
||||
fn C.CreateHardLinkW(&u16, &u16, C.SECURITY_ATTRIBUTES) int
|
||||
|
||||
fn C._getpid() int
|
||||
|
||||
|
@ -321,7 +320,7 @@ pub fn execute(cmd string) Result {
|
|||
|
||||
pub fn symlink(origin string, target string) ?bool {
|
||||
// this is a temporary fix for TCC32 due to runtime error
|
||||
// TODO: patch TCC32
|
||||
// TODO: find the cause why TCC32 for Windows does not work without the compiletime option
|
||||
$if x64 || x32 {
|
||||
mut flags := 0
|
||||
if is_dir(origin) {
|
||||
|
@ -344,8 +343,6 @@ pub fn symlink(origin string, target string) ?bool {
|
|||
}
|
||||
|
||||
pub fn link(origin string, target string) ?bool {
|
||||
/*
|
||||
// TODO: TCC gets builder error
|
||||
res := C.CreateHardLinkW(target.to_wide(), origin.to_wide(), C.NULL)
|
||||
// 1 = success, != 1 failure => https://stackoverflow.com/questions/33010440/createsymboliclink-on-windows-10
|
||||
if res != 1 {
|
||||
|
@ -355,12 +352,6 @@ pub fn link(origin string, target string) ?bool {
|
|||
return error('C.CreateHardLinkW reported success, but link still does not exist')
|
||||
}
|
||||
return true
|
||||
*/
|
||||
res := execute('fsutil hardlink create $target $origin')
|
||||
if res.exit_code != 0 {
|
||||
return error(res.output)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
pub fn (mut f File) close() {
|
||||
|
|
Loading…
Reference in New Issue