os: fix `find_abs_path_of_executable` function (on Windows) (#14835)
parent
2524207d1c
commit
587101a1ea
|
@ -0,0 +1,46 @@
|
||||||
|
module os
|
||||||
|
|
||||||
|
fn test_find_abs_path_of_executable() ? {
|
||||||
|
tfolder := join_path(temp_dir(), 'v', 'tests', 'filepath_test')
|
||||||
|
rmdir_all(tfolder) or {}
|
||||||
|
assert !is_dir(tfolder)
|
||||||
|
mkdir_all(tfolder)?
|
||||||
|
defer {
|
||||||
|
rmdir_all(tfolder) or {}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
original_path := getenv('PATH')
|
||||||
|
original_wdir := getwd()
|
||||||
|
defer {
|
||||||
|
chdir(original_wdir) or {}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
new_path := tfolder + path_delimiter + original_path
|
||||||
|
setenv('PATH', new_path, true)
|
||||||
|
//
|
||||||
|
mut myclang_file := 'myclang'
|
||||||
|
$if windows {
|
||||||
|
myclang_file += '.bat'
|
||||||
|
}
|
||||||
|
//
|
||||||
|
chdir(tfolder)?
|
||||||
|
write_file(myclang_file, 'echo hello')?
|
||||||
|
chmod(myclang_file, 0o0777)?
|
||||||
|
dump(real_path(myclang_file))
|
||||||
|
dump(is_executable(myclang_file))
|
||||||
|
defer {
|
||||||
|
rm(myclang_file) or {}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
fpath := find_abs_path_of_executable('myclang') or {
|
||||||
|
assert false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dump(fpath)
|
||||||
|
//
|
||||||
|
setenv('PATH', original_path, true)
|
||||||
|
if x := find_abs_path_of_executable('myclang') {
|
||||||
|
eprintln('> find_abs_path_of_executable should have failed, but instead it found: $x')
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
}
|
|
@ -404,7 +404,7 @@ pub fn is_executable(path string) bool {
|
||||||
// 04 Read-only
|
// 04 Read-only
|
||||||
// 06 Read and write
|
// 06 Read and write
|
||||||
p := real_path(path)
|
p := real_path(path)
|
||||||
return exists(p) && p.ends_with('.exe')
|
return exists(p) && (p.ends_with('.exe') || p.ends_with('.bat'))
|
||||||
}
|
}
|
||||||
$if solaris {
|
$if solaris {
|
||||||
statbuf := C.stat{}
|
statbuf := C.stat{}
|
||||||
|
|
|
@ -12,6 +12,8 @@ pub const (
|
||||||
args = []string{}
|
args = []string{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const executable_suffixes = ['']
|
||||||
|
|
||||||
fn get_path_delimiter() string {
|
fn get_path_delimiter() string {
|
||||||
delimiter := ':'
|
delimiter := ':'
|
||||||
$if js_node {
|
$if js_node {
|
||||||
|
|
37
vlib/os/os.v
37
vlib/os/os.v
|
@ -452,27 +452,34 @@ fn error_failed_to_find_executable() IError {
|
||||||
return IError(&ExecutableNotFoundError{})
|
return IError(&ExecutableNotFoundError{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_exe_path walks the environment PATH, just like most shell do, it returns
|
// find_abs_path_of_executable walks the environment PATH, just like most shell do, it returns
|
||||||
// the absolute path of the executable if found
|
// the absolute path of the executable if found
|
||||||
pub fn find_abs_path_of_executable(exepath string) ?string {
|
pub fn find_abs_path_of_executable(exepath string) ?string {
|
||||||
if exepath == '' {
|
if exepath == '' {
|
||||||
return error('expected non empty `exepath`')
|
return error('expected non empty `exepath`')
|
||||||
}
|
}
|
||||||
if is_abs_path(exepath) {
|
|
||||||
return real_path(exepath)
|
for suffix in executable_suffixes {
|
||||||
}
|
fexepath := exepath + suffix
|
||||||
mut res := ''
|
if is_abs_path(fexepath) {
|
||||||
path := getenv('PATH')
|
return real_path(fexepath)
|
||||||
paths := path.split(path_delimiter)
|
}
|
||||||
for p in paths {
|
mut res := ''
|
||||||
found_abs_path := join_path_single(p, exepath)
|
path := getenv('PATH')
|
||||||
if exists(found_abs_path) && is_executable(found_abs_path) {
|
paths := path.split(path_delimiter)
|
||||||
res = found_abs_path
|
for p in paths {
|
||||||
break
|
found_abs_path := join_path_single(p, fexepath)
|
||||||
|
$if trace_find_abs_path_of_executable ? {
|
||||||
|
dump(found_abs_path)
|
||||||
|
}
|
||||||
|
if exists(found_abs_path) && is_executable(found_abs_path) {
|
||||||
|
res = found_abs_path
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if res.len > 0 {
|
||||||
|
return real_path(res)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if res.len > 0 {
|
|
||||||
return real_path(res)
|
|
||||||
}
|
}
|
||||||
return error_failed_to_find_executable()
|
return error_failed_to_find_executable()
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ pub const (
|
||||||
path_delimiter = ':'
|
path_delimiter = ':'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const executable_suffixes = ['']
|
||||||
|
|
||||||
const (
|
const (
|
||||||
stdin_value = 0
|
stdin_value = 0
|
||||||
stdout_value = 1
|
stdout_value = 1
|
||||||
|
|
|
@ -14,6 +14,8 @@ fn C.CreateHardLinkW(&u16, &u16, C.SECURITY_ATTRIBUTES) int
|
||||||
|
|
||||||
fn C._getpid() int
|
fn C._getpid() int
|
||||||
|
|
||||||
|
const executable_suffixes = ['.exe', '.bat', '']
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
path_separator = '\\'
|
path_separator = '\\'
|
||||||
path_delimiter = ';'
|
path_delimiter = ';'
|
||||||
|
|
Loading…
Reference in New Issue